Bug 706485: Fix mutool clean to cope with XRef missing from ObjStm.
authorRobin Watts <[email protected]>
Fri, 31 Mar 2023 17:21:27 +0000 (18:21 +0100)
committerRobin Watts <[email protected]>
Mon, 3 Apr 2023 13:55:05 +0000 (14:55 +0100)
If we try to load an obj from an objstm and it's not there,
trigger a repair. If the obj is still not found after the
repair, we'll still throw.

Cope with ignoring such errors in preloadobjstms.

source/pdf/pdf-write.c
source/pdf/pdf-xref.c

index efc5d4a8f586cfbb7d98b5838651285256656ca2..778b5ace5716a2511bd095121e7f3ca34289c1d3 100644 (file)
@@ -1549,13 +1549,31 @@ static void preloadobjstms(fz_context *ctx, pdf_document *doc)
        pdf_obj *obj;
        int num;
 
+       /* If we have attempted a repair, then everything will have been
+        * loaded already. */
+       if (doc->repair_attempted)
+               return;
+
+       fz_var(num);
+
        /* xref_len may change due to repair, so check it every iteration */
        for (num = 0; num < pdf_xref_len(ctx, doc); num++)
        {
-               if (pdf_get_xref_entry_no_null(ctx, doc, num)->type == 'o')
+               fz_try(ctx)
+               {
+                       for (; num < pdf_xref_len(ctx, doc); num++)
+                       {
+                               if (pdf_get_xref_entry_no_null(ctx, doc, num)->type == 'o')
+                               {
+                                       obj = pdf_load_object(ctx, doc, num);
+                                       pdf_drop_obj(ctx, obj);
+                               }
+                       }
+               }
+               fz_catch(ctx)
                {
-                       obj = pdf_load_object(ctx, doc, num);
-                       pdf_drop_obj(ctx, obj);
+                       /* Ignore the error, so we can carry on trying to load. */
+                       fz_warn(ctx, fz_caught_message(ctx));
                }
        }
 }
index 29c8b5d39e2b5c1cae7fc76d65730092934a94eb..4270404205ab3dd517f95e0bef2c4d33ac742e4e 100644 (file)
@@ -2405,6 +2405,7 @@ object_updated:
 
                if (try_repair)
                {
+perform_repair:
                        fz_try(ctx)
                        {
                                pdf_repair_xref(ctx, doc);
@@ -2442,7 +2443,13 @@ object_updated:
                        if (x == NULL)
                                fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load object stream containing object (%d 0 R)", num);
                        if (!x->obj)
-                               fz_throw(ctx, FZ_ERROR_GENERIC, "object (%d 0 R) was not found in its object stream", num);
+                       {
+                               x->type = 'f';
+                               orig_x->type = 'f';
+                               if (doc->repair_attempted)
+                                       fz_throw(ctx, FZ_ERROR_GENERIC, "object (%d 0 R) was not found in its object stream", num);
+                               goto perform_repair;
+                       }
                }
        }
        else if (doc->hint_obj_offsets && read_hinted_object(ctx, doc, num))