[
https://issues.apache.org/jira/browse/PDFBOX-6270?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jakob Heher updated PDFBOX-6270:
--------------------------------
Description:
Calling `page.getAnnotations()` marks various already-existing annotations as
dirty. This causes them to be re-emitted in a subsequent incremental update
save, even though no mutations were performed.
In particular, `addSignature` triggers this bug (it uses `getAnnotations`),
causing pre-existing signature annotations to be re-emitted byte-by byte.
The cause is the `COSDictionary`-taking constructors of the annotation wrappers
unconditionally calling `setName` -> `setItem` to set the correct type/subtype
values. `setItem` then unconditionally marks the dictionary as dirty. Cf.
[PDAnnotationWidget.java|https://github.com/apache/pdfbox/blob/3.0.6/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAnnotationWidget.java#L56].
These constructors are called from getAnnotations -> createAnnotation.
A minimal reproducer is attached. A sample PDF file exhibiting this bug is also
attached.
A suggested fix would be either to make the `setItem` invocations conditional,
or to skip them entirely (since the comment on this constructor suggests that
it assumes that the passed dictionary is already valid). This likely applies to
more than just PDAnnotationWidget.
*AI disclaimer:* I used ChatGPT to perform the cause analysis after noticing
the erroneous behavior in production, and to generate an initial reproducer.
However, I have manually refined the reproducer, and have manually verified the
erroneous behavior in the source tree. I have written this bug report by hand.
I am confident that this is a real bug.
was:
Calling `page.getAnnotations()` marks various already-existing annotations as
dirty. This causes them to be re-emitted in a subsequent incremental update
save, even though no mutations were performed.
In particular, `addSignature` triggers this bug (it uses `getAnnotations`),
causing pre-existing signature annotations to be re-emitted byte-by byte.
The cause is the `COSDictionary` constructors of the annotation wrappers
unconditionally calling `setName` -> `setItem` to set the correct type/subtype
values. `setItem` then unconditionally marks the dictionary as dirty. Cf.
[PDAnnotationWidget.java|https://github.com/apache/pdfbox/blob/3.0.6/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAnnotationWidget.java#L56].
These constructors are called from getAnnotations -> createAnnotation.
A minimal reproducer is attached. A sample PDF file exhibiting this bug is also
attached.
A suggested fix would be either to make the `setItem` invocations conditional,
or to skip them entirely (since the comment on this constructor suggests that
it assumes that the passed dictionary is already valid). This likely applies to
more than just PDAnnotationWidget.
*AI disclaimer:* I used ChatGPT to perform the cause analysis after noticing
the erroneous behavior in production, and to generate an initial reproducer.
However, I have manually refined the reproducer, and have manually verified the
erroneous behavior in the source tree. I have written this bug report by hand.
I am confident that this is a real bug.
> `getAnnotations` marks annotations as dirty
> -------------------------------------------
>
> Key: PDFBOX-6270
> URL: https://issues.apache.org/jira/browse/PDFBOX-6270
> Project: PDFBox
> Issue Type: Bug
> Affects Versions: 3.0.6 PDFBox
> Reporter: Jakob Heher
> Priority: Major
> Attachments: Repro1WidgetConstructor.java, double-signed.pdf
>
>
> Calling `page.getAnnotations()` marks various already-existing annotations as
> dirty. This causes them to be re-emitted in a subsequent incremental update
> save, even though no mutations were performed.
> In particular, `addSignature` triggers this bug (it uses `getAnnotations`),
> causing pre-existing signature annotations to be re-emitted byte-by byte.
> The cause is the `COSDictionary`-taking constructors of the annotation
> wrappers unconditionally calling `setName` -> `setItem` to set the correct
> type/subtype values. `setItem` then unconditionally marks the dictionary as
> dirty. Cf.
> [PDAnnotationWidget.java|https://github.com/apache/pdfbox/blob/3.0.6/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAnnotationWidget.java#L56].
> These constructors are called from getAnnotations -> createAnnotation.
> A minimal reproducer is attached. A sample PDF file exhibiting this bug is
> also attached.
> A suggested fix would be either to make the `setItem` invocations
> conditional, or to skip them entirely (since the comment on this constructor
> suggests that it assumes that the passed dictionary is already valid). This
> likely applies to more than just PDAnnotationWidget.
> *AI disclaimer:* I used ChatGPT to perform the cause analysis after noticing
> the erroneous behavior in production, and to generate an initial reproducer.
> However, I have manually refined the reproducer, and have manually verified
> the erroneous behavior in the source tree. I have written this bug report by
> hand. I am confident that this is a real bug.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]