[ 
https://issues.apache.org/jira/browse/PDFBOX-4997?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17217630#comment-17217630
 ] 

Michael Klink commented on PDFBOX-4997:
---------------------------------------

Probably one can fix this by replacing the {{if}} clause by
{code:java}
if (actual != null && objectKeys.containsKey(actual) 
    && object instanceof COSUpdateInfo && 
!((COSUpdateInfo)object).isNeedToBeUpdated() 
    && !(cosBase instanceof COSUpdateInfo && 
((COSUpdateInfo)cosBase).isNeedToBeUpdated()) )
{code}
This change assumes that an object not implementing {{COSUpdateInfo}} cannot 
have its internal state updated and, therefore, has an implicit 
{{isNeedToBeUpdated}} value of {{false}}.
----
As an aside, the issue is not limited to indirect objects containing a name 
object, other object classes not implementing {{COSUpdateInfo}} also are 
affected, in particular number and string classes.
----
As an aside, while debugging I found more code with a _suspicious smell_, in 
{{org.apache.pdfbox.pdfwriter.COSWriter}}; in {{prepareIncrement(PDDocument)}} 
two maps are filled, one mapping object references to objects and the other 
vice versa:
{code:java}
if (object != null && cosObjectKey!= null && !(object instanceof COSNumber))
{
    objectKeys.put(object, cosObjectKey);
    keyObject.put(cosObjectKey,object);
}
{code}
If some code assumes those two maps are inverse, that code may fail in case of 
objects that are {{COSName}} instances: {{COSName}} enforces a value object 
nature, you get the same instance for the same name. Thus, in case of multiple 
indirect objects containing only the same name the map {{objectKeys}} has fewer 
entries than {{keyObject}} and, therefore, is not the inverse.

Apparently a similar issue for {{COSNumber}} objects had already been 
recognized and was fixed by ignoring them.

Even worse, recently there have been attempts to make {{equals}} and 
{{hashcode}} consider dictionaries and arrays equal if they have equal entries. 
Thus, even for them the two maps above are not necessarily inverse to each 
other anymore.

> Incremental update adds certain objects not marked as needing update
> --------------------------------------------------------------------
>
>                 Key: PDFBOX-4997
>                 URL: https://issues.apache.org/jira/browse/PDFBOX-4997
>             Project: PDFBox
>          Issue Type: Bug
>          Components: Writing
>    Affects Versions: 2.0.21, 3.0.0 PDFBox
>            Reporter: Michael Klink
>            Priority: Major
>         Attachments: signed-000.pdf
>
>
> _This bug causes the eSignature DSS issue 
> [DSS-2260|https://ec.europa.eu/cefdigital/tracker/browse/DSS-2260]._
> If during an incremental update an indirect object containing only a name 
> object is checked for need of writing, it always is added to the objects to 
> write and, therefore, eventually written to the update section.
> For example in the attached document {{signed-000.pdf}} each page has a color 
> space resource entry *CS1* referring to the indirect object 54 containing 
> only the name object, *DeviceGray*. Whenever a page is marked as needing an 
> update, the bug causes object 54 also to be written even if it is not changed 
> at all.
> While this seems like a minor annoyance only, it has serious repercussions: 
> In multi-signature use cases this makes Adobe Reader claim previous 
> signatures to be broken whenever a new signature with visualization is added 
> using PDFBox, see also 
> [DSS-2260|https://ec.europa.eu/cefdigital/tracker/browse/DSS-2260].
> ----
> The cause of the bug is 
> {{org.apache.pdfbox.pdfwriter.COSWriter.addObjectToWrite(COSBase)}} where the 
> following {{if}} clause attempts to determine whether the inspected object 
> does not need to be written:
> {code:java}
> if (actual != null && objectKeys.containsKey(actual) 
>     && object instanceof COSUpdateInfo && 
> !((COSUpdateInfo)object).isNeedToBeUpdated() 
>     && cosBase instanceof COSUpdateInfo && 
> !((COSUpdateInfo)cosBase).isNeedToBeUpdated() )
> {
>     return;
> }
> {code}
> Here {{cosBase}} contains the content of the indirect object, in the case in 
> question the {{COSName}} *DeviceGray*. As {{COSName}} does not implement 
> {{COSUpdateInfo}}, the condition never evaluates to {{true}}, so the flow 
> never returns here but instead always continues with the following lines 
> where the object is added to the collection of objects to write.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to