Skip to content

Commit ea7e512

Browse files
committed
Add stack to constant expansion to prevent infinite loops
1 parent dc1fd84 commit ea7e512

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

src/preprocess.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ struct constant *constants_find(struct constants *constants, char *name, int len
277277
return c;
278278
}
279279

280-
char *constants_preprocess(struct constants *constants, char *source, int line) {
280+
char *constants_preprocess(struct constants *constants, char *source, int line, struct constant_stack *constant_stack) {
281281
char *ptr = source;
282282
char *start;
283283
char *result;
@@ -289,6 +289,7 @@ char *constants_preprocess(struct constants *constants, char *source, int line)
289289
int level;
290290
char in_string;
291291
struct constant *c;
292+
struct constant_stack *cs;
292293

293294
result = (char *)safe_malloc(1);
294295
result[0] = 0;
@@ -321,6 +322,16 @@ char *constants_preprocess(struct constants *constants, char *source, int line)
321322
continue;
322323
}
323324

325+
// prevent infinite loop
326+
if (constant_stack != NULL) {
327+
for (cs = constant_stack; cs != NULL; cs = cs->next) {
328+
if (cs->constant == c)
329+
break;
330+
}
331+
if (cs != NULL && cs->constant == c)
332+
continue;
333+
}
334+
324335
args = NULL;
325336
num_args = 0;
326337
if (*ptr == '(') {
@@ -362,7 +373,7 @@ char *constants_preprocess(struct constants *constants, char *source, int line)
362373
}
363374
}
364375

365-
value = constant_value(constants, c, num_args, args, line);
376+
value = constant_value(constants, c, num_args, args, line, constant_stack);
366377
if (!value)
367378
return NULL;
368379

@@ -397,11 +408,16 @@ void constants_free(struct constants *constants) {
397408
}
398409

399410
char *constant_value(struct constants *constants, struct constant *constant,
400-
int num_args, char **args, int line) {
411+
int num_args, char **args, int line, struct constant_stack *constant_stack) {
401412
int i;
402413
char *result;
403414
char *ptr;
404415
char *tmp;
416+
struct constant_stack *cs;
417+
418+
cs = (struct constant_stack *)malloc(sizeof(struct constant_stack));
419+
cs->next = constant_stack;
420+
cs->constant = constant;
405421

406422
if (num_args != constant->num_args) {
407423
if (num_args)
@@ -411,7 +427,7 @@ char *constant_value(struct constants *constants, struct constant *constant,
411427
}
412428

413429
for (i = 0; i < num_args; i++) {
414-
args[i] = constants_preprocess(constants, args[i], line);
430+
args[i] = constants_preprocess(constants, args[i], line, cs);
415431
trim(args[i], strlen(args[i]) + 1);
416432
if (args[i] == NULL)
417433
return NULL;
@@ -434,9 +450,11 @@ char *constant_value(struct constants *constants, struct constant *constant,
434450
strcat(result, ptr);
435451
}
436452

437-
result = constants_preprocess(constants, result, line);
453+
result = constants_preprocess(constants, result, line, cs);
438454
trim(result, strlen(result) + 1);
439455

456+
free(cs);
457+
440458
return result;
441459
}
442460

@@ -858,7 +876,7 @@ int preprocess(char *source, FILE *f_target, struct constants *constants, struct
858876
// if (constants[1].value == 0)
859877
// constants[1].value = (char *)safe_malloc(16);
860878
// sprintf(constants[1].value, "%i", line - 1);
861-
879+
862880
if (level_comment == 0 && buffer[0] == '#') {
863881
ptr = buffer+1;
864882
while (*ptr == ' ' || *ptr == '\t')
@@ -950,7 +968,7 @@ int preprocess(char *source, FILE *f_target, struct constants *constants, struct
950968

951969
free(directive);
952970
} else if (strlen(buffer) > 1) {
953-
buffer = constants_preprocess(constants, buffer, line);
971+
buffer = constants_preprocess(constants, buffer, line, NULL);
954972
if (buffer == NULL) {
955973
lerrorf(source, line, "Failed to resolve macros.\n");
956974
fclose(f_source);

src/preprocess.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ struct lineref {
5353
uint32_t *line_number;
5454
};
5555

56+
struct constant_stack {
57+
struct constant *constant;
58+
struct constant_stack *next;
59+
};
60+
5661

5762
char include_stack[MAXINCLUDES][1024];
5863

@@ -61,11 +66,11 @@ struct constants *constants_init();
6166
bool constants_parse(struct constants *constants, char *definition, int line);
6267
bool constants_remove(struct constants *constants, char *name);
6368
struct constant *constants_find(struct constants *constants, char *name, int len);
64-
char *constants_preprocess(struct constants *constants, char *source, int line);
69+
char *constants_preprocess(struct constants *constants, char *source, int line, struct constant_stack *constant_stack);
6570
void constants_free(struct constants *constants);
6671

6772
char *constant_value(struct constants *constants, struct constant *constant,
68-
int num_args, char **args, int value);
73+
int num_args, char **args, int value, struct constant_stack *constant_stack);
6974
void constant_free(struct constant *constant);
7075

7176
bool matches_includepath(char *path, char *includepath, char *includefolder);

0 commit comments

Comments
 (0)