tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 4b80e50e76e2dea98aedd0baeb5f45cbd9ad9e40
parent ff824076445da02a66cb85898c85631361e344f3
Author: Ryan VanderMeulen <rvandermeulen@mozilla.com>
Date:   Mon, 10 Nov 2025 13:12:31 +0000

Bug 1998861 - Update Snappy to version 1.2.2. r=dom-storage-reviewers,asuth

Differential Revision: https://phabricator.services.mozilla.com/D271788

Diffstat:
Mdom/cache/FileUtils.cpp | 2+-
Mdom/indexedDB/ActorsParentCommon.cpp | 2+-
Mdom/localstorage/SnappyUtils.cpp | 2+-
Mother-licenses/snappy/README | 2+-
Mother-licenses/snappy/snappy-stubs-public.h | 4++--
Mother-licenses/snappy/src/NEWS | 15+++++++++++++++
Mother-licenses/snappy/src/README.md | 8++++----
Mother-licenses/snappy/src/snappy.cc | 37+++++++++++++++++++++++++++++++++----
Mother-licenses/snappy/src/snappy.h | 22+++++++++++++++++-----
Mother-licenses/snappy/src/snappy_unittest.cc | 13+++++++++++++
10 files changed, 88 insertions(+), 19 deletions(-)

diff --git a/dom/cache/FileUtils.cpp b/dom/cache/FileUtils.cpp @@ -32,7 +32,7 @@ namespace mozilla::dom::cache { -static_assert(SNAPPY_VERSION == 0x010200); +static_assert(SNAPPY_VERSION == 0x010202); using mozilla::dom::quota::Client; using mozilla::dom::quota::CloneFileAndAppend; diff --git a/dom/indexedDB/ActorsParentCommon.cpp b/dom/indexedDB/ActorsParentCommon.cpp @@ -66,7 +66,7 @@ class nsIFile; namespace mozilla::dom::indexedDB { -static_assert(SNAPPY_VERSION == 0x010200); +static_assert(SNAPPY_VERSION == 0x010202); using mozilla::ipc::IsOnBackgroundThread; diff --git a/dom/localstorage/SnappyUtils.cpp b/dom/localstorage/SnappyUtils.cpp @@ -17,7 +17,7 @@ namespace mozilla::dom { -static_assert(SNAPPY_VERSION == 0x010200); +static_assert(SNAPPY_VERSION == 0x010202); bool SnappyCompress(const nsACString& aSource, nsACString& aDest) { MOZ_ASSERT(!aSource.IsVoid()); diff --git a/other-licenses/snappy/README b/other-licenses/snappy/README @@ -7,7 +7,7 @@ constructor warnings. We have replaced its build system with our own. Snappy comes from: https://github.com/google/snappy -We are currently using revision: 1.2.0 +We are currently using revision: 1.2.2 To upgrade to a newer version: 1. Check out the new code using git. diff --git a/other-licenses/snappy/snappy-stubs-public.h b/other-licenses/snappy/snappy-stubs-public.h @@ -39,9 +39,9 @@ #define SNAPPY_MAJOR 1 #define SNAPPY_MINOR 2 -#define SNAPPY_PATCHLEVEL 0 +#define SNAPPY_PATCHLEVEL 2 #define SNAPPY_VERSION \ - ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) + ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL) namespace snappy { diff --git a/other-licenses/snappy/src/NEWS b/other-licenses/snappy/src/NEWS @@ -1,3 +1,18 @@ +Snappy v1.2.2, Mar 26th 2025: + + * We added a new compression level in v1.2.1 which compresses a bit + denser but slower. Decompression speed should be even faster with it. + + * We fixed a very old issue of data corruption when compressed size + exceeds 4GB. This can happen when you compress data close to 4GB + and it's incompressible, for example, random data. + + * Started to use minimum CMake 3.10 because older ones are not + planned to be supported. + + * Various other small fixes and performance improvements (especially + for clang). + Snappy v1.1.10, Mar 8th 2023: * Performance improvements diff --git a/other-licenses/snappy/src/README.md b/other-licenses/snappy/src/README.md @@ -140,10 +140,10 @@ explicitly supports the following: 1. C++11 2. Clang (gcc and MSVC are best-effort). 3. Low level optimizations (e.g. assembly or equivalent intrinsics) for: - 1. [x86](https://en.wikipedia.org/wiki/X86) - 2. [x86-64](https://en.wikipedia.org/wiki/X86-64) - 3. ARMv7 (32-bit) - 4. ARMv8 (AArch64) + - [x86](https://en.wikipedia.org/wiki/X86) + - [x86-64](https://en.wikipedia.org/wiki/X86-64) + - ARMv7 (32-bit) + - ARMv8 (AArch64) 4. Supports only the Snappy compression scheme as described in [format_description.txt](format_description.txt). 5. CMake for building diff --git a/other-licenses/snappy/src/snappy.cc b/other-licenses/snappy/src/snappy.cc @@ -74,6 +74,7 @@ #include <cstdint> #include <cstdio> #include <cstring> +#include <functional> #include <memory> #include <string> #include <utility> @@ -1498,7 +1499,7 @@ class SnappyDecompressor { // If ip < ip_limit_min_maxtaglen_ it's safe to read kMaxTagLength from // buffer. const char* ip_limit_min_maxtaglen_; - uint32_t peeked_; // Bytes peeked from reader (need to skip) + uint64_t peeked_; // Bytes peeked from reader (need to skip) bool eof_; // Hit end of input without an error? char scratch_[kMaximumTagLength]; // See RefillTag(). @@ -1689,7 +1690,8 @@ constexpr uint32_t CalculateNeeded(uint8_t tag) { #if __cplusplus >= 201402L constexpr bool VerifyCalculateNeeded() { for (int i = 0; i < 1; i++) { - if (CalculateNeeded(i) != (char_table[i] >> 11) + 1) return false; + if (CalculateNeeded(i) != static_cast<uint32_t>((char_table[i] >> 11)) + 1) + return false; } return true; } @@ -1725,7 +1727,7 @@ bool SnappyDecompressor::RefillTag() { assert(needed <= sizeof(scratch_)); // Read more bytes from reader if needed - uint32_t nbuf = ip_limit_ - ip; + uint64_t nbuf = ip_limit_ - ip; if (nbuf < needed) { // Stitch together bytes from ip and reader to form the word // contents. We store the needed bytes in "scratch_". They @@ -1738,7 +1740,7 @@ bool SnappyDecompressor::RefillTag() { size_t length; const char* src = reader_->Peek(&length); if (length == 0) return false; - uint32_t to_add = std::min<uint32_t>(needed - nbuf, length); + uint64_t to_add = std::min<uint64_t>(needed - nbuf, length); std::memcpy(scratch_ + nbuf, src, to_add); nbuf += to_add; reader_->Skip(to_add); @@ -1792,11 +1794,16 @@ bool GetUncompressedLength(Source* source, uint32_t* result) { return decompressor.ReadUncompressedLength(result); } +size_t Compress(Source* reader, Sink* writer) { + return Compress(reader, writer, CompressionOptions{}); +} + size_t Compress(Source* reader, Sink* writer, CompressionOptions options) { assert(options.level == 1 || options.level == 2); int token = 0; size_t written = 0; size_t N = reader->Available(); + assert(N <= 0xFFFFFFFFu); const size_t uncompressed_size = N; char ulength[Varint::kMax32]; char* p = Varint::Encode32(ulength, N); @@ -2299,6 +2306,12 @@ bool IsValidCompressed(Source* compressed) { } void RawCompress(const char* input, size_t input_length, char* compressed, + size_t* compressed_length) { + RawCompress(input, input_length, compressed, compressed_length, + CompressionOptions{}); +} + +void RawCompress(const char* input, size_t input_length, char* compressed, size_t* compressed_length, CompressionOptions options) { ByteArraySource reader(input, input_length); UncheckedByteArraySink writer(compressed); @@ -2309,6 +2322,12 @@ void RawCompress(const char* input, size_t input_length, char* compressed, } void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length, + char* compressed, size_t* compressed_length) { + RawCompressFromIOVec(iov, uncompressed_length, compressed, compressed_length, + CompressionOptions{}); +} + +void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length, char* compressed, size_t* compressed_length, CompressionOptions options) { SnappyIOVecReader reader(iov, uncompressed_length); @@ -2319,6 +2338,11 @@ void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length, *compressed_length = writer.CurrentDestination() - compressed; } +size_t Compress(const char* input, size_t input_length, + std::string* compressed) { + return Compress(input, input_length, compressed, CompressionOptions{}); +} + size_t Compress(const char* input, size_t input_length, std::string* compressed, CompressionOptions options) { // Pre-grow the buffer to the max length of the compressed output @@ -2332,6 +2356,11 @@ size_t Compress(const char* input, size_t input_length, std::string* compressed, } size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt, + std::string* compressed) { + return CompressFromIOVec(iov, iov_cnt, compressed, CompressionOptions{}); +} + +size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt, std::string* compressed, CompressionOptions options) { // Compute the number of bytes to be compressed. size_t uncompressed_length = 0; diff --git a/other-licenses/snappy/src/snappy.h b/other-licenses/snappy/src/snappy.h @@ -78,8 +78,10 @@ namespace snappy { // Compress the bytes read from "*reader" and append to "*writer". Return the // number of bytes written. + // First version is to preserve ABI. + size_t Compress(Source* reader, Sink* writer); size_t Compress(Source* reader, Sink* writer, - CompressionOptions options = {}); + CompressionOptions options); // Find the uncompressed length of the given stream, as given by the header. // Note that the true length could deviate from this; the stream could e.g. @@ -98,16 +100,22 @@ namespace snappy { // Original contents of *compressed are lost. // // REQUIRES: "input[]" is not an alias of "*compressed". + // First version is to preserve ABI. size_t Compress(const char* input, size_t input_length, - std::string* compressed, CompressionOptions options = {}); + std::string* compressed); + size_t Compress(const char* input, size_t input_length, + std::string* compressed, CompressionOptions options); // Same as `Compress` above but taking an `iovec` array as input. Note that // this function preprocesses the inputs to compute the sum of // `iov[0..iov_cnt-1].iov_len` before reading. To avoid this, use // `RawCompressFromIOVec` below. + // First version is to preserve ABI. + size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt, + std::string* compressed); size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt, std::string* compressed, - CompressionOptions options = {}); + CompressionOptions options); // Decompresses "compressed[0..compressed_length-1]" to "*uncompressed". // Original contents of "*uncompressed" are lost. @@ -151,14 +159,18 @@ namespace snappy { // ... Process(output, output_length) ... // delete [] output; void RawCompress(const char* input, size_t input_length, char* compressed, - size_t* compressed_length, CompressionOptions options = {}); + size_t* compressed_length); + void RawCompress(const char* input, size_t input_length, char* compressed, + size_t* compressed_length, CompressionOptions options); // Same as `RawCompress` above but taking an `iovec` array as input. Note that // `uncompressed_length` is the total number of bytes to be read from the // elements of `iov` (_not_ the number of elements in `iov`). void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length, + char* compressed, size_t* compressed_length); + void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length, char* compressed, size_t* compressed_length, - CompressionOptions options = {}); + CompressionOptions options); // Given data in "compressed[0..compressed_length-1]" generated by // calling the Snappy::Compress routine, this routine diff --git a/other-licenses/snappy/src/snappy_unittest.cc b/other-licenses/snappy/src/snappy_unittest.cc @@ -27,6 +27,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <algorithm> +#include <cinttypes> #include <cmath> #include <cstdlib> #include <random> @@ -484,6 +485,18 @@ TEST(Snappy, MaxBlowup) { Verify(input); } +// Issue #201, when output is more than 4GB, we had a data corruption bug. +// We cannot run this test always because of CI constraints. +TEST(Snappy, DISABLED_MoreThan4GB) { + std::mt19937 rng; + std::uniform_int_distribution<int> uniform_byte(0, 255); + std::string input; + input.resize((1ull << 32) - 1); + for (uint64_t i = 0; i < ((1ull << 32) - 1); ++i) + input[i] = static_cast<char>(uniform_byte(rng)); + Verify(input); +} + TEST(Snappy, RandomData) { std::minstd_rand0 rng(snappy::GetFlag(FLAGS_test_random_seed)); std::uniform_int_distribution<int> uniform_0_to_3(0, 3);