summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-clean-file.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-02-22 15:45:36 +0000
committerRobin Watts <robin.watts@artifex.com>2016-02-22 16:38:05 +0000
commitf99993f33a5af4dad808cb2f8d3668cbd0a192e9 (patch)
tree345966e1a5ccd48ed866bfa282bd1107c6948b6f /source/pdf/pdf-clean-file.c
parent5a390d0ce33a7dd9400675a236424db390a807c5 (diff)
downloadmupdf-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/pdf-clean-file.c')
-rw-r--r--source/pdf/pdf-clean-file.c38
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--;
+ }
}
}
}