Skip to content

Commit 20aeb99

Browse files
committed
Reject malformed inputs in the term parser
1 parent 397756c commit 20aeb99

1 file changed

Lines changed: 103 additions & 10 deletions

File tree

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

@@ -769,7 +850,10 @@ static int get_coefficient_ff_and_term_from_line(char *line, int32_t nterms,
769850
iv_tmp += field_char; //MS change int -> long int
770851
}
771852
gens->cfs[pos] = (int32_t)iv_tmp;
772-
store_exponent(term, gens, pos*gens->nvars);
853+
if (store_exponent(term, gens, pos*gens->nvars)) {
854+
free(term);
855+
return 1;
856+
}
773857
for(int j = 1; j < nterms; j++){
774858
get_term(line, &prev_pos, &term, &term_size);
775859
if (term != NULL) {
@@ -792,7 +876,10 @@ static int get_coefficient_ff_and_term_from_line(char *line, int32_t nterms,
792876
cf_tmp += field_char;
793877
}
794878
gens->cfs[pos+j] = (int32_t)cf_tmp;
795-
store_exponent(term, gens, (pos+j)*gens->nvars);
879+
if (store_exponent(term, gens, (pos+j)*gens->nvars)) {
880+
free(term);
881+
return 1;
882+
}
796883
}
797884
// store_exponent(term, basis, ht);
798885
}
@@ -880,11 +967,17 @@ static int get_coefficient_mpz_and_term_from_line(char *line, int32_t nterms,
880967
if(term != NULL){
881968

882969
beginning_strterm_to_mpz(term, gens->mpz_cfs[pos], gens->mpz_cfs[pos+1]);
883-
store_exponent(term, gens, pos/2*gens->nvars);
970+
if (store_exponent(term, gens, pos/2*gens->nvars)) {
971+
free(term);
972+
return 1;
973+
}
884974
for(int j = 2; j < 2*nterms; j+=2){
885975
get_term(line, &prev_pos, &term, &term_size);
886976
inner_strterm_to_mpz(term, gens->mpz_cfs[pos+j], gens->mpz_cfs[pos+j+1]);
887-
store_exponent(term, gens, ((pos+j)/2)*gens->nvars);
977+
if (store_exponent(term, gens, ((pos+j)/2)*gens->nvars)) {
978+
free(term);
979+
return 1;
980+
}
888981
}
889982
free(term);
890983
return 0;

0 commit comments

Comments
 (0)