Panic: Range end index out of range in enc.rs
## Description
Hello, I discovered a panic in `pdf-rs` while fuzzing.
The parser panics with "range end index out of range" when processing a specific input. I attach the crashing input as a PoC file to the issue.
## Crash Location
* `pdf/src/enc.rs:417`
* **Message:** `range end index out of range`
## Fuzz Target
Here are the fuzz target and PoC that I used.
```rust
#![no_main]
use libfuzzer_sys::fuzz_target;
use pdf::enc::*;
use std::convert::TryInto;
fn get_i32(data: &[u8], offset: &mut usize) -> i32 {
if *offset + 4 > data.len() {
return 0;
}
let val = i32::from_le_bytes(data[*offset..*offset+4].try_into().unwrap());
*offset += 4;
val
}
fuzz_target!(|data: &[u8]| {
if data.len() < 1 { return; }
let mut offset = 0;
let filter_type = data[offset] % 6;
offset += 1;
let filter = match filter_type {
0 => StreamFilter::ASCIIHexDecode,
1 => StreamFilter::ASCII85Decode,
2 | 3 => {
let predictor = get_i32(data, &mut offset);
let n_components = get_i32(data, &mut offset);
let bits_per_component = get_i32(data, &mut offset);
let columns = get_i32(data, &mut offset);
let early_change = get_i32(data, &mut offset);
let params = LZWFlateParams {
predictor,
n_components,
bits_per_component,
columns,
early_change
};
if filter_type == 2 {
StreamFilter::LZWDecode(params)
} else {
StreamFilter::FlateDecode(params)
}
},
4 => StreamFilter::RunLengthDecode,
5 => {
let color_transform = Some(get_i32(data, &mut offset));
StreamFilter::DCTDecode(DCTDecodeParams { color_transform })
},
_ => return
};
if offset > data.len() { return; }
let payload = &data[offset..];
let _ = decode(payload, &filter);
});
```
[poc.zip](https://github.com/user-attachments/files/24302267/poc.zip)
## Stack Trace
```text
thread '<unnamed>' (14120) panicked at /home/sun/pdf/pdf/src/enc.rs:417:37:
range end index 110 out of range for slice of length 2
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/panicking.rs:689:5
1: core::panicking::panic_fmt
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/core/src/panicking.rs:80:14
2: core::slice::index::slice_index_fail::do_panic::runtime
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/core/src/panic.rs:173:21
3: core::slice::index::slice_index_fail
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/core/src/panic.rs:178:9
4: <core::ops::range::Range<usize> as core::slice::index::SliceIndex<[u8]>>::index
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/core/src/slice/index.rs:443:13
5: <[u8] as core::ops::index::Index<core::ops::range::Range<usize>>>::index
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/core/src/slice/index.rs:19:15
6: pdf::enc::run_length_decode
at /home/sun/pdf/pdf/src/enc.rs:417:37
7: pdf::enc::decode
at /home/sun/pdf/pdf/src/enc.rs:469:42
8: decode::_::__libfuzzer_sys_run
at ./fuzz_targets/decode.rs:69:13
9: rust_fuzzer_test_input
at /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/src/lib.rs:276:60
10: libfuzzer_sys::test_input_wrap::{closure#0}
at /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/src/lib.rs:62:9
11: std::panicking::catch_unwind::do_call::<libfuzzer_sys::test_input_wrap::{closure#0}, i32>
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/panicking.rs:581:40
12: __rust_try
13: std::panicking::catch_unwind::<i32, libfuzzer_sys::test_input_wrap::{closure#0}>
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/panicking.rs:544:19
14: std::panic::catch_unwind::<libfuzzer_sys::test_input_wrap::{closure#0}, i32>
at /rustc/1aa9bab4ecbce4859eaad53000f78158ebe2be2c/library/std/src/panic.rs:359:14
15: LLVMFuzzerTestOneInput
at /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/src/lib.rs:60:22
16: _ZN6fuzzer6Fuzzer15ExecuteCallbackEPKhm
at /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/libfuzzer/FuzzerLoop.cpp:619:15
17: _ZN6fuzzer10RunOneTestEPNS_6FuzzerEPKcm
at /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/libfuzzer/FuzzerDriver.cpp:328:21
18: _ZN6fuzzer12FuzzerDriverEPiPPPcPFiPKhmE
at /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/libfuzzer/FuzzerDriver.cpp:863:19
19: main
at /home/sun/.cargo/registry/src/rsproxy.cn-e3de039b2554c837/libfuzzer-sys-0.4.10/libfuzzer/FuzzerMain.cpp:20:30
20: __libc_start_call_main
at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
21: __libc_start_main_impl
at ./csu/../csu/libc-start.c:360:3
22: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
==14120== ERROR: libFuzzer: deadly signal
```
关闭于 2025-12-23 1 条评论