[gs-commits] mupdf 1.16.1.78 Separate flag for freezing updates to PDF
[email protected] (Sebastian Rasmussen) Fri, 4 Oct 2019 10:28:15 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 6d7d90f61a0f2110dbe45ff9f360873b28bb7f76 Author: Pete McLaughlin <[email protected]> Date: Sat Sep 14 11:53:41 2019 +0100 Separate flag for freezing updates to PDF document into two. The flag freeze_updates conflated two states: * A flag indicating that repaired files can't be saved incrementally. * A flag indicating that changes to PDF objects while the document is being saved (e.g. when the signature dictionary has /Contents and /ByteRange updated) should not cause an incremental xref section from being created. To see why consider that pdf_save_document() calls prepare_for_save() which used to set the flag freeze_updates, later cleared at end of do_pdf_save_document(). If the document was saved incrementally but had no incremental xref sections, then an early return prevented freeze_updates from being cleared. An easy fix would have been to clear freeze_updates at the early return too. The same freeze_updates flag was also set by pdf_repair_xref(), because saving a repaired file incrementally will create a broken file. With the easy fix, a repaired document without incremental xref sections being saved incrementally could then have its freeze_updates flag incorrectly cleared. This commit splits freeze_updates into the existing repair_attempted flag and save_in_progress. This allows for clearing the latter flag both at the end of do_pdf_save_document() and at the early return in without affecting the flag set by pdf_repair_xref(). (+1 squashed commit) Squashed commits: [ff966f966] Ensure that PDFDocument freeze_updates is always reset on save We set the freeze_updates field to 1 in prepare_for_save() when saving a document, and we reset it to zero when we complete the save. However, we can fail to reset the field in do_pdf_save_document() in the case where we have incremental save enabled, but have no incremental sections in the document. We do a simple return in this instance. Add code to reset the freeze_updates field in this case. diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h index 55bd877..6c57da8 100644 --- a/include/mupdf/pdf/document.h +++ b/include/mupdf/pdf/document.h @@ -219,7 +219,7 @@ struct pdf_document_s pdf_xref *xref_sections; pdf_xref *saved_xref_sections; int *xref_index; - int freeze_updates; + int save_in_progress; int has_xref_streams; int has_old_style_xrefs; diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c index 7a541a8..9a49388 100644 --- a/source/pdf/pdf-object.c +++ b/source/pdf/pdf-object.c @@ -681,10 +681,10 @@ static void prepare_object_for_alteration(fz_context *ctx, pdf_obj *obj, pdf_obj } /* - parent_num = 0 while an object is being parsed from the file. + parent_num == 0 while an object is being parsed from the file. No further action is necessary. */ - if (parent == 0 || doc->freeze_updates) + if (parent == 0 || doc->save_in_progress || doc->repair_attempted) return; /* diff --git a/source/pdf/pdf-repair.c b/source/pdf/pdf-repair.c index 2433a0c..fc49d88 100644 --- a/source/pdf/pdf-repair.c +++ b/source/pdf/pdf-repair.c @@ -331,7 +331,6 @@ pdf_repair_xref(fz_context *ctx, pdf_document *doc) doc->repair_attempted = 1; doc->dirty = 1; - doc->freeze_updates = 1; /* Can't support incremental update after repair */ pdf_forget_xref(ctx, doc); diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c index 2345a37..94d8467 100644 --- a/source/pdf/pdf-write.c +++ b/source/pdf/pdf-write.c @@ -3106,12 +3106,19 @@ int pdf_can_be_saved_incrementally(fz_context *ctx, pdf_document *doc) static void prepare_for_save(fz_context *ctx, pdf_document *doc, pdf_write_options *in_opts) { - doc->freeze_updates = 1; - /* Rewrite (and possibly sanitize) the operator streams */ if (in_opts->do_clean || in_opts->do_sanitize) clean_content_streams(ctx, doc, in_opts->do_sanitize, in_opts->do_ascii); + /* When saving a PDF with signatures the file will + first be written once, then the file will have its + digests and byte ranges calculated and and then the + signature dictionary containing them will be updated + both in memory and in the saved file. By setting this + flag we avoid a new xref section from being created when + the signature dictionary is updated. */ + doc->save_in_progress = 1; + presize_unsaved_signature_byteranges(ctx, doc); } @@ -3217,7 +3224,11 @@ do_pdf_save_document(fz_context *ctx, pdf_document *doc, pdf_write_state *opts, { /* If no changes, nothing to write */ if (doc->num_incremental_sections == 0) + { + doc->save_in_progress = 0; return; + } + if (opts->out) { fz_seek_output(ctx, opts->out, 0, SEEK_END); @@ -3411,7 +3422,7 @@ do_pdf_save_document(fz_context *ctx, pdf_document *doc, pdf_write_state *opts, finalise_write_state(ctx, opts); if (opts->crypt != doc->crypt) pdf_drop_crypt(ctx, opts->crypt); - doc->freeze_updates = 0; + doc->save_in_progress = 0; } fz_catch(ctx) { @@ -3524,7 +3535,10 @@ void pdf_save_document(fz_context *ctx, pdf_document *doc, const char *filename, { /* If no changes, nothing to write */ if (doc->num_incremental_sections == 0) + { + doc->save_in_progress = 0; return; + } opts.out = fz_new_output_with_path(ctx, filename, 1); } else http://git.ghostscript.com/?p=mupdf.git;a=commit;h=6d7d90f61a0f2110dbe45ff9f360873b28bb7f76 -- MuPDF library Artifex Software, Inc.