Skip to content

Commit 7ee1528

Browse files
authored
GH-53518: [Parquet] Reject unsupported compression codecs (#53522)
### Rationale for this change See #53518 for rationale. Treating unknown compression codecs as `UNCOMPRESSED` is wrong and at best causes the read to fail late during decoding and at worst yields incorrect results if the compressed stream is actually a valid decodable set of bytes (very unlikely). ### What changes are included in this PR? This PR causes unsupported compression codecs to fail a read eagerly during Thrift parsing. ### Are these changes tested? Yes, new test case added to `metadata_test.cc` ### Are there any user-facing changes? No ### Was AI used for this PR? **PR code and description written by:** - [x] Human - [x] AI **Reviewed before submission by:** - [x] Human - [ ] AI - [ ] Not reviewed Closes #53518 * GitHub Issue: #53518 Authored-by: Divjot Arora <[email protected]> Signed-off-by: Antoine Pitrou <[email protected]>
1 parent b61b1c7 commit 7ee1528

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

‎cpp/src/parquet/metadata_test.cc‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@
1717

1818
#include "parquet/metadata.h"
1919

20+
#include <gmock/gmock.h>
2021
#include <gtest/gtest.h>
2122

23+
#include <cstring>
24+
2225
#include "arrow/util/key_value_metadata.h"
26+
#include "parquet/exception.h"
2327
#include "parquet/file_reader.h"
2428
#include "parquet/file_writer.h"
2529
#include "parquet/schema.h"
@@ -344,6 +348,23 @@ void AssertColumnChunkMinMax(const FileMetaData& metadata,
344348

345349
} // namespace
346350

351+
TEST(Metadata, UnknownCompressionCodecThrows) {
352+
format::FileMetaData thrift_metadata = SingleInt32MetadataWithStats();
353+
auto metadata = ParseMetadata(SerializeMetadata(thrift_metadata));
354+
355+
auto& column_chunk = thrift_metadata.row_groups.at(0).columns.at(0);
356+
const int32_t raw_codec = 8;
357+
static_assert(sizeof(column_chunk.meta_data.codec) == sizeof(raw_codec));
358+
std::memcpy(&column_chunk.meta_data.codec, &raw_codec, sizeof(raw_codec));
359+
360+
auto column = ColumnChunkMetaData::Make(&column_chunk, metadata->schema()->Column(0));
361+
362+
EXPECT_THROW_THAT([&]() { column->compression(); }, ParquetException,
363+
::testing::Property(
364+
&ParquetException::what,
365+
::testing::HasSubstr("Unsupported compression codec value: 8")));
366+
}
367+
347368
TEST(Metadata, UnknownColumnOrderIgnoresMinMax) {
348369
format::FileMetaData thrift_metadata = SingleInt32MetadataWithStats();
349370
// Simulate an unsupported ColumnOrder value: unknown union fields are skipped by

‎cpp/src/parquet/thrift_internal.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ inline typename Compression::type LoadEnumSafe(const format::CompressionCodec::t
227227
const auto max_value =
228228
static_cast<decltype(raw_value)>(format::CompressionCodec::LZ4_RAW);
229229
if (raw_value < min_value || raw_value > max_value) {
230-
return Compression::UNCOMPRESSED;
230+
throw ParquetException("Unsupported compression codec value: ", raw_value);
231231
}
232232
return FromThriftUnsafe(*in);
233233
}

0 commit comments

Comments
 (0)