From 9b56c6c88522b7ff6c592c93ff8ec33ee158747a Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Tue, 15 Nov 2011 18:38:44 +0000 Subject: Fix bug 692627; pdfclean -ggg of encrypted files fails. Encryption bakes the object numbers into the strings/streams. This means that our renumbering technique falls down; when we move an object to its new position, then come to read it, we find that it decrypts badly. The fix here is (as suggested by Zeniko) to avoid renumbering when encryption is in use. --- apps/pdfclean.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'apps/pdfclean.c') diff --git a/apps/pdfclean.c b/apps/pdfclean.c index dd85b1a4..f46c4b76 100644 --- a/apps/pdfclean.c +++ b/apps/pdfclean.c @@ -754,7 +754,10 @@ int main(int argc, char **argv) compactxref(); /* Make renumbering affect all indirect references and update xref */ - if (dogarbage >= 2) + /* Do not renumber objects if encryption is in use, as the object + * numbers are baked into the streams/strings, and we can't currently + * cope with moving them. See bug 692627. */ + if (dogarbage >= 2 && xref->crypt == NULL) renumberobjs(); writepdf(); -- cgit v1.2.3 From 2be04fd23c9650820fa5abd1196647ccf1b73921 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Tue, 15 Nov 2011 19:05:59 +0000 Subject: Bug 692487: Make pdfclean keep internal links where possible. Take on a (cosmetically tweaked) version of Zenikos patch to allow pdfclean to keep link destinations that are in preserved pages. --- apps/pdfclean.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'apps/pdfclean.c') diff --git a/apps/pdfclean.c b/apps/pdfclean.c index f46c4b76..b436a9cb 100644 --- a/apps/pdfclean.c +++ b/apps/pdfclean.c @@ -278,16 +278,18 @@ static void renumberobjs(void) static void retainpages(int argc, char **argv) { fz_error error; - fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent; + fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests; /* Load the old page tree */ error = pdf_load_page_tree(xref); if (error) die(fz_rethrow(error, "cannot load page tree")); - /* Keep only pages/type entry to avoid references to unretained pages */ + /* Keep only pages/type and (reduced) dest entries to avoid + * references to unretained pages */ oldroot = fz_dict_gets(xref->trailer, "Root"); pages = fz_dict_gets(oldroot, "Pages"); + olddests = pdf_load_name_tree(xref, "Dests"); root = fz_new_dict(2); fz_dict_puts(root, "Type", fz_dict_gets(oldroot, "Type")); @@ -359,6 +361,41 @@ static void retainpages(int argc, char **argv) fz_drop_obj(countobj); fz_dict_puts(pages, "Kids", kids); fz_drop_obj(kids); + + /* Also preserve the (partial) Dests name tree */ + if (olddests) + { + int i; + fz_obj *names = fz_new_dict(1); + fz_obj *dests = fz_new_dict(1); + fz_obj *names_list = fz_new_array(32); + + for (i = 0; i < fz_dict_len(olddests); i++) + { + fz_obj *key = fz_dict_get_key(olddests, i); + fz_obj *val = fz_dict_get_val(olddests, i); + fz_obj *key_str = fz_new_string(fz_to_name(key), strlen(fz_to_name(key))); + fz_obj *dest = fz_dict_gets(val, "D"); + + dest = fz_array_get(dest ? dest : val, 0); + if (fz_array_contains(fz_dict_gets(pages, "Kids"), dest)) + { + fz_array_push(names_list, key_str); + fz_array_push(names_list, val); + } + fz_drop_obj(key_str); + } + + root = fz_dict_gets(xref->trailer, "Root"); + fz_dict_puts(dests, "Names", names_list); + fz_dict_puts(names, "Dests", dests); + fz_dict_puts(root, "Names", names); + + fz_drop_obj(names); + fz_drop_obj(dests); + fz_drop_obj(names_list); + fz_drop_obj(olddests); + } } /* -- cgit v1.2.3