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

Issue:
Panic `assertion `left == right` 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)
        }
    }
}
```

cause this
```
thread 'main' panicked at /home/runner/.cargo/git/checkouts/lopdf-0013854ec52a6141/2d6052f/src/object.rs:712:9:
assertion `left == right` failed
  left: [126, 62]
 right: [62, 13]
stack backtrace:
   0: rust_begin_unwind
             at /rustc/5ec7d6eee7e0f5236ec1559499070eaf836bc608/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/5ec7d6eee7e0f5236ec1559499070eaf836bc608/library/core/src/panicking.rs:76:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
             at /home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panicking.rs:373:5
   4: lopdf::object::Stream::decode_ascii85
             at /home/runner/.cargo/git/checkouts/lopdf-0013854ec52a6141/2d6052f/src/object.rs:712:9
   5: lopdf::object::Stream::decompressed_content
             at /home/runner/.cargo/git/checkouts/lopdf-0013854ec52a6141/2d6052f/src/object.rs:652:36
   6: lopdf::object::Stream::decompress
             at /home/runner/.cargo/git/checkouts/lopdf-0013854ec52a6141/2d6052f/src/object.rs:773:20
   7: lopdf::processor::<impl lopdf::document::Document>::decompress
             at /home/runner/.cargo/git/checkouts/lopdf-0013854ec52a6141/2d6052f/src/processor.rs:37:25
   8: lopdf::check_file
             at ./src/crates/lopdf/src/main.rs:37:13
   9: lopdf::main
             at ./src/crates/lopdf/src/main.rs:23:9
  10: core::ops::function::FnOnce::call_once
             at /home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

##### Automatic Fuzzer note, output status "None", output signal "Some(6)"
```

[compressed.zip](https://github.com/user-attachments/files/17796437/compressed.zip)



Discussion / hints:

Fix patch:
diff --git a/src/document.rs b/src/document.rs
index ca8a08b..0753083 100644
--- a/src/document.rs
+++ b/src/document.rs
@@ -270,11 +270,15 @@ impl Document {
             .unwrap_or(true);
 
         let key = encryption::get_encryption_key(self, &password, true)?;
-        let cfm = self.get_encrypted()?.get(b"CF")?.as_dict()?
+        let cfm = self
+            .get_encrypted()?
+            .get(b"CF")?
+            .as_dict()?
             .get(b"StdCF")?
             .as_dict()?
             .get(b"CFM")?
-            .as_name().unwrap_or_default();
+            .as_name()
+            .unwrap_or_default();
         let is_aes = cfm == b"AESV2";
         for (&id, obj) in self.objects.iter_mut() {
             // The encryption dictionary is not encrypted, leave it alone
diff --git a/src/object.rs b/src/object.rs
index 2035487..3a685bf 100644
--- a/src/object.rs
+++ b/src/object.rs
@@ -709,8 +709,13 @@ impl Stream {
         let mut buffer: u32 = 0;
         let mut count = 0;
         // Check for EOD marker
-        assert_eq!(b"~>", &input[input.len() - 2..]);
-        for &ch in &input[..input.len() - 2] {
+        let input_no_eod = if input.len() >= 2 && &input[input.len() - 2..] == b"~>" {
+            &input[..input.len() - 2]
+        } else {
+            log::warn!("ASCII85 stream is missing its EOD marker");
+            input
+        };
+        for &ch in input_no_eod {
             if ch == b'z' {
                 if count != 0 {
                     // z character is not allowed in middle of a group


Test patch: