Fix an issue where the ByteSource path (used for parsing std::string)
would incorrectly accept some invalid varints that the other path would not, causing potential CHECK-failures if the unit test were run with --write_uncompressed and a corrupted input file. Found by the afl fuzzer.
This commit is contained in:
@@ -196,6 +196,7 @@ void Test_Snappy_RandomData();
|
|||||||
void Test_Snappy_FourByteOffset();
|
void Test_Snappy_FourByteOffset();
|
||||||
void Test_SnappyCorruption_TruncatedVarint();
|
void Test_SnappyCorruption_TruncatedVarint();
|
||||||
void Test_SnappyCorruption_UnterminatedVarint();
|
void Test_SnappyCorruption_UnterminatedVarint();
|
||||||
|
void Test_SnappyCorruption_OverflowingVarint();
|
||||||
void Test_Snappy_ReadPastEndOfBuffer();
|
void Test_Snappy_ReadPastEndOfBuffer();
|
||||||
void Test_Snappy_FindMatchLength();
|
void Test_Snappy_FindMatchLength();
|
||||||
void Test_Snappy_FindMatchLengthRandom();
|
void Test_Snappy_FindMatchLengthRandom();
|
||||||
@@ -500,6 +501,7 @@ static inline int RUN_ALL_TESTS() {
|
|||||||
snappy::Test_Snappy_FourByteOffset();
|
snappy::Test_Snappy_FourByteOffset();
|
||||||
snappy::Test_SnappyCorruption_TruncatedVarint();
|
snappy::Test_SnappyCorruption_TruncatedVarint();
|
||||||
snappy::Test_SnappyCorruption_UnterminatedVarint();
|
snappy::Test_SnappyCorruption_UnterminatedVarint();
|
||||||
|
snappy::Test_SnappyCorruption_OverflowingVarint();
|
||||||
snappy::Test_Snappy_ReadPastEndOfBuffer();
|
snappy::Test_Snappy_ReadPastEndOfBuffer();
|
||||||
snappy::Test_Snappy_FindMatchLength();
|
snappy::Test_Snappy_FindMatchLength();
|
||||||
snappy::Test_Snappy_FindMatchLengthRandom();
|
snappy::Test_Snappy_FindMatchLengthRandom();
|
||||||
|
|||||||
@@ -545,7 +545,9 @@ class SnappyDecompressor {
|
|||||||
if (n == 0) return false;
|
if (n == 0) return false;
|
||||||
const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));
|
const unsigned char c = *(reinterpret_cast<const unsigned char*>(ip));
|
||||||
reader_->Skip(1);
|
reader_->Skip(1);
|
||||||
*result |= static_cast<uint32>(c & 0x7f) << shift;
|
uint32 val = c & 0x7f;
|
||||||
|
if (((val << shift) >> shift) != val) return false;
|
||||||
|
*result |= val << shift;
|
||||||
if (c < 128) {
|
if (c < 128) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1007,6 +1007,20 @@ TEST(SnappyCorruption, UnterminatedVarint) {
|
|||||||
&uncompressed));
|
&uncompressed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SnappyCorruption, OverflowingVarint) {
|
||||||
|
string compressed, uncompressed;
|
||||||
|
size_t ulength;
|
||||||
|
compressed.push_back('\xfb');
|
||||||
|
compressed.push_back('\xff');
|
||||||
|
compressed.push_back('\xff');
|
||||||
|
compressed.push_back('\xff');
|
||||||
|
compressed.push_back('\x7f');
|
||||||
|
CHECK(!CheckUncompressedLength(compressed, &ulength));
|
||||||
|
CHECK(!snappy::IsValidCompressedBuffer(compressed.data(), compressed.size()));
|
||||||
|
CHECK(!snappy::Uncompress(compressed.data(), compressed.size(),
|
||||||
|
&uncompressed));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Snappy, ReadPastEndOfBuffer) {
|
TEST(Snappy, ReadPastEndOfBuffer) {
|
||||||
// Check that we do not read past end of input
|
// Check that we do not read past end of input
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user