vcl/source/filter/jpeg/Exif.cxx | 73 +++++++++++++++++++++++++++++----------- vcl/source/filter/jpeg/Exif.hxx | 10 ++--- 2 files changed, 59 insertions(+), 24 deletions(-)
New commits: commit 42c0e433aca68c669bc0f55af404b6bae1655fba Author: Stephan Bergmann <sberg...@redhat.com> AuthorDate: Tue Jun 18 00:00:54 2019 +0200 Commit: Stephan Bergmann <sberg...@redhat.com> CommitDate: Tue Jun 18 10:59:59 2019 +0200 Avoid -fsanitize=misaligned-pointer-use ...like > vcl/source/filter/jpeg/Exif.cxx:158:31: runtime error: member access within misaligned address 0x624000a5610a for type 'Exif::ExifIFD', which requires 4 byte alignment > 0x624000a5610a: note: pointer points here > 00 00 00 07 01 12 00 03 00 00 00 01 00 01 00 00 01 1a 00 05 00 00 00 01 00 00 00 62 01 1b 00 05 > ^ > #0 in Exif::processIFD(unsigned char*, unsigned short, unsigned short, unsigned short, bool, bool) at vcl/source/filter/jpeg/Exif.cxx:158:31 > #1 in Exif::processExif(SvStream&, unsigned short, bool) at vcl/source/filter/jpeg/Exif.cxx:255:5 > #2 in Exif::processJpeg(SvStream&, bool) at vcl/source/filter/jpeg/Exif.cxx:132:20 [...] when inserting some .jpg into Draw. The swapping in Exif::processIFD had been introduced with 3ad12d1a540eeb54fbb34afc3b7a76bf9e3207c3 "fdo#57659: fix exif processing", and it had probably been an oversight that it used OSL_SWAPWORD instead of OSL_SWAPDWORD to swap sal_uInt32 ifd->offset (in two places), and that it failed to swap ifd->type and ifd->count in the bSetValue branch (see the discussion at <https://gerrit.libreoffice.org/#/c/6245/> "fdo#57659: fix exif processing"). Change-Id: If40ddb9b1ef4e2ffc08a0899920919989e8cdfdc Reviewed-on: https://gerrit.libreoffice.org/74236 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sberg...@redhat.com> diff --git a/vcl/source/filter/jpeg/Exif.cxx b/vcl/source/filter/jpeg/Exif.cxx index 3b014f6deb1d..187d5ac6efc6 100644 --- a/vcl/source/filter/jpeg/Exif.cxx +++ b/vcl/source/filter/jpeg/Exif.cxx @@ -148,38 +148,73 @@ bool Exif::processJpeg(SvStream& rStream, bool bSetValue) return false; } -void Exif::processIFD(sal_uInt8* pExifData, sal_uInt16 aLength, sal_uInt16 aOffset, sal_uInt16 aNumberOfTags, bool bSetValue, bool bSwap) +namespace { + +sal_uInt16 read16(sal_uInt8 const * data, bool littleEndian) { + if (littleEndian) { + return data[0] | (sal_uInt16(data[1]) << 8); + } else { + return data[1] | (sal_uInt16(data[0]) << 8); + } +} + +void write16(sal_uInt16 value, sal_uInt8 * data, bool littleEndian) { + if (littleEndian) { + data[0] = value & 0xFF; + data[1] = value >> 8; + } else { + data[1] = value & 0xFF; + data[0] = value >> 8; + } +} + +sal_uInt32 read32(sal_uInt8 const * data, bool littleEndian) { + if (littleEndian) { + return data[0] | (sal_uInt32(data[1]) << 8) + | (sal_uInt32(data[2]) << 16) | (sal_uInt32(data[3]) << 24); + } else { + return data[3] | (sal_uInt32(data[2]) << 8) + | (sal_uInt32(data[1]) << 16) | (sal_uInt32(data[0]) << 24); + } +} + +void write32(sal_uInt32 value, sal_uInt8 * data, bool littleEndian) { + if (littleEndian) { + data[0] = value & 0xFF; + data[1] = (value >> 8) & 0xFF; + data[2] = (value >> 16) & 0xFF; + data[3] = value >> 24; + } else { + data[3] = value & 0xFF; + data[2] = (value >> 8) & 0xFF; + data[1] = (value >> 16) & 0xFF; + data[0] = value >> 24; + } +} + +} + +void Exif::processIFD(sal_uInt8* pExifData, sal_uInt16 aLength, sal_uInt16 aOffset, sal_uInt16 aNumberOfTags, bool bSetValue, bool littleEndian) { ExifIFD* ifd = nullptr; while (aOffset <= aLength - 12 && aNumberOfTags > 0) { ifd = reinterpret_cast<ExifIFD*>(&pExifData[aOffset]); - sal_uInt16 tag = ifd->tag; - if (bSwap) - { - tag = OSL_SWAPWORD(ifd->tag); - } + sal_uInt16 tag = read16(ifd->tag, littleEndian); if (tag == ORIENTATION) { if(bSetValue) { - ifd->tag = ORIENTATION; - ifd->type = 3; - ifd->count = 1; - ifd->offset = maOrientation; - if (bSwap) - { - ifd->tag = OSL_SWAPWORD(ifd->tag); - ifd->offset = OSL_SWAPWORD(ifd->offset); - } + write16(ORIENTATION, ifd->tag, littleEndian); + write16(3, ifd->type, littleEndian); + write32(1, ifd->count, littleEndian); + write32(maOrientation, ifd->offset, littleEndian); } else { - sal_uInt32 nIfdOffset = ifd->offset; - if (bSwap) - nIfdOffset = OSL_SWAPWORD(ifd->offset); + sal_uInt32 nIfdOffset = read32(ifd->offset, littleEndian); maOrientation = convertToOrientation(nIfdOffset); } } @@ -252,7 +287,7 @@ bool Exif::processExif(SvStream& rStream, sal_uInt16 aSectionLength, bool bSetVa aNumberOfTags = ((aExifData[aOffset] << 8) | aExifData[aOffset+1]); } - processIFD(aExifData.get(), aLength, aOffset+2, aNumberOfTags, bSetValue, bSwap); + processIFD(aExifData.get(), aLength, aOffset+2, aNumberOfTags, bSetValue, bIntel); if (bSetValue) { diff --git a/vcl/source/filter/jpeg/Exif.hxx b/vcl/source/filter/jpeg/Exif.hxx index 6b5991c60ee7..046df028a891 100644 --- a/vcl/source/filter/jpeg/Exif.hxx +++ b/vcl/source/filter/jpeg/Exif.hxx @@ -49,13 +49,13 @@ private: bool processJpeg(SvStream& rStream, bool bSetValue); bool processExif(SvStream& rStream, sal_uInt16 aLength, bool bSetValue); - void processIFD(sal_uInt8* pExifData, sal_uInt16 aLength, sal_uInt16 aOffset, sal_uInt16 aNumberOfTags, bool bSetValue, bool bMoto); + void processIFD(sal_uInt8* pExifData, sal_uInt16 aLength, sal_uInt16 aOffset, sal_uInt16 aNumberOfTags, bool bSetValue, bool bLittleEndian); struct ExifIFD { - sal_uInt16 tag; - sal_uInt16 type; - sal_uInt32 count; - sal_uInt32 offset; + sal_uInt8 tag[2]; + sal_uInt8 type[2]; + sal_uInt8 count[4]; + sal_uInt8 offset[4]; }; struct TiffHeader { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits