pdf
pdf copied to clipboard
Panic on invalid input to `pdf::file::FileOptions::load`
Describe the bug
Panic could be triggered when passing pdf::file::FileOptions::load with invalid input. Panic info is shown below:
thread 'main' panicked at pdf/src/crypt.rs:156:18:
range end index 16 out of range for slice of length 0
Full stack backtrace:
0: rust_begin_unwind
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/std/src/panicking.rs:652:5
1: core::panicking::panic_fmt
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/panicking.rs:72:14
2: core::slice::index::slice_end_index_len_fail_rt
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/slice/index.rs:66:5
3: core::slice::index::slice_end_index_len_fail
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/slice/index.rs:59:5
4: <core::ops::range::Range<usize> as core::slice::index::SliceIndex<[T]>>::index
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/slice/index.rs:405:13
5: <core::ops::range::RangeTo<usize> as core::slice::index::SliceIndex<[T]>>::index
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/slice/index.rs:453:9
6: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/slice/index.rs:18:9
7: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/alloc/src/vec/mod.rs:2907:9
8: pdf::crypt::Decoder::key
at ./src/crypt.rs:156:18
9: pdf::crypt::Decoder::decrypt
at ./src/crypt.rs:581:42
10: pdf::parser::Context::decrypt
at ./src/parser/mod.rs:48:13
11: pdf::parser::_parse_with_lexer_ctx
at ./src/parser/mod.rs:252:25
12: pdf::parser::parse_with_lexer_ctx
at ./src/parser/mod.rs:132:11
13: pdf::parser::parse_dictionary_object
at ./src/parser/mod.rs:81:26
14: pdf::parser::_parse_with_lexer_ctx
at ./src/parser/mod.rs:151:23
15: pdf::parser::parse_with_lexer_ctx
at ./src/parser/mod.rs:132:11
16: pdf::parser::parse_object::parse_indirect_object
at ./src/parser/parse_object.rs:26:18
17: pdf::file::Storage<B,OC,SC,L>::resolve_ref
at ./src/file.rs:248:32
18: <pdf::file::StorageResolver<B,OC,SC,L> as pdf::object::Resolve>::resolve_flags
at ./src/file.rs:306:9
19: pdf::object::Resolve::resolve
at ./src/object/mod.rs:63:9
20: <pdf::file::StorageResolver<B,OC,SC,L> as pdf::object::Resolve>::get::{{closure}}
at ./src/file.rs:327:19
21: globalcache::sync::SyncCache<K,V>::get
at /DATA2/dev/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/globalcache-0.2.4/src/sync.rs:71:29
22: <alloc::sync::Arc<globalcache::sync::SyncCache<pdf::object::PlainRef,T>> as pdf::file::Cache<T>>::get_or_compute
at ./src/file.rs:55:9
23: <pdf::file::StorageResolver<B,OC,SC,L> as pdf::object::Resolve>::get
at ./src/file.rs:326:19
24: <pdf::object::RcRef<T> as pdf::object::Object>::from_primitive
at ./src/object/mod.rs:271:40
25: <core::option::Option<T> as pdf::object::Object>::from_primitive
at ./src/object/mod.rs:741:24
26: <pdf::file::Trailer as pdf::object::FromDict>::from_dict
at ./src/file.rs:672:10
27: <pdf::file::Trailer as pdf::object::Object>::from_primitive
at ./src/file.rs:672:10
28: pdf::file::File<B,OC,SC,L>::load_data
at ./src/file.rs:619:26
29: pdf::file::FileOptions<OC,SC,L>::load
at ./src/file.rs:602:9
30: fz_unencrypted_strings::main
at ./bin/fz_unencrypted_strings.rs:9:27
Expected behavior
Not panic. It could be an error reported to the users.
Test environment:
Version: pdf = main branch (commit: f87d3f5e90bddc9df8e0e144b06f2727e7afcc7e) OS: Ubuntu 20.04, 64 bit Target triple: x86_64-unknown-linux-gnu Rustc version: rustc 1.80.0-nightly (c987ad527 2024-05-01)
To Reproduce
It can be reproduced with the following program:
fn main() {
let p = "crash.pdf";
if let Ok(data) = std::fs::read(p) {
if let Ok(file) = pdf::file::FileOptions::cached().load(data.as_slice()) {
for idx in 0..file.num_pages() {
let _ = file.get_page(idx);
}
}
}
}
crash.pdf is attached: