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

Issue:
Unpack objects after decrypting object streams
Upon decryption, we can finally inspect and parse the object streams that we could not handle in `Reader::read()`. This code adds the same code from `Reader::read()` to `Document::decrypt()` to add the new objects from the decrypted object stream(s), but has been simplified as we only have to deal with object streams at this point.

This partially fixes #369.


Discussion / hints:

Fix patch:
diff --git a/src/document.rs b/src/document.rs
index 11679d3..28ed5d3 100644
--- a/src/document.rs
+++ b/src/document.rs
@@ -309,12 +309,19 @@ impl Document {
             };
 
             if !stream.dict.has_type(b"ObjStm") {
-                let obj_stream = ObjectStream::new(stream).ok().unwrap();
-
-                // TODO: Is insert and replace intended behavior?
-                // See https://github.com/J-F-Liu/lopdf/issues/160 for more info
-                object_streams.extend(obj_stream.objects);
+                continue;
             }
+
+            let obj_stream = ObjectStream::new(stream).ok().unwrap();
+
+            // TODO: Is insert and replace intended behavior?
+            // See https://github.com/J-F-Liu/lopdf/issues/160 for more info
+            object_streams.extend(obj_stream.objects);
+        }
+
+        // Only add entries, but never replace entries
+        for (id, entry) in object_streams {
+            self.objects.entry(id).or_insert(entry);
         }
 
         self.trailer.remove(b"Encrypt");
diff --git a/src/reader.rs b/src/reader.rs
index f502c3d..6428504 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -284,6 +284,8 @@ impl Reader<'_> {
         self.document.trailer = trailer;
         self.document.reference_table = xref;
 
+        let is_encrypted = self.document.trailer.get(b"Encrypt").is_ok();
+
         let zero_length_streams = Mutex::new(vec![]);
         let object_streams = Mutex::new(vec![]);
 
@@ -296,8 +298,9 @@ impl Reader<'_> {
                 if let Some(filter_func) = filter_func {
                     filter_func(object_id, &mut object)?;
                 }
+
                 if let Ok(ref mut stream) = object.as_stream_mut() {
-                    if stream.dict.has_type(b"ObjStm") {
+                    if stream.dict.has_type(b"ObjStm") && !is_encrypted {
                         let obj_stream = ObjectStream::new(stream).ok()?;
                         let mut object_streams = object_streams.lock().unwrap();
                         // TODO: Is insert and replace intended behavior?
@@ -317,6 +320,7 @@ impl Reader<'_> {
                         zero_length_streams.push(object_id);
                     }
                 }
+
                 Some((object_id, object))
             } else {
                 None


Test patch: