Bug 704045: Purge local_xref keyed objects from store on local_xref destruction.
authorRobin Watts <[email protected]>
Wed, 21 Jul 2021 15:46:16 +0000 (16:46 +0100)
committerRobin Watts <[email protected]>
Wed, 21 Jul 2021 17:34:11 +0000 (18:34 +0100)
This avoids us being left with fonts in the store keyed on
objects that no longer exist.

Part of this commit is that we make pdf_is_local_object respond
whether the xref is in force or not. The current place it is
called from always has the local xref in force, so this doesn't
alter any behaviour.

include/mupdf/pdf/resource.h
source/pdf/pdf-appearance.c
source/pdf/pdf-object.c
source/pdf/pdf-store.c
source/pdf/pdf-xref.c

index 7f176a9a4cf8c40a18211d4d196cd3b9ef0caac3..bddcf04c77da6dc9535214690a5759bf2efc4502 100644 (file)
@@ -5,6 +5,7 @@ void pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, size_t itemsize);
 void *pdf_find_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key);
 void pdf_remove_item(fz_context *ctx, fz_store_drop_fn *drop, pdf_obj *key);
 void pdf_empty_store(fz_context *ctx, pdf_document *doc);
+void pdf_purge_locals_from_store(fz_context *ctx, pdf_document *doc);
 
 /*
  * Structures used for managing resource locations and avoiding multiple
index 954a845554d39bef4d6fc524da5481194b5b79dd..651a9503eccdbad1ce82add7329ea259939fb4a0 100644 (file)
@@ -2613,6 +2613,7 @@ void pdf_annot_pop_and_discard_local_xref(fz_context *ctx, pdf_annot *annot)
        if (doc->local_xref)
                fz_write_printf(ctx, fz_stddbg(ctx), "pop and discard local_xref for annot\n");
 #endif
+       pdf_purge_locals_from_store(ctx, doc);
        --doc->local_xref_nesting;
        assert(doc->local_xref_nesting == 0);
        pdf_purge_local_font_resources(ctx, doc);
index e714d11c561028c8c59bc4610b2a1319021822b2..2aef19cebe4c6d917527ebd70e331b8f1369ba4c 100644 (file)
@@ -973,6 +973,7 @@ swap_fragments(fz_context *ctx, pdf_document *doc, pdf_journal_entry *entry)
                fz_throw(ctx, FZ_ERROR_GENERIC, "Can't undo/redo within an operation");
 
        pdf_purge_local_font_resources(ctx, doc);
+       pdf_purge_locals_from_store(ctx, doc);
        pdf_drop_local_xref(ctx, doc->local_xref);
        doc->local_xref = NULL;
 
@@ -1394,6 +1395,7 @@ static void prepare_object_for_alteration(fz_context *ctx, pdf_obj *obj, pdf_obj
                         * to edit the document. This invalidates it, so
                         * throw it away. */
                        pdf_purge_local_font_resources(ctx, doc);
+                       pdf_purge_locals_from_store(ctx, doc);
                        pdf_drop_local_xref(ctx, doc->local_xref);
                        doc->local_xref = NULL;
                }
index b43a6ee03ab3411cc70ed97e90cac6376cbba768..7a00f8c3e4564aab744ee3cd2249d2b3ad9098f4 100644 (file)
@@ -99,3 +99,18 @@ pdf_empty_store(fz_context *ctx, pdf_document *doc)
 {
        fz_filter_store(ctx, pdf_filter_store, doc, &pdf_obj_store_type);
 }
+
+static int
+pdf_filter_locals(fz_context *ctx, void *doc_, void *key)
+{
+       pdf_document *doc = (pdf_document *)doc_;
+       pdf_obj *obj = (pdf_obj *)key;
+       pdf_document *key_doc = pdf_get_bound_document(ctx, obj);
+
+       return (doc == key_doc && pdf_is_local_object(ctx, doc, obj));
+}
+
+void pdf_purge_locals_from_store(fz_context *ctx, pdf_document *doc)
+{
+       fz_filter_store(ctx, pdf_filter_locals, doc, &pdf_obj_store_type);
+}
index 29a773e9c6185d9210404d68782f92e6ae464ca0..99dc707a1cba432c6658ad7b4065f27922fd1106 100644 (file)
@@ -2354,7 +2354,7 @@ pdf_is_local_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
        if (!pdf_is_indirect(ctx, obj))
                return 0;
 
-       if (xref == NULL || doc->local_xref_nesting == 0)
+       if (xref == NULL)
                return 0; /* no local xref present */
 
        num = pdf_to_num(ctx, obj);