Repository: J-F-Liu/lopdf (language: rust)

Issue:
Crash `memory allocation of 66666666666664 bytes failed`
code
```
fn check_file(file_path: &str) {
    let Ok(content) = fs::read(file_path) else {
        return;
    };
    let cursor = Cursor::new(content);
    match Document::load_from(cursor) {
        Ok(mut document) => {
            let pages = document.get_pages();

            let mut doc_clone = document.clone();
            doc_clone.decompress();

            for (i, _) in pages.iter().enumerate() {
                let page_number = (i + 1) as u32;
                let _text = document.extract_text(&[page_number]);
            }

            let _ = document.save_to(&mut Cursor::new(Vec::new()));
        }
        Err(err) => {
            eprintln!("Error reading PDF contents: {}", err)
        }
    }
}
```

crashes 

```
memory allocation of 66666666666664 bytes failed
Aborted (core dumped)



#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff7c4526e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff7c288ff in __GI_abort () at ./stdlib/abort.c:79
#5  0x0000555555618a5a in std::sys::pal::unix::abort_internal () at library/std/src/sys/pal/unix/mod.rs:373
#6  0x000055555561305a in std::process::abort () at library/std/src/process.rs:2388
#7  0x000055555561a651 in std::alloc::rust_oom () at library/std/src/alloc.rs:377
#8  0x000055555561a673 in std::alloc::_::__rg_oom () at library/std/src/alloc.rs:372
#9  0x0000555555630c83 in alloc::alloc::handle_alloc_error::rt_error () at library/alloc/src/alloc.rs:385
#10 alloc::alloc::handle_alloc_error () at library/alloc/src/alloc.rs:391
#11 0x0000555555630c64 in alloc::raw_vec::handle_error () at library/alloc/src/raw_vec.rs:611
#12 0x00005555555d4cfd in alloc::raw_vec::RawVec<u8, alloc::alloc::Global>::with_capacity_zeroed_in<u8, alloc::alloc::Global> (capacity=<optimized out>, alloc=...)
    at /rustc/7120fdac7a6e55a5e4b606256042890b36067052/library/alloc/src/raw_vec.rs:178
#13 alloc::vec::spec_from_elem::{impl#3}::from_elem<alloc::alloc::Global> (elem=0, n=66666666666664, alloc=...)
    at /rustc/7120fdac7a6e55a5e4b606256042890b36067052/library/alloc/src/vec/spec_from_elem.rs:52
#14 alloc::vec::from_elem<u8> (n=<optimized out>, n=<optimized out>) at /rustc/7120fdac7a6e55a5e4b606256042890b36067052/library/alloc/src/vec/mod.rs:2744
#15 lopdf::filters::png::decode_frame (content=..., bytes_per_pixel=1, pixels_per_row=<optimized out>) at /rustc/7120fdac7a6e55a5e4b606256042890b36067052/library/alloc/src/macros.rs:47
#16 0x00005555555d153c in lopdf::object::Stream::decompress_predictor (data=..., params=...) at src/object.rs:675
#17 0x00005555555d0c67 in lopdf::object::Stream::decompress_zlib (input=..., params=...) at src/object.rs:662
#18 lopdf::object::Stream::decompressed_content (self=<optimized out>) at src/object.rs:606
#19 0x00005555555d15fd in lopdf::object::Stream::decompress (self=0x7fffffffc680) at src/object.rs:684
#20 0x00005555555ca4da in lopdf::parser_aux::decode_xref_stream (stream=<error reading variable: Cannot access memory at address 0x2b65>) at src/parser_aux.rs:193
#21 0x00005555555c0ec8 in lopdf::parser::xref_and_trailer::{closure#1}::{closure#0} () at src/nom_parser.rs:431
#22 core::result::Result<((u32, u16), lopdf::object::Object), lopdf::error::Error>::map<((u32, u16), lopdf::object::Object), lopdf::error::Error, (&[u8], core::result::Result<(lopdf::xref::Xref, lopdf::object::Dictionary), lopdf::error::Error>), lopdf::parser::xref_and_trailer::{closure#1}::{closure_env#0}> (self=<error reading variable: Cannot access memory at address 0x8>, 
    op=...) at /rustc/7120fdac7a6e55a5e4b606256042890b36067052/library/core/src/result.rs:771
#23 lopdf::parser::xref_and_trailer::{closure#1} (input=...) at src/nom_parser.rs:429
#24 nom::internal::{impl#12}::parse<&[u8], core::result::Result<(lopdf::xref::Xref, lopdf::object::Dictionary), lopdf::error::Error>, (), lopdf::parser::xref_and_trailer::{closure_env#1}> (
    self=<optimized out>, i=...) at /home/rafal/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/internal.rs:325
#25 0x00005555555cdf42 in nom::branch::{impl#1}::choice<&[u8], core::result::Result<(lopdf::xref::Xref, lopdf::object::Dictionary), lopdf::error::Error>, (), nom::combinator::map::{closure_env#0}<&[u8], (lopdf::xref::Xref, lopdf::object::Dictionary), core::result::Result<(lopdf::xref::Xref, lopdf::object::Dictionary), lopdf::error::Error>, (), nom::sequence::pair::{closure_env#0}<&[u8], lopdf::xref::Xref, lopdf::object::Dictionary, (), fn(&[u8]) -> core::result::Result<(&[u8], lopdf::xref::Xref), nom::internal::Err<()>>, fn(&[u8]) -> core::result::Result<(&[u8], lopdf::object::Dictionary), nom::internal::Err<()>>>, lopdf::parser::xref_and_trailer::{closure_env#0}>, lopdf::parser::xref_and_trailer::{closure_env#1}> (self=0x7fffffffcb10, input=...)
    at /home/rafal/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/branch/mod.rs:146
#26 0x00005555555bcd4f in nom::branch::alt::{closure#0}<&[u8], core::result::Result<(lopdf::xref::Xref, lopdf::object::Dictionary), lopdf::error::Error>, (), (nom::combinator::map::{closure_env#0}<&[u8], (lopdf::xref::Xref, lopdf::object::Dictionary), core::result::Result<(lopdf::xref::Xref, lopdf::object::Dictionary), lopdf::error::Error>, (), nom::sequence::pair::{closure_env#0}<&[u8], lopdf::xref::Xref, lopdf::object::Dictionary, (), fn(&[u8]) -> core::result::Result<(&[u8], lopdf::xref::Xref), nom::internal::Err<()>>, fn(&[u8]) -> core::result::Result<(&[u8], lopdf::object::Dictionary), nom::internal::Err<()>>>, lopdf::parser::xref_and_trailer::{closure_env#0}>, lopdf::parser::xref_and_trailer::{closure_env#1})> (i=...)
    at /home/rafal/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/branch/mod.rs:50
#27 lopdf::parser::xref_and_trailer (input=..., reader=0x7fffffffcdd0) at src/nom_parser.rs:419
#28 lopdf::reader::Reader::read (self=..., filter_func=...) at src/reader.rs:230
#29 0x00005555555a1be6 in lopdf::document::Document::load_internal<std::io::cursor::Cursor<alloc::vec::Vec<u8, alloc::alloc::Global>>> (source=..., capacity=..., filter_func=...)
    at /home/rafal/.cargo/git/checkouts/lopdf-0013854ec52a6141/c25cef3/src/reader.rs:60
```


