From c3bc010b87f4bb42e288a001030b71468e4ea051 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" <pesco@khjk.org> Date: Fri, 19 Jun 2020 21:20:22 +0200 Subject: [PATCH] check for integer overflow --- pdf.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/pdf.c b/pdf.c index 129e159..8f4c3fd 100644 --- a/pdf.c +++ b/pdf.c @@ -102,6 +102,12 @@ 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)); -- GitLab