diff --git a/src/common/impl/networking_common.c b/src/common/impl/networking_common.c index ac0930756..c716195ae 100644 --- a/src/common/impl/networking_common.c +++ b/src/common/impl/networking_common.c @@ -146,16 +146,24 @@ bool ffNetworkingDecompressGzip(FFstrbuf* buffer, char* headerEnd) { result = zlibData.ffinflate(&zs, Z_FINISH); } + // Check for decompression errors before using result + if (result != Z_STREAM_END) { + FF_DEBUG("Decompression failed with zlib error: %d", result); + zlibData.ffinflateEnd(&zs); + return false; + } + zlibData.ffinflateEnd(&zs); - // Calculate decompressed size + // Calculate decompressed size (from the last inflate call) uint32_t decompressedSize = (uint32_t) (availableOut - zs.avail_out); decompressedBuffer.length += decompressedSize; decompressedBuffer.chars[decompressedBuffer.length] = '\0'; FF_DEBUG("Successfully decompressed %u bytes compressed data to %u bytes", compressedSize, decompressedBuffer.length); // Modify Content-Length header and remove Content-Encoding header - FF_STRBUF_AUTO_DESTROY newBuffer = ffStrbufCreateA(headerSize + decompressedSize + 64); + // Use decompressedBuffer.length (total) not decompressedSize (last chunk only) + FF_STRBUF_AUTO_DESTROY newBuffer = ffStrbufCreateA(headerSize + decompressedBuffer.length + 64); char* line = NULL; size_t len = 0; diff --git a/src/common/impl/networking_linux.c b/src/common/impl/networking_linux.c index f63bc47aa..0db8d8829 100644 --- a/src/common/impl/networking_linux.c +++ b/src/common/impl/networking_linux.c @@ -448,7 +448,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf // Check for Content-Length header to pre-allocate enough memory const char* clHeader = strcasestr(buffer->chars, "Content-Length:"); if (clHeader) { - contentLength = (uint32_t) strtoul(clHeader + 16, NULL, 10); + contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10); if (contentLength > 0) { FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength); // Ensure buffer is large enough, adding header size and some margin @@ -473,18 +473,18 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf FF_DEBUG("No HTTP header end marker found"); return "No HTTP header end found"; } + + if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) { + FF_DEBUG("Invalid response: %.40s...", buffer->chars); + return "Invalid response"; + } + FF_DEBUG("Received valid HTTP 200 response, content %u bytes, total %u bytes", contentLength, buffer->length); + if (contentLength > 0 && buffer->length != contentLength + headerEnd + 4) { FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + headerEnd + 4); return "Content length mismatch"; } - if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) { - FF_DEBUG("Received valid HTTP 200 response, content %u bytes, total %u bytes", contentLength, buffer->length); - } else { - FF_DEBUG("Invalid response: %.40s...", buffer->chars); - return "Invalid response"; - } - // If compression was used, try to decompress #ifdef FF_HAVE_ZLIB if (state->compression) { diff --git a/src/common/impl/networking_windows.c b/src/common/impl/networking_windows.c index 65eaf2445..dd90948dc 100644 --- a/src/common/impl/networking_windows.c +++ b/src/common/impl/networking_windows.c @@ -320,7 +320,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf // Check for Content-Length header to pre-allocate enough memory const char* clHeader = strcasestr(buffer->chars, "Content-Length:"); if (clHeader) { - contentLength = (uint32_t) strtoul(clHeader + 16, NULL, 10); + contentLength = (uint32_t) strtoul(clHeader + 15, NULL, 10); if (contentLength > 0) { FF_DEBUG("Detected Content-Length: %u, pre-allocating buffer", contentLength); // Ensure buffer is large enough, adding header size and some margin @@ -345,20 +345,20 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf FF_DEBUG("No HTTP header end marker found"); return "No HTTP header end found"; } + + if (!ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) { + FF_DEBUG("Invalid response: %.40s...", buffer->chars); + return "Invalid response"; + } + FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes", + contentLength, + buffer->length); + if (contentLength > 0 && buffer->length != contentLength + headerEnd + 4) { FF_DEBUG("Received content length mismatches: %u != %u", buffer->length, contentLength + headerEnd + 4); return "Content length mismatch"; } - if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) { - FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes", - contentLength, - buffer->length); - } else { - FF_DEBUG("Invalid response: %.40s...", buffer->chars); - return "Invalid response"; - } - // If compression was used, try to decompress #ifdef FF_HAVE_ZLIB if (state->compression) {