Skip to content

Commit 8eeff33

Browse files
committed
Reject malformed inputs in the term parser
1 parent 5d1fc9e commit 8eeff33

3 files changed

Lines changed: 99 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: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,48 @@
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+
mpz_init(tmp_z);
34+
mpq_init(tmp_q);
35+
2636
char *var = NULL;
2737
char *ev = NULL;
38+
char *end = NULL;
2839
for (i = 0; i < strlen(term)+1; ++i) {
2940
if (term[i] == '*' || i == strlen(term)) {
3041
j = op;
3142
while (j < i && term[j] != '^') {
3243
++j;
3344
}
34-
if (term[j-1] == ',') {
35-
--j;
36-
}
3745
while(term[op] == ' ' || term[op] == '+' || term[op] == '-') {
3846
++op;
3947
}
48+
if (op >= j) {
49+
fprintf(stderr, "Error when parsing term %s (missing operand for *)\n", term);
50+
res = 1;
51+
break;
52+
}
4053
var = realloc(var, sizeof(char)*(j-op+1));
4154
memcpy(var, term+op, j-op);
4255
var[j-op] = '\0';
43-
if (term[j] == '^') {
56+
int has_exponent = (j < i && term[j] == '^');
57+
if (has_exponent) {
58+
if (j + 1 >= i) {
59+
fprintf(stderr, "Error when parsing term %s (missing exponent)\n", term);
60+
res = 1;
61+
break;
62+
}
4463
ev = realloc(ev, (sizeof(char)*(i-j)));
4564
ev = memcpy(ev, term+(j+1), i-j-1);
4665
ev[i-j-1] = '\0';
@@ -49,17 +68,73 @@ static inline void store_exponent(const char *term, data_gens_ff_t *gens, int32_
4968
ev[0] = '1';
5069
ev[1] ='\0';
5170
}
71+
int is_var = 0;
5272
for (k = 0; k < gens->nvars; ++k) {
5373
if (strcmp(gens->vnames[k], var) == 0) {
54-
((gens->exps) + pos)[k] = strtol(ev, NULL, 10);
74+
is_var = 1;
75+
if (((gens->exps) + pos)[k] != 0) {
76+
fprintf(stderr, "Error when parsing term %s (variable appears multiple times)\n", term);
77+
res = 1;
78+
break;
79+
}
80+
long val = strtol(ev, &end, 10);
81+
if (ev == end) {
82+
fprintf(stderr, "Error when parsing term %s (invalid exponent)\n", term);
83+
res = 1;
84+
break;
85+
}
86+
if (errno == ERANGE || val > INT_MAX) {
87+
fprintf(stderr, "Error when parsing term %s (exponent out of range)\n", term);
88+
res = 1;
89+
break;
90+
}
91+
if (val <= 0) {
92+
fprintf(stderr, "Error when parsing term %s (exponent must be positive)\n", term);
93+
res = 1;
94+
break;
95+
}
96+
((gens->exps) + pos)[k] = val;
5597
break;
5698
}
5799
}
100+
if (res == 1) {
101+
break;
102+
}
103+
if (is_var == 0) {
104+
if (has_exponent) {
105+
fprintf(stderr, "Error when parsing term %s (coefficient cannot have an exponent)\n", term);
106+
res = 1;
107+
break;
108+
}
109+
if (index > 0) {
110+
fprintf(stderr, "Error when parsing term %s (multiple coefficients are not allowed)\n", term);
111+
res = 1;
112+
break;
113+
}
114+
if (gens->field_char > 0) {
115+
if (mpz_set_str(tmp_z, var, 10) != 0) {
116+
fprintf(stderr, "Error when parsing term %s (invalid coefficient for finite field)\n", term);
117+
res = 1;
118+
break;
119+
}
120+
} else {
121+
if (mpq_set_str(tmp_q, var, 10) != 0) {
122+
fprintf(stderr, "Error when parsing term %s (invalid coefficient)\n", term);
123+
res = 1;
124+
break;
125+
}
126+
}
127+
}
58128
op = i+1;
129+
index++;
59130
}
60131
}
132+
61133
free(var);
62134
free(ev);
135+
mpq_clear(tmp_q);
136+
mpz_clear(tmp_z);
137+
return res;
63138
}
64139

65140

@@ -751,7 +826,10 @@ static int get_coefficient_ff_and_term_from_line(char *line, int32_t nterms,
751826
iv_tmp += field_char; //MS change int -> long int
752827
}
753828
gens->cfs[pos] = (int32_t)iv_tmp;
754-
store_exponent(term, gens, pos*gens->nvars);
829+
if (store_exponent(term, gens, pos*gens->nvars)) {
830+
free(term);
831+
return 1;
832+
}
755833
for(int j = 1; j < nterms; j++){
756834
get_term(line, &prev_pos, &term, &term_size);
757835
if (term != NULL) {
@@ -769,7 +847,10 @@ static int get_coefficient_ff_and_term_from_line(char *line, int32_t nterms,
769847
cf_tmp += field_char;
770848
}
771849
gens->cfs[pos+j] = (int32_t)cf_tmp;
772-
store_exponent(term, gens, (pos+j)*gens->nvars);
850+
if (store_exponent(term, gens, (pos+j)*gens->nvars)) {
851+
free(term);
852+
return 1;
853+
}
773854
}
774855
// store_exponent(term, basis, ht);
775856
}
@@ -857,11 +938,17 @@ static int get_coefficient_mpz_and_term_from_line(char *line, int32_t nterms,
857938
if(term != NULL){
858939

859940
beginning_strterm_to_mpz(term, gens->mpz_cfs[pos], gens->mpz_cfs[pos+1]);
860-
store_exponent(term, gens, pos/2*gens->nvars);
941+
if (store_exponent(term, gens, pos/2*gens->nvars)) {
942+
free(term);
943+
return 1;
944+
}
861945
for(int j = 2; j < 2*nterms; j+=2){
862946
get_term(line, &prev_pos, &term, &term_size);
863947
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);
948+
if (store_exponent(term, gens, ((pos+j)/2)*gens->nvars)) {
949+
free(term);
950+
return 1;
951+
}
865952
}
866953
free(term);
867954
return 0;

0 commit comments

Comments
 (0)