commit - 86cc2a8811c0ecaa347a5e512ea99e1bd18bda67
commit + c3bc010b87f4bb42e288a001030b71468e4ea051
blob - 129e1591f556a77f2c976bb3b91c4a17977f5dcb
blob + 8f4c3fd4e7d148dca1dfa58ceb3a3dafbb6c0faf
--- pdf.c
+++ pdf.c
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
*/
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)
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);
}
}
+#define validate_numb validate_notnull
+
HParsedToken *
act_ref(const HParseResult *p, void *u)
{
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));
// 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));