Control: forwarded -1 https://github.com/google/snappy/issues/266

On Sun, 20 Sep 2026 at 07:52:35 +0200, Sebastian Ramacher wrote:
snappy FTBFS on 32 bit architectures:

[ RUN      ] Snappy.LiteralLengthU32Overflow
./snappy_unittest.cc:1011: Failure
Value of: snappy::Uncompress(compressed.data(), compressed.size(), 
&uncompressed)
 Actual: true
Expected: false

./snappy_unittest.cc:1013: Failure
Value of: snappy::IsValidCompressedBuffer(compressed.data(), compressed.size())
 Actual: true
Expected: false

[  FAILED  ] Snappy.LiteralLengthU32Overflow (0 ms)

I think the attached might fix it? (Untested, so no patch tag yet.)

    smcv
From: Simon McVittie <[email protected]>
Date: Tue, 22 Sep 2026 00:06:11 +0100
Subject: Calculate literal_length as 64-bit, even on 32-bit platforms

The test added in 7406111ac "Reject streams with literal spans of
2^32 bytes" fails on 32-bit architectures such as i386, because size_t
on such platforms is still only 32 bits, so the addition of 1 byte
to the result of ExtractLowBytes still overflows and wraps around to 0.
If we do the calculation in 64-bit space even on 32-bit platforms,
this works as intended.

An i386 version of libsnappy is used by ffmpeg, and indirectly
by 32-bit Wine, which is one of the few remaining use-cases for i386.

Bug-Debian: https://bugs.debian.org/1148501
Signed-off-by: Simon McVittie <[email protected]>
---
 snappy.cc | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/snappy.cc b/snappy.cc
index add72f8..f4f5137 100644
--- a/snappy.cc
+++ b/snappy.cc
@@ -1691,7 +1691,8 @@ class SnappyDecompressor {
       // pb              24%        76%
       // bin             24%        76%
       if (SNAPPY_PREDICT_FALSE((c & 0x3) == LITERAL)) {
-        size_t literal_length = (c >> 2) + 1u;
+        // This needs to be larger than 32 bits, even if size_t is 32-bit.
+        uint64_t literal_length = (c >> 2) + 1u;
         if (writer->TryFastAppend(ip, ip_limit_ - ip, literal_length, &op)) {
           assert(literal_length < 61);
           ip += literal_length;
@@ -1708,9 +1709,10 @@ class SnappyDecompressor {
           // returns 0xFFFFFFFF); this is implicitly invalid stream (since
           // uncompressed length is capped with 0xFFFFFFFF); for performance we
           // do not check for this case here.
+          // Because literal_length is 64-bit, the addition here can't overflow.
           literal_length =
               ExtractLowBytes(LittleEndian::Load32(ip), literal_length_length) +
-              size_t{1};
+              uint64_t{1};
           ip += literal_length_length;
         }
 

Reply via email to