Skip to content

Commit 814e543

Browse files
committed
Reject malformed inputs in the term parser
1 parent 156fe8a commit 814e543

3 files changed

Lines changed: 105 additions & 12 deletions

File tree

input_files/bug-68.ms

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
x,y,z
22
257
33
0,
4-
x*x+y*y+z*z,
4+
x^2+y^2+z^2,
55
x+y+z,
66
x+y*z

input_files/radical-shape-qq.ms

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ x, y, z
22
0
33
-2*z^3-3*z^2+x-5*z-7,
44
-z^3+z^2+y-z+1,
5-
z^4-z^3-z^2-*z-1
5+
z^4-z^3-z^2-z-1

src/msolve/iofiles.c

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,51 @@
1818
* Christian Eder
1919
* Mohab Safey El Din */
2020

21-
static inline void store_exponent(const char *term, data_gens_ff_t *gens, int32_t pos)
21+
#include <errno.h>
22+
23+
static inline int store_exponent(const char *term, data_gens_ff_t *gens, int32_t pos)
2224
{
2325
len_t i, j, k;
2426

2527
len_t op = 0;
28+
len_t index = 0;
29+
30+
int res = 0;
31+
mpz_t tmp_z;
32+
mpq_t tmp_q;
33+
if (gens->field_char > 0) {
34+
mpz_init(tmp_z);
35+
} else {
36+
mpq_init(tmp_q);
37+
}
38+
2639
char *var = NULL;
2740
char *ev = NULL;
41+
char *end = NULL;
2842
for (i = 0; i < strlen(term)+1; ++i) {
2943
if (term[i] == '*' || i == strlen(term)) {
3044
j = op;
3145
while (j < i && term[j] != '^') {
3246
++j;
3347
}
34-
if (term[j-1] == ',') {
35-
--j;
36-
}
3748
while(term[op] == ' ' || term[op] == '+' || term[op] == '-') {
3849
++op;
3950
}
51+
if (op >= j) {
52+
fprintf(stderr, "Error when parsing term %s (missing operand for *)\n", term);
53+
res = 1;
54+
break;
55+
}
4056
var = realloc(var, sizeof(char)*(j-op+1));
4157
memcpy(var, term+op, j-op);
4258
var[j-op] = '\0';
43-
if (term[j] == '^') {
59+
int has_exponent = (j < i && term[j] == '^');
60+
if (has_exponent) {
61+
if (j + 1 >= i) {
62+
fprintf(stderr, "Error when parsing term %s (missing exponent)\n", term);
63+
res = 1;
64+
break;
65+
}
4466
ev = realloc(ev, (sizeof(char)*(i-j)));
4567
ev = memcpy(ev, term+(j+1), i-j-1);
4668
ev[i-j-1] = '\0';
@@ -49,17 +71,76 @@ static inline void store_exponent(const char *term, data_gens_ff_t *gens, int32_
4971
ev[0] = '1';
5072
ev[1] ='\0';
5173
}
74+
int is_var = 0;
5275
for (k = 0; k < gens->nvars; ++k) {
5376
if (strcmp(gens->vnames[k], var) == 0) {
54-
((gens->exps) + pos)[k] = strtol(ev, NULL, 10);
77+
is_var = 1;
78+
if (((gens->exps) + pos)[k] != 0) {
79+
fprintf(stderr, "Error when parsing term %s (variable appears multiple times)\n", term);
80+
res = 1;
81+
break;
82+
}
83+
long val = strtol(ev, &end, 10);
84+
if (ev == end) {
85+
fprintf(stderr, "Error when parsing term %s (invalid exponent)\n", term);
86+
res = 1;
87+
break;
88+
}
89+
if (errno == ERANGE || val > INT_MAX) {
90+
fprintf(stderr, "Error when parsing term %s (exponent out of range)\n", term);
91+
res = 1;
92+
break;
93+
}
94+
if (val <= 0) {
95+
fprintf(stderr, "Error when parsing term %s (exponent must be positive)\n", term);
96+
res = 1;
97+
break;
98+
}
99+
((gens->exps) + pos)[k] = val;
55100
break;
56101
}
57102
}
103+
if (res == 1) {
104+
break;
105+
}
106+
if (is_var == 0) {
107+
if (has_exponent) {
108+
fprintf(stderr, "Error when parsing term %s (coefficient cannot have an exponent)\n", term);
109+
res = 1;
110+
break;
111+
}
112+
if (index > 0) {
113+
fprintf(stderr, "Error when parsing term %s (multiple coefficients are not allowed)\n", term);
114+
res = 1;
115+
break;
116+
}
117+
if (gens->field_char > 0) {
118+
if (mpz_set_str(tmp_z, var, 10) != 0) {
119+
fprintf(stderr, "Error when parsing term %s (invalid coefficient for finite field)\n", term);
120+
res = 1;
121+
break;
122+
}
123+
} else {
124+
if (mpq_set_str(tmp_q, var, 10) != 0) {
125+
fprintf(stderr, "Error when parsing term %s (invalid coefficient)\n", term);
126+
res = 1;
127+
break;
128+
}
129+
}
130+
}
58131
op = i+1;
132+
index++;
59133
}
60134
}
135+
61136
free(var);
62137
free(ev);
138+
if (gens->field_char > 0) {
139+
mpz_clear(tmp_z);
140+
} else {
141+
mpq_clear(tmp_q);
142+
}
143+
return res;
63144
}
64145

65146

@@ -751,7 +832,10 @@ static int get_coefficient_ff_and_term_from_line(char *line, int32_t nterms,
751832
iv_tmp += field_char; //MS change int -> long int
752833
}
753834
gens->cfs[pos] = (int32_t)iv_tmp;
754-
store_exponent(term, gens, pos*gens->nvars);
835+
if (store_exponent(term, gens, pos*gens->nvars)) {
836+
free(term);
837+
return 1;
838+
}
755839
for(int j = 1; j < nterms; j++){
756840
get_term(line, &prev_pos, &term, &term_size);
757841
if (term != NULL) {
@@ -769,7 +853,10 @@ static int get_coefficient_ff_and_term_from_line(char *line, int32_t nterms,
769853
cf_tmp += field_char;
770854
}
771855
gens->cfs[pos+j] = (int32_t)cf_tmp;
772-
store_exponent(term, gens, (pos+j)*gens->nvars);
856+
if (store_exponent(term, gens, (pos+j)*gens->nvars)) {
857+
free(term);
858+
return 1;
859+
}
773860
}
774861
// store_exponent(term, basis, ht);
775862
}
@@ -857,11 +944,17 @@ static int get_coefficient_mpz_and_term_from_line(char *line, int32_t nterms,
857944
if(term != NULL){
858945

859946
beginning_strterm_to_mpz(term, gens->mpz_cfs[pos], gens->mpz_cfs[pos+1]);
860-
store_exponent(term, gens, pos/2*gens->nvars);
947+
if (store_exponent(term, gens, pos/2*gens->nvars)) {
948+
free(term);
949+
return 1;
950+
}
861951
for(int j = 2; j < 2*nterms; j+=2){
862952
get_term(line, &prev_pos, &term, &term_size);
863953
inner_strterm_to_mpz(term, gens->mpz_cfs[pos+j], gens->mpz_cfs[pos+j+1]);
864-
store_exponent(term, gens, ((pos+j)/2)*gens->nvars);
954+
if (store_exponent(term, gens, ((pos+j)/2)*gens->nvars)) {
955+
free(term);
956+
return 1;
957+
}
865958
}
866959
free(term);
867960
return 0;

0 commit comments

Comments
 (0)