diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-02-22 15:45:36 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-02-22 16:38:05 +0000 |
commit | f99993f33a5af4dad808cb2f8d3668cbd0a192e9 (patch) | |
tree | 345966e1a5ccd48ed866bfa282bd1107c6948b6f /source/pdf | |
parent | 5a390d0ce33a7dd9400675a236424db390a807c5 (diff) | |
download | mupdf-f99993f33a5af4dad808cb2f8d3668cbd0a192e9.tar.xz |
Fix Annot handling in mutool clean.
When cleaning a file, we discard any Annot entries that no longer
point to genuine pages. Or at least, we should have done, were it
not for the fact that we only handled the /A form of Annots, and
not the /Dest form of annots. Fixed here.
Diffstat (limited to 'source/pdf')
-rw-r--r-- | source/pdf/pdf-clean-file.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/source/pdf/pdf-clean-file.c b/source/pdf/pdf-clean-file.c index 69ca8a36..29efbd5c 100644 --- a/source/pdf/pdf-clean-file.c +++ b/source/pdf/pdf-clean-file.c @@ -36,6 +36,24 @@ static void retainpage(fz_context *ctx, pdf_document *doc, pdf_obj *parent, pdf_ pdf_array_push(ctx, kids, pageref); } +static int dest_is_valid_page(fz_context *ctx, pdf_document *doc, pdf_obj *obj) +{ + int i; + int num = pdf_to_num(ctx, obj); + int pagecount = pdf_count_pages(ctx, doc); + + if (num == 0) + return 0; + for (i = 0; i < pagecount; i++) + { + pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, i); + + if (pdf_to_num(ctx, pageref) == num) + return 1; + } + return 0; +} + static void retainpages(fz_context *ctx, globals *glo, int argc, char **argv) { pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests; @@ -170,22 +188,28 @@ static void retainpages(fz_context *ctx, globals *glo, int argc, char **argv) { pdf_obj *o = pdf_array_get(ctx, annots, j); pdf_obj *p; + int remove = 0; if (!pdf_name_eq(ctx, pdf_dict_get(ctx, o, PDF_NAME_Subtype), PDF_NAME_Link)) continue; p = pdf_dict_get(ctx, o, PDF_NAME_A); - if (!pdf_name_eq(ctx, pdf_dict_get(ctx, p, PDF_NAME_S), PDF_NAME_GoTo)) - continue; + if (pdf_name_eq(ctx, pdf_dict_get(ctx, p, PDF_NAME_S), PDF_NAME_GoTo) && + !string_in_names_list(ctx, pdf_dict_get(ctx, p, PDF_NAME_D), names_list)) + remove = 1; - if (string_in_names_list(ctx, pdf_dict_get(ctx, p, PDF_NAME_D), names_list)) - continue; + p = pdf_dict_get(ctx, 0, PDF_NAME_Dest); + if (!dest_is_valid_page(ctx, doc, pdf_array_get(ctx, p, 0))) + remove = 1; /* FIXME: Should probably look at Next too */ - /* Remove this annotation */ - pdf_array_delete(ctx, annots, j); - j--; + if (remove) + { + /* Remove this annotation */ + pdf_array_delete(ctx, annots, j); + j--; + } } } } |