From 374c470174a4a76ef928430cfb98e696d427c7f2 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 27 May 2026 05:19:03 +0000 Subject: [PATCH] fix: cap HTTP response buffer at 512 KB to prevent OOM on Pi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit writeCallback had no size limit, so a runaway API response (large error HTML, misconfigured proxy, etc.) could exhaust memory on a Pi with limited RAM. Adding a 512 KB hard cap — normal weatherapi.com responses are ~10 KB — and returning 0 from the callback to abort the transfer with CURLE_WRITE_ERROR, which the existing error-handling path already treats as a failed fetch. https://claude.ai/code/session_0166Zd59EUgWgYd3FrphQAio --- src/weather.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/weather.cpp b/src/weather.cpp index 006b51b..22f1d7d 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -26,9 +26,18 @@ std::string urlEncode(const std::string& value) { return escaped.str(); } +constexpr size_t MAX_RESPONSE_BYTES = 512 * 1024; // 512 KB; weatherapi.com responses are ~10 KB + size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp) { - static_cast(userp)->append(static_cast(contents), size * nmemb); - return size * nmemb; + auto* buf = static_cast(userp); + size_t incoming = size * nmemb; + if (buf->size() + incoming > MAX_RESPONSE_BYTES) { + LOG_ERROR("Weather API response exceeds " << (MAX_RESPONSE_BYTES / 1024) + << " KB — aborting fetch"); + return 0; // signals libcurl to abort with CURLE_WRITE_ERROR + } + buf->append(static_cast(contents), incoming); + return incoming; } // Helper: safely extract a string from a JSON value, returning fallback on missing/null.