From 982ab01c40a8fd31554142b85693329fef2a9313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Gro=C3=9Fmann?= Date: Sat, 11 Apr 2026 20:20:52 +0200 Subject: [PATCH 1/4] fix: add missing return value in parse_cookies() parse_cookies() is declared as returning int but had no return statement after free(buf), causing undefined behavior. Fixes #8 --- src/httpshen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/httpshen.c b/src/httpshen.c index 33fc9ac..2b8fd4b 100644 --- a/src/httpshen.c +++ b/src/httpshen.c @@ -44,6 +44,7 @@ parse_cookies(HTTPC *httpc, const UCHAR *in) } free(buf); + return 0; } static int From 2916bb9dcc34d42801429abd5a6f8e2f1a9251dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Gro=C3=9Fmann?= Date: Sat, 11 Apr 2026 20:21:07 +0200 Subject: [PATCH 2/4] fix: prevent integer overflow in environment variable allocation Use size_t instead of int for string length calculations in httpnenv() to prevent integer overflow on long name+value pairs. Add +2 for the two null terminators that were missing from the allocation size. Reject combined lengths over 8192 bytes as a sanity limit. Fixes #7 --- src/httpnenv.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/httpnenv.c b/src/httpnenv.c index e5db879..fcc01b4 100644 --- a/src/httpnenv.c +++ b/src/httpnenv.c @@ -6,9 +6,14 @@ extern HTTPV * httpnenv(const UCHAR *name, const UCHAR *value) { - int namelen = strlen(name); - int vallen = value ? strlen(value) : 0; - HTTPV *v = calloc(1, sizeof(HTTPV)+namelen+vallen); + size_t namelen = strlen(name); + size_t vallen = value ? strlen(value) : 0; + size_t total = sizeof(HTTPV) + namelen + vallen + 2; + HTTPV *v; + + if (namelen + vallen > 8192) return NULL; /* sanity limit */ + + v = calloc(1, total); if (v) { strcpy(v->eye, HTTPV_EYE); From 4f5abeae9dfe6712edbf97734e36287fb3a18bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Gro=C3=9Fmann?= Date: Sat, 11 Apr 2026 20:23:24 +0200 Subject: [PATCH 3/4] fix: replace strtok with reentrant parsing, use snprintf strtok() uses internal static state that is not thread-safe. Replace all strtok() calls with manual pointer-based tokenizers: - httpshen.c: cookie parser - httpdbug.c: debug options parser - httpjes2.c: DSID and jobid list parsers - httpfile.c: SSI directive and quoted value parsers Also replace sprintf with snprintf for version string in httppars.c to prevent potential buffer overflow. Fixes #11 --- src/httpdbug.c | 19 +++++++++++-------- src/httpfile.c | 28 +++++++++++++++++++--------- src/httpjes2.c | 12 ++++++++++-- src/httppars.c | 2 +- src/httpshen.c | 12 +++++++++++- 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/httpdbug.c b/src/httpdbug.c index 3d3c217..96bbac8 100644 --- a/src/httpdbug.c +++ b/src/httpdbug.c @@ -20,25 +20,28 @@ http_debug(HTTPC *httpc, const char *options) http_printf(httpc, "\n"); diff --git a/src/httpfile.c b/src/httpfile.c index da4a1dd..0e59a37 100644 --- a/src/httpfile.c +++ b/src/httpfile.c @@ -283,11 +283,13 @@ ssi_process(HTTPC *httpc, char *ssi) while (isspace(*p)) p++; /* skip any white space */ if (!*p) goto invalid; - p = strtok(p, " "); /* isolate the ssi request */ - if (!p) goto invalid; - - next = strtok(NULL,""); /* remember whatever follows the request */ - if (!next) goto invalid; + /* isolate the ssi request (split at first space) */ + next = p; + while (*next && *next != ' ') next++; + if (!*next) goto invalid; + *next++ = 0; + while (isspace(*next)) next++; + if (!*next) goto invalid; if (http_cmp(p, "echo")==0) { /* next *should* point to whatever follows "