summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2019-06-18 00:00:54 +0200
committerStephan Bergmann <sbergman@redhat.com>2019-06-18 10:59:59 +0200
commit42c0e433aca68c669bc0f55af404b6bae1655fba (patch)
treeb9aca1e8f0c6c16d8070e46afc1aca689c0e609c
parenta2e4b76e29e491bac4f9e6dfd9929dfd49a4b05e (diff)
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 <sbergman@redhat.com>
-rw-r--r--vcl/source/filter/jpeg/Exif.cxx73
-rw-r--r--vcl/source/filter/jpeg/Exif.hxx10
2 files changed, 59 insertions, 24 deletions
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 {