summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2023-11-18 19:35:42 +0100
committerTor Egge <Tor.Egge@online.no>2023-11-18 19:35:42 +0100
commit15e5129e06c8c17fc171125768ee60419801ef1e (patch)
tree29896f71aaffc304fdec9956e0030a7ad0220e8c /vespalib
parent20ff0cb482338440f04cc7607a7ec9f0aca81684 (diff)
Avoid reading beyond end of stack dump buffer.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/compress/compress_test.cpp6
-rw-r--r--vespalib/src/vespa/vespalib/util/compress.h26
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);