Exiv2 crashes when writing to some multi-frame tiff files
Added by Mikayel Egibyan over 5 years ago
Hi,
I have seen discussions that are 2, 5 years old on this topic, but the error is still present. For 5 frame multi frame tiff, when trying to write the Software tag I get:
terminate called after throwing an instance of 'Exiv2::BasicError<char>'
what(): Invalid ifdId 103
Is this still a known issue, or there is a workaround?
Thanks,
Mikayel
p.s. try{}catch(){}
doesn't help
Replies (9)
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Robin Mills over 5 years ago
I'm not aware of this issue. Perhaps you can attach a test file so that I can reproduce this.
Last year, I investigated multi-page tiffs and discovered that the libtiff utilities tiffsplit and tiffcp can be used to split a multi-page tiff into different files which can be handled by exiv2. The files can be reassembled into a multi-page tiff using tiffcp. http://dev.exiv2.org/issues/1124#note-4
Exiv2 doesn't currently support multi-page tiff files. One of the goals for v0.27 is to work on multi-page tiffs. http://dev.exiv2.org/news/3
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Mikayel Egibyan over 5 years ago
Please find the test file attached.
Though Exiv2 doesn't support multi-frame tiff, this should not be the case for the crash, since For <= 4 frames Exiv2 is able to write metadata to the file (to the first frame). The attached file has 5 frames.
Thank you,
Mikayel
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Robin Mills over 5 years ago
What's the command-line that you are using? Here's what I have tried:
508 rmills@rmillsmbp:~ $ exiv2 -pa --grep FNumber ~/Downloads/tst.tiff Warning: Directory Image3 has an unexpected next pointer; ignored. 510 rmills@rmillsmbp:~ $ exiv2 -M'set Exif.Photo.FNumber F5' ~/Downloads/tst.tiff Warning: Directory Image3 has an unexpected next pointer; ignored. Warning: Directory Image3 has an unexpected next pointer; ignored. 511 rmills@rmillsmbp:~ $ exiv2 -pa --grep FNumber ~/Downloads/tst.tiff Exif.Photo.FNumber Rational 1 F4.6 512 rmills@rmillsmbp:~ $If you're trying to write to Exif.ImageN.Something, I really don't believe that will work. 2 weeks ago, there was a very extensive discussion about writing to Exif.SubImageN.Something which is something similar. http://dev.exiv2.org/issues/1182
For v0.26, I have added an option -pR (recursive dump) which operates on TIFF/JPEG/PNG (and some raw formats) to recursively dump the structure of an image file. When I use that, I can see that the above command:
$ exiv2 -M'set Exif.Photo.FNumber F5' ~/Downloads/tst.tiffhas mutilated the file. I feel a strong desire to modify
src/tiffimage.cpp TiffImage::readMetadata() TiffImage::writeMetadata()
to throw an exception for multi-page tiffs. As always, you are welcome to persuade me otherwise!
But first, gimme your command-line buddy, so we can be on the same page!
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Mikayel Egibyan over 5 years ago
I am not using command line. What I do is following:
....
exifData["Exif.Image.Software"] = "blah";
image->writeMetadata();
....
Since for some cases it works, you could possibly add exception. Exceptions are always better than crashes :)
Mikayel
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Robin Mills over 5 years ago
The following command does that:
$ exiv2 --verbose -M'set Exif.Image.Software blah' tst.tiffI'm not getting a crash on the trunk build. Which build are you using? Exiv2 v0.25 on MSVC 64 bit/static?
The following is mutilating the file:
553 rmills@rmillsmbp:~/gnu/exiv2/ttt $ cp ~/Downloads/tst.tiff . ; tiffinfo tst.tiff | grep TIFF ; \ exiv2 --verbose -M'set Exif.Image.Software Robin' tst.tiff ; exiv2 -pa --grep Software tst.tiff ; \ tiffinfo tst.tiff | grep TIFF TIFF Directory at offset 0xafd0 (45008) TIFF Directory at offset 0x160b2 (90290) TIFF Directory at offset 0x21194 (135572) TIFF Directory at offset 0x2c276 (180854) TIFF Directory at offset 0x37358 (226136) File 1/1: tst.tiff Warning: Directory Image3 has an unexpected next pointer; ignored. Set Exif.Image.Software "Robin" (Ascii) Warning: Directory Image3 has an unexpected next pointer; ignored. Exif.Image.Software Ascii 6 Robin TIFF Directory at offset 0x8 (8) TIFF Directory at offset 0x134 (308) TIFF Directory at offset 0xb216 (45590) TIFF Directory at offset 0xb330 (45872) 554 rmills@rmillsmbp:~/gnu/exiv2/ttt $ ls -alt ~/Downloads/tst.tiff tst.tiff -rw-r--r--@ 1 rmills staff 181154 18 May 12:10 tst.tiff -rw-r--r--@ 1 rmills staff 226418 18 May 11:54 /Users/rmills/Downloads/tst.tiff 555 rmills@rmillsmbp:~/gnu/exiv2/ttt $I think you have to accept that Exiv2 cannot be used on multi-page tiffs.
I rather busy today on the house project. I'll take another look at this tonight.
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Mikayel Egibyan over 5 years ago
I am using static build x64 Exiv 0.25.
Mikayel
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Robin Mills over 5 years ago
Here's what I see with "vanilla" v0.25.
C:\cygwin64\home\rmills\gnu\exiv2\0.25\msvc2005\bin\x64\debug>exiv2 --verbose -M"set Exif.Image.Software robin" tst.tiff File 1/1: tst.tiff Set Exif.Image.Software "robin" (Ascii) Exiv2 exception in modify action for file tst.tiff: Invalid ifdId 103 C:\cygwin64\home\rmills\gnu\exiv2\0.25\msvc2005\bin\x64\debug>I don't see a crash. exiv2(.exe) is catching an exception. I'll step it through the debugger this evening. Here's the behaviour on the trunk:
C:\cygwin64\home\rmills\gnu\exiv2\0.25\msvc2005>cd ..\..\trunk\msvc2005\bin\x64\debug C:\cygwin64\home\rmills\gnu\exiv2\trunk\msvc2005\bin\x64\debug>copy ..\..\..\..\..\0.25\msvc2005\bin\x64\debug\tst.tiff 1 file(s) copied. C:\cygwin64\home\rmills\gnu\exiv2\trunk\msvc2005\bin\x64\debug>exiv2 --verbose -M"set Exif.Image.Software robin" tst.tiff File 1/1: tst.tiff Warning: Directory Image3 has an unexpected next pointer; ignored. Set Exif.Image.Software "robin" (Ascii) Warning: Directory Image3 has an unexpected next pointer; ignored. C:\cygwin64\home\rmills\gnu\exiv2\trunk\msvc2005\bin\x64\debug>exiv2 -vVg date --grep svn exiv2 0.25 001900 (64 bit build) date=May 18 2016 svn=4281 C:\cygwin64\home\rmills\gnu\exiv2\trunk\msvc2005\bin\x64\debug>exiv2 -pa --grep Software tst.tiff Exif.Image.Software Ascii 6 robin C:\cygwin64\home\rmills\gnu\exiv2\trunk\msvc2005\bin\x64\debug>
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Robin Mills over 5 years ago
Mikayel
I've had a long 12 hour day on the house project. I'm too tired to start debugging tonight.
I'm going to have to ask you to isolate this issue. I don't see any crash. And I see different behaviour on v0.25 and the trunk. You're going to have to dig into this and get down to a definition of the issue that we can both easily reproduce. The best way is with exiv2(.exe). If that's not possible, modify one of the sample applications (e.g. exifprint.cpp) so that I can drop your code into my environment and reproduce the issue.
There are a couple of matters you should consider:
1 Exiv2 does not support multi-page tiffs
2 Signal handers (to catch crashes) are an application responsibility
I could start debugging tst.tiff to find out exactly what happens on v0.25 and trunk. However, I ask myself the question, "what am I looking for?". There's an exception being thrown in v0.25 that seems to be fixed on the trunk. However we don't support multi-page tiffs. And I don't see a crash - which is the subject. So, I don't know how to move forward with this issue.
Robin
RE: Exiv2 crashes when writing metadata to a some multi-fram tiff files - Added by Robin Mills over 5 years ago
I'm not so tired tonight and have done more work on this. The exception being thrown in v0.25 is coming from tags.cpp inside TiffImage::writeMetadata -> TiffImage::encode -> a deep recursion inside TiffVisitor. I don't know much about that code and don't recall changing anything related to this. So, I've written a little script to identify the build that fixed the v0.25 exception:
#!/bin/bash for r in $(seq 3800 10 3890) ; do echo ------------- $r begin -------------- if [ -e $r ]; then rm -rf $r ; fi svn export svn://dev.exiv2.org/svn/trunk --revision $r $r | wcv0.25 cd $r make config 2>/dev/null | wc ./configure | wc make -j 2>&1 | wc sudo make install | wc echo build = $(exiv2 -vV | grep -e svn -e dll) $(ls -alt $(which exiv2)) T=tst.tiff curl --silent -O http://dev.exiv2.org/attachments/download/1004/$T exiv2 -v -M"set Exif.Image.Software revision $r" $T exiv2 -pa --grep Software $T echo ------------- $r end -------------- echo '' cd .. done # That's all Folks! ##The behaviour changes with r3883. #1095: Do not create a TIFF component for unexpected next IFD pointers. Submitted by Andreas 2015-07-31 (after v0.25 shipped). Here's the evidence:
------------- 3882 begin -------------- 1160 2321 46669 2 10 116 197 1156 9381 191 4573 63819 105 583 7651 build = dll=1 svn=0 -rwxr-xr-x 1 root admin 208104 19 May 21:09 /usr/local/bin/exiv2 File 1/1: tst.tiff Set Exif.Image.Software "revision 3882" (Ascii) Exiv2 exception in modify action for file tst.tiff: Invalid ifdId 103 ------------- 3882 end -------------- ------------- 3883 begin -------------- 1160 2321 46669 2 10 116 197 1156 9381 191 4573 63819 105 583 7651 build = dll=1 svn=0 -rwxr-xr-x 1 root admin 208104 19 May 21:10 /usr/local/bin/exiv2 File 1/1: tst.tiff Warning: Directory Image3 has an unexpected next pointer; ignored. Set Exif.Image.Software "revision 3883" (Ascii) Warning: Directory Image3 has an unexpected next pointer; ignored. Exif.Image.Software Ascii 14 revision 3883 ------------- 3883 end --------------r3883 is good and fixes #1095. I was not involved with either that issue or revision.
I modified exifprint.cpp to operate on tst.tiff. I added your code:
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
assert(image.get() != 0);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
exifData["Exif.Image.Software"] = "blah";
image->writeMetadata();
exit(1);
if (exifData.empty()) {
I invoke exifprint.exe with tst.tiff on the command line. The exception handler is working and reporting Invalid ifdId 103
534 rmills@rmillsmbp:~/gnu/exiv2/3810 $ bin/exifprint tst.tiff Caught Exiv2 exception 'Invalid ifdId 103' 535 rmills@rmillsmbp:~/gnu/exiv2/3810 $So two puzzles:
1 Why is your exception handler not effective?
2 You are reporting a different exception: "terminate called after throwing an instance of 'Exiv2::BasicError<char>'what(): Invalid ifdId 103"
Solution:
Your exception handler is catching the exception, however there something wrong with it and it throws another exception which causes a crash. Eureka!