aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--libqpdf/QPDFAnnotationObjectHelper.cc9
-rw-r--r--manual/release-notes.rst8
-rw-r--r--qpdf/qtest/qpdf/form-form-bad-fields-array.out4
-rw-r--r--qpdf/qtest/qpdf/form-form-document-defaults.out4
-rw-r--r--qpdf/qtest/qpdf/form-form-empty-from-odt.out4
-rw-r--r--qpdf/qtest/qpdf/form-form-errors.out4
-rw-r--r--qpdf/qtest/qpdf/form-form-mod1.out4
8 files changed, 35 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index ea4a9c5d..00864384 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,15 @@
reserved object fits better in the QPDF API. The old call just
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>
* 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
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;
}
diff --git a/manual/release-notes.rst b/manual/release-notes.rst
index c0d2fcca..7b6a8876 100644
--- a/manual/release-notes.rst
+++ b/manual/release-notes.rst
@@ -26,6 +26,14 @@ For a detailed list of changes, please see the file
- Add ``QPDF::newReserved`` as a better alternative to
``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
- CLI Enhancements
diff --git a/qpdf/qtest/qpdf/form-form-bad-fields-array.out b/qpdf/qtest/qpdf/form-form-bad-fields-array.out
index 1347c8de..0a3500c0 100644
--- a/qpdf/qtest/qpdf/form-form-bad-fields-array.out
+++ b/qpdf/qtest/qpdf/form-form-bad-fields-array.out
@@ -178,7 +178,7 @@ Page: 11 0 R
Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R
Field: 16 0 R
Subtype: /Widget
@@ -249,5 +249,5 @@ Page: 35 0 R
Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 36 0 R
test 43 done
diff --git a/qpdf/qtest/qpdf/form-form-document-defaults.out b/qpdf/qtest/qpdf/form-form-document-defaults.out
index 555e7898..31622cf7 100644
--- a/qpdf/qtest/qpdf/form-form-document-defaults.out
+++ b/qpdf/qtest/qpdf/form-form-document-defaults.out
@@ -166,7 +166,7 @@ Page: 11 0 R
Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R
Field: 16 0 R
Subtype: /Widget
@@ -237,5 +237,5 @@ Page: 35 0 R
Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 36 0 R
test 43 done
diff --git a/qpdf/qtest/qpdf/form-form-empty-from-odt.out b/qpdf/qtest/qpdf/form-form-empty-from-odt.out
index 83597c8d..c9b47a99 100644
--- a/qpdf/qtest/qpdf/form-form-empty-from-odt.out
+++ b/qpdf/qtest/qpdf/form-form-empty-from-odt.out
@@ -166,7 +166,7 @@ Page: 11 0 R
Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R
Field: 16 0 R
Subtype: /Widget
@@ -237,5 +237,5 @@ Page: 35 0 R
Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 36 0 R
test 43 done
diff --git a/qpdf/qtest/qpdf/form-form-errors.out b/qpdf/qtest/qpdf/form-form-errors.out
index 130e3536..0225f068 100644
--- a/qpdf/qtest/qpdf/form-form-errors.out
+++ b/qpdf/qtest/qpdf/form-form-errors.out
@@ -171,7 +171,7 @@ Page: 11 0 R
Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R
Field: 16 0 R
Subtype: /Widget
@@ -242,5 +242,5 @@ Page: 35 0 R
Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 36 0 R
test 43 done
diff --git a/qpdf/qtest/qpdf/form-form-mod1.out b/qpdf/qtest/qpdf/form-form-mod1.out
index 8e8f1a94..1c7fea76 100644
--- a/qpdf/qtest/qpdf/form-form-mod1.out
+++ b/qpdf/qtest/qpdf/form-form-mod1.out
@@ -166,7 +166,7 @@ Page: 11 0 R
Subtype: /Widget
Rect: [123.4, 692.1, 260.9, 706.7]
Appearance stream (/N): 14 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 14 0 R
Annotation: 16 0 R
Field: 16 0 R
Subtype: /Widget
@@ -237,5 +237,5 @@ Page: 35 0 R
Subtype: /Widget
Rect: [113.6, 378.5, 351.3, 396.3]
Appearance stream (/N): 36 0 R
- Appearance stream (/N, /3): null
+ Appearance stream (/N, /3): 36 0 R
test 43 done