commit c3bc010b87f4bb42e288a001030b71468e4ea051 from: Sven M. Hallberg date: Fri Jun 19 19:20:22 2020 UTC check for integer overflow commit - 86cc2a8811c0ecaa347a5e512ea99e1bd18bda67 commit + c3bc010b87f4bb42e288a001030b71468e4ea051 blob - 129e1591f556a77f2c976bb3b91c4a17977f5dcb blob + 8f4c3fd4e7d148dca1dfa58ceb3a3dafbb6c0faf --- pdf.c +++ pdf.c @@ -102,7 +102,13 @@ validate_eq_uint(HParseResult *p, void *u) v->uint == (uint64_t)(uintptr_t)u); } +bool +validate_notnull(HParseResult *p, void *u) +{ + return p->ast != NULL; +} + /* * auxiliary global data structure needed by the parser */ @@ -530,15 +536,23 @@ act_nat(const HParseResult *p, void *u) uint64_t x = 0; HCountedArray *seq = H_CAST_SEQ(p->ast); - // XXX check for overflow - for (size_t i = 0; i < seq->used; i++) - x = x*10 + H_CAST_UINT(seq->elements[i]); + for (size_t i = 0; i < seq->used; i++) { + uint64_t d = H_CAST_UINT(seq->elements[i]); + + if (x > (UINT64_MAX - d) / 10) /* would overflow */ + return NULL; + // XXX introduce a structured error type and unify with VIOL() + x = x * 10 + d; + } + return H_MAKE_UINT(x); } #define act_xroff act_nat #define act_xrgen act_nat +#define validate_nat validate_notnull + HParser *p_violsev; HParsedToken * act_viol(const HParseResult *p, void *viol) @@ -618,6 +632,8 @@ act_numb(const HParseResult *p, void *u) assert(sgn == 1 || sgn == -1); switch (x->token_type) { case TT_UINT: + if (x->uint > -INT64_MIN) /* would overflow */ + return NULL; // XXX structured error type return H_MAKE_SINT(sgn * x->uint); case TT_DOUBLE: return H_MAKE_DOUBLE(sgn * x->dbl); @@ -626,6 +642,8 @@ act_numb(const HParseResult *p, void *u) } } +#define validate_numb validate_notnull + HParsedToken * act_ref(const HParseResult *p, void *u) { @@ -951,7 +969,7 @@ init_parser(struct Env *aux) H_RULE(epsilon, h_epsilon_p()); H_RULE(empty, SEQ(epsilon)); H_RULE(digits, h_many1(digit)); - H_ARULE(nat, digits); + H_VARULE(nat, digits); H_VRULE(pnat, nat); H_RULE(npair, SEQ(pnat, wel,ws, nat)); @@ -972,7 +990,7 @@ init_parser(struct Env *aux) // XXX ^ we _could_ move the "123." case into intnn... H_RULE(numbnn, CHX(realnn, intnn)); H_RULE(snumb, SEQ(sign, numbnn)); - H_ARULE(numb, CHX(snumb, numbnn)); + H_VARULE(numb, CHX(snumb, numbnn)); /* names */ H_ARULE(nesc, SEQ(hash, hdigit, hdigit));