2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 19:08:59 +00:00

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.
This commit is contained in:
Jay Berkenbilt 2023-05-13 16:27:07 -04:00
parent 3cfd6546f3
commit 293a2e52b3
8 changed files with 35 additions and 11 deletions

View File

@ -5,6 +5,15 @@
reserved object fits better in the QPDF API. The old call just reserved object fits better in the QPDF API. The old call just
delegates to the new one. delegates to the new one.
2023-05-13 Jay Berkenbilt <ejb@ql.org>
* When an annotation dictionary's appearance dictionary (`/AP`)
has a key that is a stream, disregard `/AS` (which is supposed to
point to a subkey). This enables qpdf to not ignore annotations
that have incorrect values for `/AS` when the appearance stream is
directly in the `/AP` dictionary instead of in a subkey. Fixes
#949.
2023-04-02 Jay Berkenbilt <ejb@ql.org> 2023-04-02 Jay Berkenbilt <ejb@ql.org>
* Allow QPDFJob's workflow to be split into a reading phase and a * Allow QPDFJob's workflow to be split into a reading phase and a
writing phase to allow the caller to operate on the QPDF object writing phase to allow the caller to operate on the QPDF object

View File

@ -54,7 +54,14 @@ QPDFAnnotationObjectHelper::getAppearanceStream(
std::string desired_state = state.empty() ? getAppearanceState() : state; std::string desired_state = state.empty() ? getAppearanceState() : state;
if (ap.isDictionary()) { if (ap.isDictionary()) {
QPDFObjectHandle ap_sub = ap.getKey(which); 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"); QTC::TC("qpdf", "QPDFAnnotationObjectHelper AP stream");
return ap_sub; return ap_sub;
} }

View File

@ -26,6 +26,14 @@ For a detailed list of changes, please see the file
- Add ``QPDF::newReserved`` as a better alternative to - Add ``QPDF::newReserved`` as a better alternative to
``QPDFObjectHandle::newReserved``. ``QPDFObjectHandle::newReserved``.
- Bug fixes
- Ignore an annotation's appearance state when the annotation only
has one appearance. This prevents qpdf's annotation flattening
logic from throwing away appearances of annotations whose
annotation state is set incorrectly, as has been seen in some
PDF files.
11.3.0: February 25, 2023 11.3.0: February 25, 2023
- CLI Enhancements - CLI Enhancements

View File

@ -178,7 +178,7 @@ Page: 11 0 R
Subtype: /Widget Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7] Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R Appearance stream (/N): 14 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R Annotation: 16 0 R
Field: 16 0 R Field: 16 0 R
Subtype: /Widget Subtype: /Widget
@ -249,5 +249,5 @@ Page: 35 0 R
Subtype: /Widget Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3] Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R Appearance stream (/N): 36 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 36 0 R
test 43 done test 43 done

View File

@ -166,7 +166,7 @@ Page: 11 0 R
Subtype: /Widget Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7] Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R Appearance stream (/N): 14 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R Annotation: 16 0 R
Field: 16 0 R Field: 16 0 R
Subtype: /Widget Subtype: /Widget
@ -237,5 +237,5 @@ Page: 35 0 R
Subtype: /Widget Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3] Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R Appearance stream (/N): 36 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 36 0 R
test 43 done test 43 done

View File

@ -166,7 +166,7 @@ Page: 11 0 R
Subtype: /Widget Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7] Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R Appearance stream (/N): 14 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R Annotation: 16 0 R
Field: 16 0 R Field: 16 0 R
Subtype: /Widget Subtype: /Widget
@ -237,5 +237,5 @@ Page: 35 0 R
Subtype: /Widget Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3] Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R Appearance stream (/N): 36 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 36 0 R
test 43 done test 43 done

View File

@ -171,7 +171,7 @@ Page: 11 0 R
Subtype: /Widget Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7] Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R Appearance stream (/N): 14 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R Annotation: 16 0 R
Field: 16 0 R Field: 16 0 R
Subtype: /Widget Subtype: /Widget
@ -242,5 +242,5 @@ Page: 35 0 R
Subtype: /Widget Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3] Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R Appearance stream (/N): 36 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 36 0 R
test 43 done test 43 done

View File

@ -166,7 +166,7 @@ Page: 11 0 R
Subtype: /Widget Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7] Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R Appearance stream (/N): 14 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R Annotation: 16 0 R
Field: 16 0 R Field: 16 0 R
Subtype: /Widget Subtype: /Widget
@ -237,5 +237,5 @@ Page: 35 0 R
Subtype: /Widget Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3] Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R Appearance stream (/N): 36 0 R
Appearance stream (/N, /3): null Appearance stream (/N, /3): 36 0 R
test 43 done test 43 done