[Libreoffice-commits] core.git: vcl/source

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Tue Jun 18 09:01:10 UTC 2019


 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 <sbergman at redhat.com>
AuthorDate: Tue Jun 18 00:00:54 2019 +0200
Commit:     Stephan Bergmann <sbergman at 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 <sbergman at 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 {


More information about the Libreoffice-commits mailing list