summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorVladislav Shchapov <vladislav@shchapov.ru>2026-01-14 01:02:47 +0500
committerHans Kristian Rosbach <hk-github@circlestorm.org>2026-01-20 12:32:09 +0100
commitfb9a6cee44b6d859ac5154ea0e847dc60e75bba9 (patch)
treea9ac6d715fd21987d223a0a82989fb76b9454c50 /test
parent503b995b7bb560114a70babb80e99df8ad206a03 (diff)
downloadProject-Tick-fb9a6cee44b6d859ac5154ea0e847dc60e75bba9.tar.gz
Project-Tick-fb9a6cee44b6d859ac5154ea0e847dc60e75bba9.zip
Make deflate output deterministic if PREFIX3(stream) is reused after deflateReset
Co-authored-by: Marcin Kowalczyk <QrczakMK@gmail.com> Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt19
-rw-r--r--test/test_deflate_deterministic.cc71
2 files changed, 81 insertions, 9 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a71949da26..37c649d65d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -178,15 +178,16 @@ if(WITH_GTEST)
if(NOT TEST_STOCK_ZLIB)
list(APPEND TEST_SRCS
- test_adler32.cc # adler32_neon(), etc
- test_adler32_copy.cc # adler32_copy implementations
- test_compare256.cc # compare256_neon(), etc
- test_compare256_rle.cc # compare256_rle(), etc
- test_crc32.cc # crc32_armv8(), etc
- test_crc32_copy.cc # crc32_copy implementations
- test_inflate_sync.cc # expects a certain compressed block layout
- test_main.cc # cpu_check_features()
- test_version.cc # expects a fixed version string
+ test_adler32.cc # adler32_neon(), etc
+ test_adler32_copy.cc # adler32_copy implementations
+ test_compare256.cc # compare256_neon(), etc
+ test_compare256_rle.cc # compare256_rle(), etc
+ test_crc32.cc # crc32_armv8(), etc
+ test_crc32_copy.cc # crc32_copy implementations
+ test_deflate_deterministic.cc # deterministic output after deflateReset
+ test_inflate_sync.cc # expects a certain compressed block layout
+ test_main.cc # cpu_check_features()
+ test_version.cc # expects a fixed version string
)
endif()
diff --git a/test/test_deflate_deterministic.cc b/test/test_deflate_deterministic.cc
new file mode 100644
index 0000000000..5cb5cb4ff1
--- /dev/null
+++ b/test/test_deflate_deterministic.cc
@@ -0,0 +1,71 @@
+/* test_deflate_deterministic.cc - Test deterministic output after deflateReset */
+
+#include "zbuild.h"
+#ifdef ZLIB_COMPAT
+# include "zlib.h"
+#else
+# include "zlib-ng.h"
+#endif
+
+#include <string>
+#include <gtest/gtest.h>
+
+#include "deflate.h"
+#include "test_shared.h"
+
+
+
+/* Issue: https://github.com/zlib-ng/zlib-ng/issues/2100 */
+
+/* len(data_b) must be greater len(data_a) */
+static const uint8_t data_a[] = { 0 , 'A', 'A', 'A', 'A', 0 , 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A' };
+static const uint8_t data_b[] = { 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B' };
+
+static std::string compress_data(const uint8_t *src, size_t len, PREFIX3(stream)* z_stream) {
+ const uint32_t buffer_size = 1024;
+ uint8_t buffer[buffer_size];
+ int err;
+
+ z_stream->next_in = (z_const uint8_t *)src;
+ z_stream->avail_in = (uint32_t)len;
+ z_stream->next_out = buffer;
+ z_stream->avail_out = buffer_size;
+ err = PREFIX(deflate)(z_stream, Z_FINISH);
+ EXPECT_EQ(err, Z_STREAM_END);
+ return std::string((const char *)buffer, (size_t)(z_stream->next_out - buffer));
+}
+
+TEST(deflate, deterministic) {
+ const int compression_level = 6;
+ const int window_bits = 15;
+ int err;
+
+ PREFIX3(stream) a_stream;
+ memset(&a_stream, 0, sizeof(a_stream));
+
+ /* Compress a with newly created z_stream. */
+ err = PREFIX(deflateInit2)(&a_stream, compression_level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
+ EXPECT_EQ(err, Z_OK);
+
+ const std::string a_compressed = compress_data(data_a, sizeof(data_a), &a_stream);
+ err = PREFIX(deflateEnd)(&a_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ /* Compress b with newly created z_stream. */
+ PREFIX3(stream) b_stream;
+ memset(&b_stream, 0, sizeof(b_stream));
+
+ err = PREFIX(deflateInit2)(&b_stream, compression_level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
+ EXPECT_EQ(err, Z_OK);
+ const std::string b_compressed = compress_data(data_b, sizeof(data_b), &b_stream);
+
+ /* Reset the stream. */
+ err = PREFIX(deflateReset)(&b_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ const std::string a_compressed2 = compress_data(data_a, sizeof(data_a), &b_stream);
+ err = PREFIX(deflateEnd)(&b_stream);
+ EXPECT_EQ(err, Z_OK);
+
+ EXPECT_EQ(a_compressed, a_compressed2);
+}