Post without Account — your post will be reviewed, and if appropriate, posted under Anonymous. You can also use this link to report any problems registering.

RT 118352 - Crash when adding to an annotations array stored as an indirect obje

  • 2 Replies
  • 1128 Views
*

Offline Phil

  • Global Moderator
  • Sr. Member
  • *****
  • 387
    • View Profile
Wed Oct 12 15:42:53 2016 jv [...] cpan.org - Ticket created
Subject:    Unexplainable crash in some PDF documents

At least it is unexplainable for me...

Test program attached.

When I uncomment the offending line 322 in PDF/API2/Page.pm it seems to work but I cannot oversee the consequences of this change.

Code: [Select]
use strict;
use warnings;

use PDF::API2 2.029; # or 2.028, ...

my $pdf = PDF::API2->open("test.pdf");
my $page = $pdf->openpage(1);

# This line will crash with
# Can't locate object method "update"
# via package "PDF::API2::Basic::PDF::Array"
# at /usr/share/perl5/vendor_perl/PDF/API2/Page.pm line 322.
my $ann = $page->annotation;
« Last Edit: October 22, 2016, 12:14:35 PM by Phil »

*

Offline Phil

  • Global Moderator
  • Sr. Member
  • *****
  • 387
    • View Profile
Fri Oct 21 16:21:57 2016 steve [...] deefs.net - Correspondence added

Initial troubleshooting:

- Your test.pdf has an empty Annots (annotations) array on each page.

- $page->annotation() creates a new annotation object, adds it to the page, and returns it.

- Unrelated: $page->annotation() doesn't take any arguments -- the code declares three, but never uses them.  It seems to be a copy-paste error from sub resource, which immediately follows it.  I've just removed them.

- If an annotations array already exists in the Page object [edit: and it's an indirect object], $page->annotation() tries to call update() on it.  However, Array.pm doesn't have an update() function, and it doesn't look like it ever did.

- There are three cases of "sub update" in the codebase, and the only one that makes sense in this case is the one in Page.pm, which "marks a page to be updated".  It does this by calling File.pm's out_obj with itself as the argument.

- out_obj notes that the object needs to be output when the PDF is generated (written to disk, stringified, etc.).

- Therefore, it looks like the correct code for that line is...

- $self->{'Annots'}->update();
+ $self->{' apipdf'}->out_obj($self->{'Annots'});

... because the purpose of the surrounding code seems to be "if an annotations array already exists, mark the array as having changed since we're about to add to it; otherwise, mark the page as having changed since we just added the annotations array to it."

- However, that exact line already appears just after the new annotation is created.

So, it does appear that just removing the line altogether will fix the crash without any consequences.

While writing a test for this ticket, I also discovered that the crash only happens if the array is an indirect object -- if an array already exists and it's inline, there isn't a problem.

This will be fixed in the next release, and working code is now in the repository.
#
Fri Oct 21 16:21:57 2016 The RT System itself - Status changed from 'new' to 'open'
#
Fri Oct 21 16:22:03 2016 steve [...] deefs.net - Status changed from 'open' to 'patched'
#
Fri Oct 21 16:22:39 2016 steve [...] deefs.net - Subject changed from 'Unexplainable crash in some PDF documents' to 'Crash when adding to an annotations array stored as an indirect object'
#
Fri Oct 21 16:22:39 2016 steve [...] deefs.net - Broken in 2.029 deleted
« Last Edit: October 22, 2016, 12:15:14 PM by Phil »

*

Offline Phil

  • Global Moderator
  • Sr. Member
  • *****
  • 387
    • View Profile
Mon Jan 30 11:49:17 2017 steve [...] deefs.net - Status changed from 'patched' to 'resolved'
#
Mon Jan 30 11:49:24 2017 steve [...] deefs.net - Fixed in 2.031 added