From 293a2e52b3fbd6dac2c89dfb35a546cdc027eb1b Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 13 May 2023 16:27:07 -0400 Subject: Disregard appearance state when irrelevant (fixes #949) If /AP is a dictionary of streams rather than a dictionary of dictionaries, disregard /AS, which is supposed to point to a subkey of one of the dictionaries. This fix prevents qpdf's annotation flattening from discarding some annotations when /AS is erroneously set. --- libqpdf/QPDFAnnotationObjectHelper.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'libqpdf') diff --git a/libqpdf/QPDFAnnotationObjectHelper.cc b/libqpdf/QPDFAnnotationObjectHelper.cc index c14d98f9..ff985ed0 100644 --- a/libqpdf/QPDFAnnotationObjectHelper.cc +++ b/libqpdf/QPDFAnnotationObjectHelper.cc @@ -54,7 +54,14 @@ QPDFAnnotationObjectHelper::getAppearanceStream( std::string desired_state = state.empty() ? getAppearanceState() : state; if (ap.isDictionary()) { QPDFObjectHandle ap_sub = ap.getKey(which); - if (ap_sub.isStream() && desired_state.empty()) { + if (ap_sub.isStream()) { + // According to the spec, Appearance State is supposed to + // refer to a subkey of the appearance stream when /AP is + // a dictionary, but files have been seen in the wild + // where Appearance State is `/N` and `/AP` is a stream. + // Therefore, if `which` points to a stream, disregard + // state and just use the stream. See qpdf issue #949 for + // details. QTC::TC("qpdf", "QPDFAnnotationObjectHelper AP stream"); return ap_sub; } -- cgit v1.2.3-54-g00ecf