diff --git a/pdf.c b/pdf.c
index 6514f50022a4312ec156ae9751281934c361d3cf..1f869c19c4970a8e9d2c955ffbe6a61bed6d0be6 100644
--- a/pdf.c
+++ b/pdf.c
@@ -251,15 +251,15 @@ act_pnat(const HParseResult *p, void *u)
 	return H_MAKE_UINT(x);
 }
 
+/* p = (sign, nat) */
 HParsedToken *
 act_intg(const HParseResult *p, void *u)
 {
-	int64_t x = 0;
-	HCountedArray *seq = H_FIELD_SEQ(1);
+	uint64_t xu = H_FIELD_UINT(1);
+	int64_t x;
 
-	// XXX check for overflow
-	for (size_t i = 0; i < seq->used; i++)
-		x = x*10 + H_CAST_UINT(seq->elements[i]);
+	assert(xu <= INT64_MAX);	// XXX add a validation to ensure this
+	x = xu;
 
 	HParsedToken *sgn = H_INDEX_TOKEN(p->ast, 0);
 	if (sgn->token_type == TT_BYTES &&
@@ -525,7 +525,8 @@ init_parser(struct Env *aux)
 	H_RULE(end,	h_end_p());
 	H_RULE(epsilon,	h_epsilon_p());
 	H_RULE(empty,	SEQ(epsilon));
-	H_ARULE(nat,	h_many1(digit));
+	H_RULE(digits,	h_many1(digit));
+	H_ARULE(nat,	digits);
 	H_ARULE(pnat,	SEQ(h_many(zero), pdigit, h_many(digit)));
 	H_RULE(npair,	SEQ(pnat, wel,ws, nat));
 
@@ -540,8 +541,7 @@ init_parser(struct Env *aux)
 	H_RULE(boole,	CHX(TOK(LIT("true")), TOK(LIT("false"))));
 
 	/* numbers */
-	H_RULE(digits,	h_many1(digit));
-	H_ARULE(intg,	TOK(SEQ(h_optional(sign), digits)));
+	H_ARULE(intg,	TOK(SEQ(h_optional(sign), nat)));
 	H_RULE(realnn,	CHX(SEQ(digits, period, digits),	/* 12.3 */
 			    SEQ(digits, period, empty),		/* 123. */
 			    SEQ(empty, period, digits)));	/* .123 */