diff --git a/cpp/src/io/parquet/io_utils/parquet_io_utils.cpp b/cpp/src/io/parquet/io_utils/parquet_io_utils.cpp index e762a0ae2f3a..6f3316581365 100644 --- a/cpp/src/io/parquet/io_utils/parquet_io_utils.cpp +++ b/cpp/src/io/parquet/io_utils/parquet_io_utils.cpp @@ -37,12 +37,10 @@ std::unique_ptr fetch_footer_to_host(cudf::io::dat constexpr auto ender_len = sizeof(file_ender_s); size_t const len = datasource.size(); - auto header_buffer = datasource.host_read(0, header_len); - auto const header = reinterpret_cast(header_buffer->data()); - auto ender_buffer = datasource.host_read(len - ender_len, ender_len); - auto const ender = reinterpret_cast(ender_buffer->data()); CUDF_EXPECTS(len > header_len + ender_len, "Incorrect data source"); - CUDF_EXPECTS(header->magic == detail::parquet_magic, "Corrupted header"); + + auto ender_buffer = datasource.host_read(len - ender_len, ender_len); + auto const ender = reinterpret_cast(ender_buffer->data()); CUDF_EXPECTS(ender->magic == detail::parquet_magic, "Corrupted footer"); CUDF_EXPECTS(ender->footer_len != 0 && ender->footer_len <= (len - header_len - ender_len), "Incorrect footer length"); diff --git a/cpp/tests/io/parquet_reader_test.cpp b/cpp/tests/io/parquet_reader_test.cpp index 9da69f9dad74..7caa41d7b186 100644 --- a/cpp/tests/io/parquet_reader_test.cpp +++ b/cpp/tests/io/parquet_reader_test.cpp @@ -4258,6 +4258,27 @@ TEST_F(ParquetReaderTest, LateBindSourceInfo) CUDF_TEST_EXPECT_TABLES_EQUAL(result.tbl->view(), expected->view()); } +TEST_F(ParquetReaderTest, InvalidFooterMagic) +{ + auto const expected = create_random_fixed_table(4, 4, false); + + std::vector buffer; + cudf::io::write_parquet( + cudf::io::parquet_writer_options::builder(cudf::io::sink_info{&buffer}, *expected)); + + constexpr std::array bad_magic{'B', 'A', 'D', '!'}; + ASSERT_GE(buffer.size(), bad_magic.size()); + for (size_t i = 0; i < bad_magic.size(); ++i) { + buffer[buffer.size() - bad_magic.size() + i] = bad_magic[i]; + } + + auto const read_opts = cudf::io::parquet_reader_options::builder( + cudf::io::source_info{cudf::host_span{ + reinterpret_cast(buffer.data()), buffer.size()}}) + .build(); + EXPECT_THROW(cudf::io::read_parquet(read_opts), cudf::logic_error); +} + TEST_F(ParquetReaderTest, DecimalTypeOption) { auto const data = std::vector{1000, 2000, 3000, 4000, 5000};