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
6 changes: 5 additions & 1 deletion src/Compression/CompressionCodecGorilla.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,14 @@ UInt32 CompressionCodecGorilla::doDecompressData(const char * source, UInt32 sou
if (static_cast<UInt32>(2 + bytes_to_skip) > source_size)
throw Exception(ErrorCodes::CANNOT_DECOMPRESS, "Cannot decompress Gorilla-encoded data. File has wrong header");

if (bytes_to_skip >= uncompressed_size)
if (bytes_to_skip > uncompressed_size)
throw Exception(ErrorCodes::CANNOT_DECOMPRESS, "Cannot decompress Gorilla-encoded data. File has wrong header");

memcpy(dest, &source[2], bytes_to_skip);

/// All data is in the skip section when data_bytes_size > uncompressed_size.
if (bytes_to_skip == uncompressed_size)
return uncompressed_size;
UInt32 source_size_no_header = source_size - bytes_to_skip - 2;
UInt32 uncompressed_size_left = uncompressed_size - bytes_to_skip;
switch (bytes_size)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1
42
100
7
31 changes: 31 additions & 0 deletions tests/queries/0_stateless/03823_gorilla_codec_mismatched_size.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-- Gorilla codec with data_bytes_size larger than the column type.
-- When all data fits in the "skip" section (uncompressed_size < data_bytes_size),
-- decompression should still work correctly.

SET allow_suspicious_codecs = 1;

DROP TABLE IF EXISTS t_gorilla_mismatched;

CREATE TABLE t_gorilla_mismatched (c0 Int16 CODEC(Gorilla(4))) ENGINE = MergeTree() ORDER BY tuple();
INSERT INTO t_gorilla_mismatched (c0) VALUES (1);
SELECT * FROM t_gorilla_mismatched;

-- Also test with codec pipeline
DROP TABLE IF EXISTS t_gorilla_mismatched;
CREATE TABLE t_gorilla_mismatched (c0 Int16 CODEC(Gorilla(4), ZSTD)) ENGINE = MergeTree() ORDER BY tuple();
INSERT INTO t_gorilla_mismatched (c0) VALUES (42);
SELECT * FROM t_gorilla_mismatched;

-- Test with Gorilla(8) on Int16
DROP TABLE IF EXISTS t_gorilla_mismatched;
CREATE TABLE t_gorilla_mismatched (c0 Int16 CODEC(Gorilla(8))) ENGINE = MergeTree() ORDER BY tuple();
INSERT INTO t_gorilla_mismatched (c0) VALUES (100);
SELECT * FROM t_gorilla_mismatched;

-- Test with compact parts (the original issue scenario)
DROP TABLE IF EXISTS t_gorilla_mismatched;
CREATE TABLE t_gorilla_mismatched (c0 Int16 CODEC(Gorilla(4))) ENGINE = MergeTree() ORDER BY tuple() SETTINGS min_bytes_for_wide_part = 10000000000;
INSERT INTO t_gorilla_mismatched (c0) VALUES (7);
SELECT * FROM t_gorilla_mismatched;

DROP TABLE IF EXISTS t_gorilla_mismatched;
Loading