[crash-d22f0d41a999453d4a5629532c6d43ea7d6958f0.zip](https://github.com/user-attachments/files/16632969/crash-d22f0d41a999453d4a5629532c6d43ea7d6958f0.zip)



Discussion / hints:

Fix patch:
diff --git a/src/filters/png.rs b/src/filters/png.rs
index 1b35e65..8841558 100644
--- a/src/filters/png.rs
+++ b/src/filters/png.rs
@@ -86,8 +86,12 @@ pub fn decode_row(filter: FilterType, bpp: usize, previous: &[u8], current: &mut
 
 pub fn decode_frame(content: &[u8], bytes_per_pixel: usize, pixels_per_row: usize) -> Result<Vec<u8>> {
     let bytes_per_row = bytes_per_pixel * pixels_per_row;
-    let mut previous = vec![0_u8; bytes_per_row];
-    let mut current = vec![0_u8; bytes_per_row];
+    let mut previous = Vec::new();
+    previous.try_reserve(bytes_per_row)?;
+    previous.resize(bytes_per_row, 0_u8);
+    let mut current = Vec::new();
+    current.try_reserve(bytes_per_row)?;
+    current.resize(bytes_per_row, 0_u8);
     let mut decoded = Vec::new();
     let mut pos = 0;
     while pos < content.len() {


Test patch: