diff options
author | Ben Deutsch <ben@bendeutsch.de> | 2018-01-30 22:12:40 +0100 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2020-02-01 14:05:26 +0100 |
commit | 2b3490db1f0e99a427e34135770f8e5afcf275ce (patch) | |
tree | 8da1c031def8d582ba2ce7b79002811e150c1808 /src/unittest/test_compression.cpp | |
parent | 1116918dbbbf7f36920c6d43a4fc504a09f0df49 (diff) | |
download | minetest-2b3490db1f0e99a427e34135770f8e5afcf275ce.tar.gz minetest-2b3490db1f0e99a427e34135770f8e5afcf275ce.tar.bz2 minetest-2b3490db1f0e99a427e34135770f8e5afcf275ce.zip |
Add limit parameter to decompressZlib
This can prevent untrusted data, such as sent over the network,
from consuming all memory with a specially crafted payload.
Diffstat (limited to 'src/unittest/test_compression.cpp')
-rw-r--r-- | src/unittest/test_compression.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/unittest/test_compression.cpp b/src/unittest/test_compression.cpp index 7d0378131..dfcadd4b2 100644 --- a/src/unittest/test_compression.cpp +++ b/src/unittest/test_compression.cpp @@ -37,6 +37,8 @@ public: void testRLECompression(); void testZlibCompression(); void testZlibLargeData(); + void testZlibLimit(); + void _testZlibLimit(u32 size, u32 limit); }; static TestCompression g_test_instance; @@ -46,6 +48,7 @@ void TestCompression::runTests(IGameDef *gamedef) TEST(testRLECompression); TEST(testZlibCompression); TEST(testZlibLargeData); + TEST(testZlibLimit); } //////////////////////////////////////////////////////////////////////////////// @@ -170,3 +173,63 @@ void TestCompression::testZlibLargeData() i, str_decompressed[i], i, data_in[i]); } } + +void TestCompression::testZlibLimit() +{ + // edge cases + _testZlibLimit(1024, 1023); + _testZlibLimit(1024, 1024); + _testZlibLimit(1024, 1025); + + // test around buffer borders + u32 bufsize = 16384; // as in implementation + for (int s = -1; s <= 1; s++) + { + for (int l = -1; l <= 1; l++) + { + _testZlibLimit(bufsize + s, bufsize + l); + } + } + // span multiple buffers + _testZlibLimit(35000, 22000); + _testZlibLimit(22000, 35000); +} + +void TestCompression::_testZlibLimit(u32 size, u32 limit) +{ + infostream << "Test: Testing zlib wrappers with a decompression " + "memory limit of " << limit << std::endl; + + infostream << "Test: Input size of compressZlib for limit is " + << size << std::endl; + + // how much data we expect to get + u32 expected = size < limit ? size : limit; + + // create recognizable data + std::string data_in; + data_in.resize(size); + for (u32 i = 0; i < size; i++) + data_in[i] = (u8)(i % 256); + + std::ostringstream os_compressed(std::ios::binary); + compressZlib(data_in, os_compressed); + infostream << "Test: Output size of compressZlib for limit is " + << os_compressed.str().size()<<std::endl; + + std::istringstream is_compressed(os_compressed.str(), std::ios::binary); + std::ostringstream os_decompressed(std::ios::binary); + decompressZlib(is_compressed, os_decompressed, limit); + infostream << "Test: Output size of decompressZlib with limit is " + << os_decompressed.str().size() << std::endl; + + std::string str_decompressed = os_decompressed.str(); + UASSERTEQ(size_t, str_decompressed.size(), expected); + + for (u32 i = 0; i < size && i < str_decompressed.size(); i++) { + UTEST(str_decompressed[i] == data_in[i], + "index out[%i]=%i differs from in[%i]=%i", + i, str_decompressed[i], i, data_in[i]); + } +} + |