diff options
author | Tor Egge <Tor.Egge@online.no> | 2023-11-18 19:35:42 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@online.no> | 2023-11-18 19:35:42 +0100 |
commit | 15e5129e06c8c17fc171125768ee60419801ef1e (patch) | |
tree | 29896f71aaffc304fdec9956e0030a7ad0220e8c /vespalib | |
parent | 20ff0cb482338440f04cc7607a7ec9f0aca81684 (diff) |
Avoid reading beyond end of stack dump buffer.
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/tests/compress/compress_test.cpp | 6 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/compress.h | 26 |
2 files changed, 32 insertions, 0 deletions
diff --git a/vespalib/src/tests/compress/compress_test.cpp b/vespalib/src/tests/compress/compress_test.cpp index 04f71d5cc18..c4383a1c193 100644 --- a/vespalib/src/tests/compress/compress_test.cpp +++ b/vespalib/src/tests/compress/compress_test.cpp @@ -26,6 +26,9 @@ CompressTest::verifyPositiveNumber(uint64_t n, const uint8_t * expected, size_t for (size_t i(0); i < sz; i++) { EXPECT_EQUAL(expected[i], buf[i]); } + EXPECT_FALSE(Integer::check_decompress_positive_space(expected, 0u)); + EXPECT_FALSE(Integer::check_decompress_positive_space(expected, sz - 1)); + EXPECT_TRUE(Integer::check_decompress_positive_space(expected, sz)); uint64_t v(0); EXPECT_EQUAL(sz, Integer::decompressPositive(v, expected)); EXPECT_EQUAL(n, v); @@ -39,6 +42,9 @@ CompressTest::verifyNumber(int64_t n, const uint8_t * expected, size_t sz) { for (size_t i(0); i < sz; i++) { EXPECT_EQUAL(expected[i], buf[i]); } + EXPECT_FALSE(Integer::check_decompress_space(expected, 0u)); + EXPECT_FALSE(Integer::check_decompress_space(expected, sz - 1)); + EXPECT_TRUE(Integer::check_decompress_space(expected, sz)); int64_t v(0); EXPECT_EQUAL(sz, Integer::decompress(v, expected)); EXPECT_EQUAL(n, v); diff --git a/vespalib/src/vespa/vespalib/util/compress.h b/vespalib/src/vespa/vespalib/util/compress.h index 5cf2814f3ea..66234da0e32 100644 --- a/vespalib/src/vespa/vespalib/util/compress.h +++ b/vespalib/src/vespa/vespalib/util/compress.h @@ -105,6 +105,32 @@ public: } return numbytes; } + + static bool check_decompress_space(const void* srcv, size_t len) { + if (len == 0u) { + return false; + } + const uint8_t * src = static_cast<const uint8_t *>(srcv); + const uint8_t c = src[0]; + if ((c & 0x40) != 0) { + return (((c & 0x20) != 0) ? (len >= 4u) : (len >= 2u)); + } else { + return true; + } + } + + static bool check_decompress_positive_space(const void* srcv, size_t len) { + if (len == 0u) { + return false; + } + const uint8_t * src = static_cast<const uint8_t *>(srcv); + const uint8_t c = src[0]; + if ((c & 0x80) != 0) { + return (((c & 0x40) != 0) ? (len >= 4u) : (len >= 2u)); + } else { + return true; + } + } private: [[ noreturn ]] static void throw_too_big(int64_t n); [[ noreturn ]] static void throw_too_big(uint64_t n); |