elshanhsynv commented on issue #6255:
URL: https://github.com/apache/arrow-rs/issues/6255#issuecomment-6726378424
This still panics on 60.1.0 (`file/metadata/mod.rs:1043`), and we hit it
while fuzzing a Parquet viewer with libFuzzer, so it is reachable from
untrusted files. In case a deterministic reproducer helps, this rewrites a
valid file's footer so column 0 has a negative `data_page_offset`:
```toml
[dependencies]
parquet = { version = "60.1.0", features = ["arrow"] }
arrow-array = "60.1.0"
bytes = "1"
```
```rust
use std::sync::Arc;
use arrow_array::{Int32Array, RecordBatch};
use bytes::Bytes;
use parquet::{
arrow::{ArrowWriter, arrow_reader::ParquetRecordBatchReaderBuilder},
file::metadata::{ParquetMetaDataReader, ParquetMetaDataWriter},
};
fn main() {
let column = Int32Array::from(vec![1, 2, 3]);
let batch = RecordBatch::try_from_iter([("i", Arc::new(column) as
_)]).unwrap();
let mut bytes = Vec::new();
let mut writer = ArrowWriter::try_new(&mut bytes, batch.schema(),
None).unwrap();
writer.write(&batch).unwrap();
writer.close().unwrap();
let bytes = Bytes::from(bytes);
let metadata =
ParquetMetaDataReader::new().parse_and_finish(&bytes).unwrap();
let mut builder = metadata.into_builder();
let mut row_groups = builder.take_row_groups();
let mut group = row_groups.remove(0).into_builder();
let mut columns = group.take_columns();
let first = columns
.remove(0)
.into_builder()
.set_dictionary_page_offset(None)
.set_data_page_offset(-100)
.build()
.unwrap();
columns.insert(0, first);
group = group.set_column_metadata(columns);
let metadata =
builder.set_row_groups(vec![group.build().unwrap()]).build();
// Keep the data pages, replace the footer.
let footer_len =
u32::from_le_bytes(bytes[bytes.len() - 8..bytes.len() -
4].try_into().unwrap()) as usize;
let mut forged = bytes[..bytes.len() - 8 - footer_len].to_vec();
ParquetMetaDataWriter::new(&mut forged, &metadata).finish().unwrap();
let reader =
ParquetRecordBatchReaderBuilder::try_new(Bytes::from(forged))
.unwrap()
.build()
.unwrap();
for batch in reader {
println!("{:?}", batch.map(|b| b.num_rows())); // expected:
Err(...), actual: panic
}
}
```
```
thread 'main' panicked at parquet-60.1.0/src/file/metadata/mod.rs:1043:9:
column start and length should not be negative
```
Note that `ParquetMetaDataReader` accepts the negative offset and the panic
only happens later, when the column chunk is read. Validating in
`ColumnChunkMetaData::from_thrift` (or when building it) would turn this into
an error at open time.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]