Exiv2 / exiv2

Image metadata library and tools
http://www.exiv2.org/
Other
920 stars 278 forks source link

Adding EXIF metadata causes some JPEGs to become invalid #2988

Closed dloebl closed 3 months ago

dloebl commented 3 months ago

Describe the bug

Adding EXIF metadata causes some JPEGs to become invalid: If the input JPEG has an empty JPEG marker section, an invalid marker is written:

Input JPEG:

00000000:  ff d8 | ff e1 00 02

00 02 is the length of the marker excluding the ff e1 bytes (so it's effectively empty).

Adding EXIF metadata causes the JPEG to become invalid.

Output JPEG:

00000000:  ff d8 | ff e1 00 28 .. <40 bytes of EXIF data to follow> |
00000020:  .. | ff e1 00 00

00 00 isn't a valid length for a JPEG marker, so the file is invalid and fails to render in some browsers (most notably Safari).

To Reproduce

test.jpg

clang++ -std=c++11 $(pkg-config --libs --cflags exiv2) test.cpp
#include <exiv2/exiv2.hpp>

int main() {
    auto image = Exiv2::ImageFactory::open("test.jpg");
    assert(image.get() != 0);
    Exiv2::ExifData newExif;
    newExif["Exif.Image.HostComputer"] = "test";
    image->setExifData(newExif);
    image->writeMetadata();
}

Before:

$ exiv2 test.jpg

File name       : test.jpg
File size       : 330 Bytes
MIME type       : image/jpeg
Image size      : 32 x 32
test.jpg: No Exif data found in the file

After:

$ exiv2 test.jpg

Exiv2 exception in print action for file test.jpg:
Failed to read image data

Expected behavior

The JPEG should be valid after adding EXIF metadata.

Desktop:

kmilos commented 3 months ago

Thanks for the report and the test file.

Since you've done much of the groundwork and a reproducer, would you be willing to debug further (should be in JpegBase::doWriteMetadata()) and propose a patch?

kmilos commented 3 months ago

Never mind, think I've found it, but need help wrapping it up...

dloebl commented 3 months ago

Thank you for addressing this issue so quickly, @kmilos! I can confirm that #2989 has resolved the issue