From 2624ec2f46d4c4cbaca2807adcbe82e8fc75041d Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 13 Jul 2026 11:57:55 +0200 Subject: [PATCH 1/3] Fix signed overflow when parsing chunk length Chunk size is accumulated from hex digits with no bounds check, so a long enough size overflows iChunkLength (int) - UB, yielding a bogus/negative length. Guard the accumulation with an INT_MAX pre-check so it can never overflow. --- src/HttpClient.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/HttpClient.cpp b/src/HttpClient.cpp index 31909d9..7380340 100644 --- a/src/HttpClient.cpp +++ b/src/HttpClient.cpp @@ -4,6 +4,7 @@ #include "HttpClient.h" #include "b64.h" +#include // Initialize constants const char* HttpClient::kUserAgent = "Arduino/2.2.0"; @@ -625,8 +626,12 @@ int HttpClient::available() else if (isHexadecimalDigit(c)) { char digit[2] = {c, '\0'}; + int digitValue = (int)strtol(digit, NULL, 16); - iChunkLength = (iChunkLength * 16) + strtol(digit, NULL, 16); + // Only apply if the value fits in int without overflow. + if (iChunkLength <= ((INT_MAX - digitValue) / 16)) { + iChunkLength = (iChunkLength * 16) + digitValue; + } } } } From 0e715a7920ec8f550e4d66111ea7247d6da7fc7d Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 13 Jul 2026 11:58:08 +0200 Subject: [PATCH 2/3] Prevent iChunkLength underflow in read() read() decremented iChunkLength unconditionally; if it hit 0 mid-chunk it went negative (UB at INT_MIN). Only decrement while it is still positive. --- src/HttpClient.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/HttpClient.cpp b/src/HttpClient.cpp index 7380340..aa6bfeb 100644 --- a/src/HttpClient.cpp +++ b/src/HttpClient.cpp @@ -678,7 +678,10 @@ int HttpClient::read() if (iState == eReadingBodyChunk) { - iChunkLength--; + if (iChunkLength > 0) + { + iChunkLength--; + } if (iChunkLength == 0) { From c762f8d6c212b396bad632a39229e259252193fe Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 13 Jul 2026 11:58:20 +0200 Subject: [PATCH 3/3] Harden Content-Length parsing against overflow The old guard computed value*10+digit first, then checked for wrap-around - but that computation is itself UB and the check may be optimised away. Use a LONG_MAX pre-check so the overflow never happens. --- src/HttpClient.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/HttpClient.cpp b/src/HttpClient.cpp index aa6bfeb..6bdbfd4 100644 --- a/src/HttpClient.cpp +++ b/src/HttpClient.cpp @@ -827,10 +827,10 @@ int HttpClient::readHeader() case eReadingContentLength: if (isdigit(c)) { - long _iContentLength = iContentLength*10 + (c - '0'); - // Only apply if the value didn't wrap around - if (_iContentLength > iContentLength) { - iContentLength = _iContentLength; + int digitValue = c - '0'; + // Only apply if the value fits in long without overflow. + if (iContentLength <= ((LONG_MAX - digitValue) / 10)) { + iContentLength = iContentLength * 10 + digitValue; } } else