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

Issue:
`add_xobject` does not follow resource references
When calling `add_xobject` on a document that uses a reference in the `XObject` resource field, it fails on a `Err(Type)`.

This is because it uses `Dictionary::get_mut` which does not attempt to dereference the resource field.


Discussion / hints:

Fix patch:
diff --git a/src/creator.rs b/src/creator.rs
index ac883a4..3987e00 100644
--- a/src/creator.rs
+++ b/src/creator.rs
@@ -95,7 +95,15 @@ impl Document {
             if !resources.has(b"XObject") {
                 resources.set("XObject", Dictionary::new());
             }
-            let xobjects = resources.get_mut(b"XObject").and_then(Object::as_dict_mut)?;
+            let mut xobjects = resources.get_mut(b"XObject")?;
+            if let Object::Reference(xobjects_ref_id) = xobjects {
+                let mut xobjects_id = xobjects_ref_id.clone();
+                while let Object::Reference(id) = self.get_object(xobjects_id)? {
+                    xobjects_id = *id;
+                }
+                xobjects = self.get_object_mut(xobjects_id)?;
+            }
+            let xobjects = Object::as_dict_mut(xobjects)?;
             xobjects.set(xobject_name, Object::Reference(xobject_id));
         }
         Ok(())
diff --git a/src/incremental_document.rs b/src/incremental_document.rs
index a4df77f..72cde5f 100644
--- a/src/incremental_document.rs
+++ b/src/incremental_document.rs
@@ -114,7 +114,15 @@ impl IncrementalDocument {
             if !resources.has(b"XObject") {
                 resources.set("XObject", Dictionary::new());
             }
-            let xobjects = resources.get_mut(b"XObject").and_then(Object::as_dict_mut)?;
+            let mut xobjects = resources.get_mut(b"XObject")?;
+            if let Object::Reference(xobjects_ref_id) = xobjects {
+                let mut xobjects_id = xobjects_ref_id.clone();
+                while let Object::Reference(id) = self.new_document.get_object(xobjects_id)? {
+                    xobjects_id = *id;
+                }
+                xobjects = self.new_document.get_object_mut(xobjects_id)?;
+            }
+            let xobjects = Object::as_dict_mut(xobjects)?;
             xobjects.set(xobject_name, Object::Reference(xobject_id));
         }
         Ok(())


Test patch: