Skip Menu |

This queue is for tickets about the Image-Info CPAN distribution.

Report information
The Basics
Id: 100847
Status: resolved
Priority: 0/
Queue: Image-Info

People
Owner: SREZIC [...] cpan.org
Requestors: tsibley [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.36
Fixed in: 1.37



Subject: Segfault when processing TIFF from reference but not from file
I ran into a segfault on a TIFF when calling image_info(). It only occurs when processing the image data from a scalar instead of a file on disk. Attached is a small script + decent hunk of data that reproduces it. I also captured a backtrace from gdb. This is a perlbrew'd perl 5.18.1 on OS X 10.8.5, though I also observed the segfault on Linux (same perl version). Thanks for the great module! Thomas
Subject: backtrace
Download backtrace
application/octet-stream 722b

Message body not shown because it is not plain text.

Subject: tiff-segfault.t

Message body is not shown because it is too large.

On 2014-12-10 18:48:19, TSIBLEY wrote: Show quoted text
> I ran into a segfault on a TIFF when calling image_info(). It only > occurs when processing the image data from a scalar instead of a file > on disk. Attached is a small script + decent hunk of data that > reproduces it. I also captured a backtrace from gdb. This is a > perlbrew'd perl 5.18.1 on OS X 10.8.5, though I also observed the > segfault on Linux (same perl version).
Confirmed. I can reproduce the problem with nearly every perl version. My first guess is that an enormous seek is done on the scalar filehandle. While this works on files (the file pointer just goes to the end of the file), it seems to allocate a huge memory block for a scalar variable. If you need a quick fix, then you can make the variable readonly (e.g. using the Readonly or Readonly::XS module); in this case the code will die() instead of segfaulting. I'll look for a better solution over weekend.
On Thu Dec 11 14:14:19 2014, SREZIC wrote: Show quoted text
> Confirmed. I can reproduce the problem with nearly every perl version. > > My first guess is that an enormous seek is done on the scalar > filehandle. While this works on files (the file pointer just goes to > the end of the file), it seems to allocate a huge memory block for a > scalar variable. If you need a quick fix, then you can make the > variable readonly (e.g. using the Readonly or Readonly::XS module); in > this case the code will die() instead of segfaulting. > > I'll look for a better solution over weekend.
Thanks for looking into this so quickly. It's good to know about the Readonly workaround!
On Thu Dec 11 14:14:19 2014, SREZIC wrote: Show quoted text
> If you need a quick fix, then you can make the > variable readonly (e.g. using the Readonly or Readonly::XS module); in > this case the code will die() instead of segfaulting.
On a closer inspection, this workaround doesn't really work. It does prevent the segfault on the tiff data I provided, but it also throws a "Modification of a read-only variable" exception on *any* image data I throw at image_info(). :/
On 2014-12-15 16:32:32, TSIBLEY wrote: Show quoted text
> On Thu Dec 11 14:14:19 2014, SREZIC wrote:
> > If you need a quick fix, then you can make the > > variable readonly (e.g. using the Readonly or Readonly::XS module); > > in > > this case the code will die() instead of segfaulting.
> > On a closer inspection, this workaround doesn't really work. It does > prevent the segfault on the tiff data I provided, but it also throws a > "Modification of a read-only variable" exception on *any* image data I > throw at image_info(). :/
Well, and using Internals::SvREADONLY() also does not help --- valid images work again, but it cannot trap the segfault... A workaround is to use either IO::Scalar or IO::String instead of perl's builtin IO scalar handling. And of both alternatives, IO::Scalar seems to be faster than IO::String. I made an experimental branch which you can find here: git clone https://github.com/eserte/image-info.git -b XXX-RT100847 Make sure that IO::Scalar is installed. With this branch, your test script does not segfault anymore, output is: Unrecognised fieldtype 64704, skipping from file: $VAR1 = { 'error' => 'short read (2/0) at pos 2348827295 at /home/e/eserte/src/CPAN.local/Image-Info/blib/lib/Image/Info/TIFF.pm line 42. ' }; Unrecognised fieldtype 64704, skipping from ref: $VAR1 = { 'error' => 'short read (2/0) at pos 1503418 at /home/e/eserte/src/CPAN.local/Image-Info/blib/lib/Image/Info/TIFF.pm line 42. ' }; I still have to think about a real solution. Maybe all read(), seek() etc. operations need to be protected in the scalar ref case, i.e. there has to be a check that the string buffer is not exceeded. Regards, Slaven
It seems like always passing image_info() a filehandle (whether "real" or IO::Scalar) is a reasonable workaround to the segfault. Show quoted text
> I still have to think about a real solution. Maybe all read(), seek() > etc. operations need to be protected in the scalar ref case, i.e. > there has to be a check that the string buffer is not exceeded.
This sounds reasonable. Do you know the underlying reason why it's trying to seek/read off the end of the data?
On 2014-12-19 12:27:57, TSIBLEY wrote: Show quoted text
> It seems like always passing image_info() a filehandle (whether "real" > or IO::Scalar) is a reasonable workaround to the segfault.
1.36_51 is out which uses IO::Scalar for image data from a variable, unless it's perl 5.21.7 or newer which does not have the seek/read bug anymore. Show quoted text
> > I still have to think about a real solution. Maybe all read(), seek() > > etc. operations need to be protected in the scalar ref case, i.e. > > there has to be a check that the string buffer is not exceeded.
> > This sounds reasonable. Do you know the underlying reason why it's > trying to seek/read off the end of the data?
It looks like an invalid entry in the tiff file. exiftool also shows the same kind of warning. Image::Info used to issue a warning and then to go on with processing, hitting unpredictable data which caused the huge seeks. Probably a better workaround is to stop processing immediately on such an invalid entry. I made another attempt here: git clone https://github.com/eserte/image-info.git -b XXX-RT100847 This should handle your test image and just add a "Warn" entry in the info hash. Regards, Slaven
On Tue Dec 23 12:05:19 2014, SREZIC wrote: Show quoted text
> git clone https://github.com/eserte/image-info.git -b XXX-RT100847 > > This should handle your test image and just add a "Warn" entry in the > info hash.
This is great and seems to work well! Will you let me know when/if it's released? I'd like to dep on it for an internal app.
On 2014-12-29 17:12:01, TSIBLEY wrote: Show quoted text
> On Tue Dec 23 12:05:19 2014, SREZIC wrote:
> > git clone https://github.com/eserte/image-info.git -b XXX-RT100847 > > > > This should handle your test image and just add a "Warn" entry in the > > info hash.
> > This is great and seems to work well! Will you let me know when/if > it's released? I'd like to dep on it for an internal app.
I just released Image-Info-1.36_52.tar.gz If CPAN Testers results look good, then there will be a stable release in a few days. Regards, Slaven
On 2014-12-29 17:24:21, SREZIC wrote: Show quoted text
> On 2014-12-29 17:12:01, TSIBLEY wrote:
> > On Tue Dec 23 12:05:19 2014, SREZIC wrote:
> > > git clone https://github.com/eserte/image-info.git -b XXX-RT100847 > > > > > > This should handle your test image and just add a "Warn" entry in > > > the > > > info hash.
> > > > This is great and seems to work well! Will you let me know when/if > > it's released? I'd like to dep on it for an internal app.
> > I just released Image-Info-1.36_52.tar.gz > If CPAN Testers results look good, then there will be a stable release > in a few days.
1.37 is out.
Thanks!