Project

General

Profile

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

tst.tiff (221 KB) tst.tiff

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.tiff
has 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.tiff
I'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!

    (1-9/9)