On Wed, 2022-08-17 at 08:49 +0600, NRK wrote:
> I think the `s++` should be removed from the for loop and `s` should
> be incremented as needed inside the loop instead.

Agreed. I've changed it.
From 4a3190695eb3f728496f7f242ab43dfe23a66518 Mon Sep 17 00:00:00 2001
From: HushBugger <hushbug...@posteo.net>
Date: Tue, 16 Aug 2022 22:37:50 +0200
Subject: [PATCH] Fix buffer over-read in decode()

The format specifier for parsing percent-formatted characters uses a
maximum number of digits, not an exact number of digits.

If the hex number has only one digit this will skip a character,
potentially pointing past the terminating null byte.
---
 http.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/http.c b/http.c
index 5b9dade..36f8b1c 100644
--- a/http.c
+++ b/http.c
@@ -135,12 +135,14 @@ decode(const char src[PATH_MAX], char dest[PATH_MAX])
 	uint8_t n;
 	const char *s;
 
-	for (s = src, i = 0; *s; s++, i++) {
-		if (*s == '%' && (sscanf(s + 1, "%2hhx", &n) == 1)) {
+	for (s = src, i = 0; *s; i++) {
+		if (*s == '%' && isxdigit((unsigned char)s[1]) &&
+		    isxdigit((unsigned char)s[2])) {
+			sscanf(s + 1, "%2hhx", &n);
 			dest[i] = n;
-			s += 2;
+			s += 3;
 		} else {
-			dest[i] = *s;
+			dest[i] = *s++;
 		}
 	}
 	dest[i] = '\0';
-- 
2.30.2

Reply via email to