diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index ce44d1ff4..fb7c9aee7 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -1027,7 +1027,7 @@ int ImageIO::savePNG (const Glib::ustring &fname, int bps) const #if defined(PNG_SKIP_sRGB_CHECK_PROFILE) && defined(PNG_SET_OPTION_SUPPORTED) png_set_option(png, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON); #endif - + png_infop info = png_create_info_struct(png); if (!info) { @@ -1227,12 +1227,12 @@ int ImageIO::saveJPEG (const Glib::ustring &fname, int quality, int subSamp) con jpeg_start_compress(&cinfo, TRUE); // buffer for exif and iptc markers - unsigned char* buffer = new unsigned char[165535]; //FIXME: no buffer size check so it can be overflowed in createJPEGMarker() for large tags, and then software will crash + unsigned char* buffer; unsigned int size; // assemble and write exif marker if (exifRoot) { - int size = rtexif::ExifManager::createJPEGMarker (exifRoot, *exifChange, cinfo.image_width, cinfo.image_height, buffer); + rtexif::ExifManager::createJPEGMarker (exifRoot, *exifChange, cinfo.image_width, cinfo.image_height, buffer, size); if (size > 0 && size < 65530) { jpeg_write_marker(&cinfo, JPEG_APP0 + 1, buffer, size); diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index a7125fb9a..a48db5229 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -3243,24 +3243,17 @@ std::vector ExifManager::getDefaultTIFFTags (TagDirectory* forthis) -int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer) +int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize) { // write tiff header - int offs = 6; - memcpy (buffer, "Exif\0\0", 6); + int offs = 6; // "Exif\0\0" ByteOrder order = INTEL; if (root) { order = root->getOrder (); } - sset2 ((unsigned short)order, buffer + offs, order); - offs += 2; - sset2 (42, buffer + offs, order); - offs += 2; - sset4 (8, buffer + offs, order); - TagDirectory* cl; if (root) { @@ -3322,11 +3315,20 @@ int ExifManager::createJPEGMarker (const TagDirectory* root, const rtengine::pro } cl->sort (); - int size = cl->write (8, buffer + 6); + bufferSize = cl->calculateSize() + 8 + 6; + buffer = new unsigned char[bufferSize]; // this has to be deleted in caller + memcpy (buffer, "Exif\0\0", 6); + sset2 ((unsigned short)order, buffer + offs, order); + offs += 2; + sset2 (42, buffer + offs, order); + offs += 2; + sset4 (8, buffer + offs, order); + + int endOffs = cl->write (8, buffer + 6); delete cl; - return size + 6; + return endOffs; } int ExifManager::createPNGMarker(const TagDirectory* root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize) diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 7b2f8ad23..beb21131a 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -379,7 +379,7 @@ public: /// @param forthis The byte order will be taken from the given directory. /// @return The ownership of the return tags is passed to the caller. static std::vector getDefaultTIFFTags (TagDirectory* forthis); - static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer); + static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char *&buffer, unsigned &bufferSize); static int createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); static int createPNGMarker(const TagDirectory *root, const rtengine::procparams::ExifPairs &changeList, int W, int H, int bps, const char *iptcdata, int iptclen, unsigned char *&buffer, unsigned &bufferSize); };