Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clickhouse/base/compressed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ bool CompressedInput::Decompress() {
throw CompressionError("compressed data too big");
}

if (compressed < HEADER_SIZE) {
throw CompressionError("compressed data too small");
}

Buffer tmp(compressed);

// Data header
Expand Down
34 changes: 34 additions & 0 deletions ut/stream_ut.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
#include <clickhouse/base/wire_format.h>
#include <clickhouse/base/output.h>
#include <clickhouse/base/input.h>
#include <clickhouse/base/compressed.h>

#include <gtest/gtest.h>

using namespace clickhouse;

namespace {

Buffer MakeCompressedBlockHeader(uint32_t compressed_size) {
Buffer buffer;
BufferOutput output(&buffer);

uint8_t hash[16] = {};
const uint8_t method = 0x82;
const uint32_t original_size = 0;

WireFormat::WriteFixed(output, hash);
WireFormat::WriteFixed(output, method);
WireFormat::WriteFixed(output, compressed_size);
WireFormat::WriteFixed(output, original_size);
output.Flush();

return buffer;
}

}

TEST(CodedStreamCase, Varint64) {
Buffer buf;

Expand All @@ -22,3 +44,15 @@ TEST(CodedStreamCase, Varint64) {
ASSERT_EQ(value, 18446744071965638648ULL);
}
}

TEST(CompressedInputCase, RejectsBlocksShorterThanHeader) {
for (const uint32_t compressed_size : {0U, 1U, 8U}) {
Buffer buffer = MakeCompressedBlockHeader(compressed_size);
ArrayInput input(buffer.data(), buffer.size());
CompressedInput compressed_input(&input);
const void* data = nullptr;

EXPECT_THROW(compressed_input.Next(&data, 1), CompressionError)
<< "compressed size: " << compressed_size;
}
}
Loading