Skip to content

Commit 29d1a76

Browse files
committed
[core/zip] Add test for compression buffer sizes
This would have found any of the previous three commits. (cherry picked from commit 73d8c3d)
1 parent a8cad67 commit 29d1a76

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

core/zip/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ target_include_directories(Core PUBLIC
2222
)
2323

2424
ROOT_INSTALL_HEADERS()
25+
26+
ROOT_ADD_TEST_SUBDIRECTORY(test)

core/zip/test/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright (C) 1995-2024, Rene Brun and Fons Rademakers.
2+
# All rights reserved.
3+
#
4+
# For the licensing terms see $ROOTSYS/LICENSE.
5+
# For the list of contributors see $ROOTSYS/README/CREDITS.
6+
7+
ROOT_ADD_GTEST(ZipTest ZipTest.cxx LIBRARIES Core)

core/zip/test/ZipTest.cxx

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include <Compression.h>
2+
#include <RZip.h>
3+
4+
#include <gtest/gtest.h>
5+
6+
#include <memory>
7+
8+
static void testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::EValues compressionAlgorithm)
9+
{
10+
static constexpr size_t BufferSize = 256;
11+
static constexpr size_t MaxBytes = 128;
12+
static_assert(MaxBytes <= BufferSize, "MaxBytes must be smaller than BufferSize");
13+
static constexpr size_t StartOffset = (BufferSize - MaxBytes) / 2;
14+
// For extra "safety", allocate the buffers on the heap to avoid corrupting the stack should anything go wrong.
15+
std::unique_ptr<char[]> source(new char[BufferSize]);
16+
std::unique_ptr<char[]> target(new char[BufferSize]);
17+
18+
// Fill the buffers with monotonically increasing numbers. This is easy to compress, but that's fine because we scan
19+
// through all possible sizes.
20+
for (size_t i = 0; i < BufferSize; i++) {
21+
source[i] = static_cast<char>(i);
22+
target[i] = static_cast<char>(i);
23+
}
24+
25+
// Now test all possible combinations of target and source sizes. The outer loop is for the target sizes because that
26+
// allows us to check that nothing got overwritten.
27+
for (size_t targetSize = 1; targetSize <= MaxBytes; targetSize++) {
28+
for (size_t sourceSize = 1; sourceSize <= MaxBytes; sourceSize++) {
29+
for (int cxlevel = 1; cxlevel <= 9; cxlevel++) {
30+
int srcsize = static_cast<int>(sourceSize);
31+
int tgtsize = static_cast<int>(targetSize);
32+
int irep = -1;
33+
R__zipMultipleAlgorithm(cxlevel, &srcsize, source.get(), &tgtsize, target.get() + StartOffset, &irep,
34+
compressionAlgorithm);
35+
36+
for (size_t i = 0; i < StartOffset; i++) {
37+
EXPECT_EQ(target[i], static_cast<char>(i));
38+
}
39+
for (size_t i = StartOffset + targetSize + 1; i < BufferSize; i++) {
40+
EXPECT_EQ(target[i], static_cast<char>(i));
41+
}
42+
}
43+
}
44+
}
45+
}
46+
47+
TEST(RZip, ZipBufferSizesOld)
48+
{
49+
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kOldCompressionAlgo);
50+
}
51+
52+
TEST(RZip, ZipBufferSizesZLIB)
53+
{
54+
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kZLIB);
55+
}
56+
57+
TEST(RZip, ZipBufferSizesLZMA)
58+
{
59+
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kLZMA);
60+
}
61+
62+
TEST(RZip, ZipBufferSizesLZ4)
63+
{
64+
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kLZ4);
65+
}
66+
67+
TEST(RZip, ZipBufferSizesZSTD)
68+
{
69+
testZipBufferSizes(ROOT::RCompressionSetting::EAlgorithm::kZSTD);
70+
}

0 commit comments

Comments
 (0)