pdf icon indicating copy to clipboard operation
pdf copied to clipboard

Panic on invalid input to `pdf::file::FileOptions::load`

Open MinghuaWang opened this issue 7 months ago • 0 comments

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:

crash.pdf

MinghuaWang avatar May 12 '25 02:05 MinghuaWang