From 0a7e1e44143be5bd468a07d4b71a28a1d45c3ce4 Mon Sep 17 00:00:00 2001
From: Pompolic <pompolic@special-circumstanc.es>
Date: Thu, 22 Jul 2021 23:14:22 +0200
Subject: [PATCH] Partial ASCII85 digit group fixes

- off by one in act_partial3group led to uninitialized memory ending up in parse result
- Check the numerical value of the resulting HBytes against A85GRPMAX in validations
- Mark printfs as debug output
---
 pdf.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/pdf.c b/pdf.c
index b9b0c05..0bd4483 100644
--- a/pdf.c
+++ b/pdf.c
@@ -427,7 +427,7 @@ act_a85group(const HParseResult *p, void *u)
 		bytes[1] = (fourbytes & 0x00FF0000) >> 16;
 		bytes[2] = (fourbytes & 0x0000FF00) >> 8;
 		bytes[3] = (fourbytes & 0x000000FF);
-		fprintf(stdout, "%6x ==> %2x %2x %2x %2x\n", fourbytes, bytes[0], bytes[1], bytes[2], bytes[3]);
+		fprintf(stdout, "%6x ==> %2x %2x %2x %2x\n", fourbytes, bytes[0], bytes[1], bytes[2], bytes[3]); // XXX debug
 	}
 	return H_MAKE_BYTES(bytes, 4);
 }
@@ -451,10 +451,9 @@ act_a85partial2group(const HParseResult *p, void *u)
 				fourbytes, fourbytes); // XXX DEBUG
 	}
 
-	// fill the other bytes with u (dec 117-33)
-	// XXX I'm confused. I think to restore the padding, '!' needs to be added instead of 'u'
+	// fill the other bytes with 0
 	for (int i=2; i<5; i++) {
-		fourbytes = fourbytes * 85 + 84;
+		fourbytes = fourbytes * 85;
 	}
 
 	// truncate and return only the high order byte
@@ -467,7 +466,7 @@ act_a85partial2group(const HParseResult *p, void *u)
 bool
 validate_a85partial2group(HParseResult *p, void *u)
 {
-	return H_CAST_BYTES(p->ast).token[0] <= A85GRPMAX;
+	return ((H_CAST_BYTES(p->ast).token[0] << 24) + (H_CAST_BYTES(p->ast).token[1] << 16)) <= A85GRPMAX;
 }
 
 HParsedToken *
@@ -487,27 +486,27 @@ act_a85partial3group(const HParseResult *p, void *u)
 		fourbytes = fourbytes * 85 + H_CAST_UINT(digits[i]->seq->elements[0]);
 	}
 
-	// fill the other bytes with u (dec 117-33)
-	for (int i=4; i<5; i++) {
-		fourbytes = fourbytes * 85 + 84;
+	// fill the other bytes with 0
+	for (int i=3; i<5; i++) {
+		fourbytes = fourbytes * 85;
 	}
 
 	// truncate and return only the high order bytes
 	// I think groups of 3 A85 characters decode to 2 bytes
 	bytes[0] = (fourbytes & 0xFF000000) >> 24;
 	bytes[1] = (fourbytes & 0x00FF0000) >> 16;
-	bytes[2] = (fourbytes & 0x0000FF00) >> 8;
+	//bytes[2] = (fourbytes & 0x0000FF00) >> 8;
 
-	fprintf(stdout, "act_a85partial3group: %4x (%d) ==> %2x %2x %2x \n", fourbytes, fourbytes, bytes[0],
-			bytes[1], bytes[2]); // XXX DEBUG
+	fprintf(stdout, "act_a85partial3group: %4x (%d) ==> %2x %2x\n", fourbytes, fourbytes, bytes[0],
+			bytes[1]); // XXX DEBUG
 
-	return H_MAKE_BYTES(bytes, 3); // XXX test: should this be 2?
+	return H_MAKE_BYTES(bytes, 2);
 }
 
 bool
 validate_a85partial3group(HParseResult *p, void *u)
 {
-	return H_CAST_UINT(p->ast) <= A85GRPMAX;
+	return ((H_CAST_BYTES(p->ast).token[0] << 24) + (H_CAST_BYTES(p->ast).token[1] << 16) + (H_CAST_BYTES(p->ast).token[2] << 8)) <= A85GRPMAX;
 }
 
 HParsedToken *
@@ -526,6 +525,10 @@ act_a85partial4group(const HParseResult *p, void *u)
 		assert(digits[i]->token_type == TT_SEQUENCE);
 		fourbytes = fourbytes * 85 + H_CAST_UINT(digits[i]->seq->elements[0]);
 	}
+
+	for (int i=4; i<5; i++) {
+		fourbytes = fourbytes * 85;
+	}
 	// truncate and return only the high order bytes
 	bytes[0] = (fourbytes & 0xFF000000) >> 24;
 	bytes[1] = (fourbytes & 0x00FF0000) >> 16;
@@ -539,7 +542,7 @@ act_a85partial4group(const HParseResult *p, void *u)
 bool
 validate_a85partial4group(HParseResult *p, void *u)
 {
-	return H_CAST_UINT(p->ast) <= A85GRPMAX;
+	return ((H_CAST_BYTES(p->ast).token[0] << 24) + (H_CAST_BYTES(p->ast).token[1] << 16) + (H_CAST_BYTES(p->ast).token[2] << 8)) <= A85GRPMAX;
 }
 
 HParsedToken *
@@ -602,7 +605,7 @@ act_a85string(const HParseResult *p, void *u)
 				chunks->elements[i]->bytes.len == 4);
 		memcpy(result_bytes + out_pos, chunks->elements[i]->bytes.token, 4);
 		fprintf(stdout, "%2x%2x%2x%2x - %8x\n", result_bytes[out_pos], result_bytes[out_pos+1],
-				result_bytes[out_pos+2], result_bytes[out_pos+3], *((unsigned int *)(chunks->elements[i]->bytes.token)));
+				result_bytes[out_pos+2], result_bytes[out_pos+3], *((unsigned int *)(chunks->elements[i]->bytes.token))); // XXX DEBUG
 		out_pos += 4;
 	}
 	if (last_chunk.len) {
-- 
GitLab