Skip to content

Commit b11af53

Browse files
committed
handle malloc failures
1 parent ff59221 commit b11af53

File tree

1 file changed

+168
-7
lines changed

1 file changed

+168
-7
lines changed

tinyexpr.c

Lines changed: 168 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ static te_expr *new_expr(const int type, const te_expr *parameters[]) {
8686
const int psize = sizeof(void*) * arity;
8787
const int size = (sizeof(te_expr) - sizeof(void*)) + psize + (IS_CLOSURE(type) ? sizeof(void*) : 0);
8888
te_expr *ret = malloc(size);
89+
if (ret == NULL) {
90+
return NULL;
91+
}
92+
8993
memset(ret, 0, size);
9094
if (arity && parameters) {
9195
memcpy(ret->parameters, parameters, psize);
@@ -305,19 +309,31 @@ static te_expr *base(state *s) {
305309
switch (TYPE_MASK(s->type)) {
306310
case TOK_NUMBER:
307311
ret = new_expr(TE_CONSTANT, 0);
312+
if (ret == NULL) {
313+
return NULL;
314+
}
315+
308316
ret->value = s->value;
309317
next_token(s);
310318
break;
311319

312320
case TOK_VARIABLE:
313321
ret = new_expr(TE_VARIABLE, 0);
322+
if (ret == NULL) {
323+
return NULL;
324+
}
325+
314326
ret->bound = s->bound;
315327
next_token(s);
316328
break;
317329

318330
case TE_FUNCTION0:
319331
case TE_CLOSURE0:
320332
ret = new_expr(s->type, 0);
333+
if (ret == NULL) {
334+
return NULL;
335+
}
336+
321337
ret->function = s->function;
322338
if (IS_CLOSURE(s->type)) ret->parameters[0] = s->context;
323339
next_token(s);
@@ -334,10 +350,18 @@ static te_expr *base(state *s) {
334350
case TE_FUNCTION1:
335351
case TE_CLOSURE1:
336352
ret = new_expr(s->type, 0);
353+
if (ret == NULL) {
354+
return NULL;
355+
}
356+
337357
ret->function = s->function;
338358
if (IS_CLOSURE(s->type)) ret->parameters[1] = s->context;
339359
next_token(s);
340360
ret->parameters[0] = power(s);
361+
if (ret->parameters[0] == NULL) {
362+
free(ret);
363+
return NULL;
364+
}
341365
break;
342366

343367
case TE_FUNCTION2: case TE_FUNCTION3: case TE_FUNCTION4:
@@ -347,6 +371,10 @@ static te_expr *base(state *s) {
347371
arity = ARITY(s->type);
348372

349373
ret = new_expr(s->type, 0);
374+
if (ret == NULL) {
375+
return NULL;
376+
}
377+
350378
ret->function = s->function;
351379
if (IS_CLOSURE(s->type)) ret->parameters[arity] = s->context;
352380
next_token(s);
@@ -358,6 +386,15 @@ static te_expr *base(state *s) {
358386
for(i = 0; i < arity; i++) {
359387
next_token(s);
360388
ret->parameters[i] = expr(s);
389+
if (ret->parameters[i] == NULL) {
390+
int j;
391+
for (j = 0; j < i; ++j) {
392+
te_free(ret->parameters[j]);
393+
}
394+
free(ret);
395+
return NULL;
396+
}
397+
361398
if(s->type != TOK_SEP) {
362399
break;
363400
}
@@ -374,6 +411,10 @@ static te_expr *base(state *s) {
374411
case TOK_OPEN:
375412
next_token(s);
376413
ret = list(s);
414+
if (ret == NULL) {
415+
return NULL;
416+
}
417+
377418
if (s->type != TOK_CLOSE) {
378419
s->type = TOK_ERROR;
379420
} else {
@@ -383,6 +424,10 @@ static te_expr *base(state *s) {
383424

384425
default:
385426
ret = new_expr(0, 0);
427+
if (ret == NULL) {
428+
return NULL;
429+
}
430+
386431
s->type = TOK_ERROR;
387432
ret->value = NAN;
388433
break;
@@ -405,7 +450,17 @@ static te_expr *power(state *s) {
405450
if (sign == 1) {
406451
ret = base(s);
407452
} else {
408-
ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s));
453+
te_expr *b = base(s);
454+
if (b == NULL) {
455+
return NULL;
456+
}
457+
458+
ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, b);
459+
if (ret == NULL) {
460+
te_free(b);
461+
return NULL;
462+
}
463+
409464
ret->function = negate;
410465
}
411466

@@ -416,6 +471,9 @@ static te_expr *power(state *s) {
416471
static te_expr *factor(state *s) {
417472
/* <factor> = <power> {"^" <power>} */
418473
te_expr *ret = power(s);
474+
if (ret == NULL) {
475+
return NULL;
476+
}
419477

420478
int neg = 0;
421479

@@ -434,19 +492,50 @@ static te_expr *factor(state *s) {
434492

435493
if (insertion) {
436494
/* Make exponentiation go right-to-left. */
437-
te_expr *insert = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, insertion->parameters[1], power(s));
495+
te_expr *p = power(s);
496+
if (p == NULL) {
497+
te_free(ret);
498+
return NULL;
499+
}
500+
501+
te_expr *insert = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, insertion->parameters[1], p);
502+
if (insert == NULL) {
503+
te_free(p);
504+
te_free(ret);
505+
return NULL;
506+
}
507+
438508
insert->function = t;
439509
insertion->parameters[1] = insert;
440510
insertion = insert;
441511
} else {
442-
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, power(s));
512+
te_expr *p = power(s);
513+
if (p == NULL) {
514+
te_free(ret);
515+
return NULL;
516+
}
517+
518+
te_expr *prev = ret;
519+
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, p);
520+
if (ret == NULL) {
521+
te_free(p);
522+
te_free(prev);
523+
return NULL;
524+
}
525+
443526
ret->function = t;
444527
insertion = ret;
445528
}
446529
}
447530

448531
if (neg) {
532+
te_expr *prev = ret;
449533
ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, ret);
534+
if (ret == NULL) {
535+
te_free(prev);
536+
return NULL;
537+
}
538+
450539
ret->function = negate;
451540
}
452541

@@ -456,11 +545,27 @@ static te_expr *factor(state *s) {
456545
static te_expr *factor(state *s) {
457546
/* <factor> = <power> {"^" <power>} */
458547
te_expr *ret = power(s);
548+
if (ret == NULL) {
549+
return NULL;
550+
}
459551

460552
while (s->type == TOK_INFIX && (s->function == pow)) {
461553
te_fun2 t = s->function;
462554
next_token(s);
463-
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, power(s));
555+
te_expr *p = power(s);
556+
if (p == NULL) {
557+
te_free(ret);
558+
return NULL;
559+
}
560+
561+
te_expr *prev = ret;
562+
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, p);
563+
if (ret == NULL) {
564+
te_free(p);
565+
te_free(prev);
566+
return NULL;
567+
}
568+
464569
ret->function = t;
465570
}
466571

@@ -473,11 +578,27 @@ static te_expr *factor(state *s) {
473578
static te_expr *term(state *s) {
474579
/* <term> = <factor> {("*" | "/" | "%") <factor>} */
475580
te_expr *ret = factor(s);
581+
if (ret == NULL) {
582+
return NULL;
583+
}
476584

477585
while (s->type == TOK_INFIX && (s->function == mul || s->function == divide || s->function == fmod)) {
478586
te_fun2 t = s->function;
479587
next_token(s);
480-
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, factor(s));
588+
te_expr *f = factor(s);
589+
if (f == NULL) {
590+
te_free(ret);
591+
return NULL;
592+
}
593+
594+
te_expr *prev = ret;
595+
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, f);
596+
if (ret == NULL) {
597+
te_free(f);
598+
te_free(prev);
599+
return NULL;
600+
}
601+
481602
ret->function = t;
482603
}
483604

@@ -488,11 +609,27 @@ static te_expr *term(state *s) {
488609
static te_expr *expr(state *s) {
489610
/* <expr> = <term> {("+" | "-") <term>} */
490611
te_expr *ret = term(s);
612+
if (ret == NULL) {
613+
return NULL;
614+
}
491615

492616
while (s->type == TOK_INFIX && (s->function == add || s->function == sub)) {
493617
te_fun2 t = s->function;
494618
next_token(s);
495-
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, term(s));
619+
te_expr *te = term(s);
620+
if (te == NULL) {
621+
te_free(ret);
622+
return NULL;
623+
}
624+
625+
te_expr *prev = ret;
626+
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, te);
627+
if (ret == NULL) {
628+
te_free(te);
629+
te_free(prev);
630+
return NULL;
631+
}
632+
496633
ret->function = t;
497634
}
498635

@@ -503,10 +640,26 @@ static te_expr *expr(state *s) {
503640
static te_expr *list(state *s) {
504641
/* <list> = <expr> {"," <expr>} */
505642
te_expr *ret = expr(s);
643+
if (ret == NULL) {
644+
return NULL;
645+
}
506646

507647
while (s->type == TOK_SEP) {
508648
next_token(s);
509-
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, expr(s));
649+
te_expr *e = expr(s);
650+
if (e == NULL) {
651+
te_free(ret);
652+
return NULL;
653+
}
654+
655+
te_expr *prev = ret;
656+
ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, e);
657+
if (ret == NULL) {
658+
te_free(e);
659+
te_free(prev);
660+
return NULL;
661+
}
662+
510663
ret->function = comma;
511664
}
512665

@@ -595,6 +748,10 @@ te_expr *te_compile(const char *expression, const te_variable *variables, int va
595748

596749
next_token(&s);
597750
te_expr *root = list(&s);
751+
if (root == NULL) {
752+
if (error) *error = -1;
753+
return NULL;
754+
}
598755

599756
if (s.type != TOK_END) {
600757
te_free(root);
@@ -613,6 +770,10 @@ te_expr *te_compile(const char *expression, const te_variable *variables, int va
613770

614771
double te_interp(const char *expression, int *error) {
615772
te_expr *n = te_compile(expression, 0, 0, error);
773+
if (n == NULL) {
774+
return NAN;
775+
}
776+
616777
double ret;
617778
if (n) {
618779
ret = te_eval(n);

0 commit comments

Comments
 (0)