From b1ca559e75ea0a8925005996e04b492887cd6e06 Mon Sep 17 00:00:00 2001 From: Patrick Ribbsaeter Date: Mon, 19 Oct 2026 20:11:54 +0200 Subject: [PATCH] fix: ParquetMetaDataPushDecoder bounds check metadata length against file size (#11690) --- parquet/src/file/metadata/push_decoder.rs | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/parquet/src/file/metadata/push_decoder.rs b/parquet/src/file/metadata/push_decoder.rs index 202fa0d..580add5 100644 --- a/parquet/src/file/metadata/push_decoder.rs +++ b/parquet/src/file/metadata/push_decoder.rs @@ -427,6 +427,13 @@ impl ParquetMetaDataPushDecoder { DecodeState::ReadingMetadata(footer_tail) => { let metadata_len: u64 = footer_tail.metadata_length() as u64; + if file_len < footer_len + metadata_len { + return Err(eof_err!( + "Parquet file too small. Size is {} but need {}", + file_len, + footer_len + metadata_len + )); + } let metadata_start = file_len - footer_len - metadata_len; let metadata_end = metadata_start + metadata_len; let metadata_range = metadata_start..metadata_end; @@ -1073,4 +1080,22 @@ mod tests { result => panic!("Expected DecodeResult::Finished, got {result:?}"), } } + + #[test] + fn test_metadata_length_exceeds_file_size() { + // A 12-byte "file": 4 bytes of data, then a footer whose metadata + // length (1000) is larger than the file. + let mut file = vec![0u8; 4]; + file.extend_from_slice(&1000u32.to_le_bytes()); + file.extend_from_slice(b"PAR1"); + let len = file.len() as u64; + + let mut decoder = ParquetMetaDataPushDecoder::try_new(len).unwrap(); + decoder.push_range(0..len, file.into()).unwrap(); + let err = decoder.try_decode().unwrap_err(); + assert_eq!( + err.to_string(), + "EOF: Parquet file too small. Size is 12 but need 1008" + ); + } } -- 2.55.0.windows.3