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

Caolán McNamara caolanm at redhat.com
Fri Feb 9 10:16:31 UTC 2018


 vcl/source/fontsubset/sft.cxx |   95 +++++++++++++++++++++++++++++++-----------
 1 file changed, 71 insertions(+), 24 deletions(-)

New commits:
commit f832198e6a33052c7cc86b25843badfb962a2ae8
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Feb 8 23:57:14 2018 +0000

    move largest bounds check to start
    
    Change-Id: I03fe80f9568759b829fac4e9bcfd496efebe6a26

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index d2423c3dcc89..5f9663ae12df 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1498,19 +1498,17 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     } else if (TTCTag == T_otto) {                         /* PS-OpenType font */
         tdoffset = 0;
     } else if (TTCTag == T_ttcf) {                         /* TrueType collection */
+        if (!withinBounds(12, 4 * facenum, sizeof(sal_uInt32), t->fsize)) {
+            return SF_FONTNO;
+        }
         sal_uInt32 Version = GetUInt32(t->ptr, 4);
         if (Version != 0x00010000 && Version != 0x00020000) {
             return SF_TTFORMAT;
         }
-        if (!withinBounds(8, 0, sizeof(sal_uInt32), t->fsize) || facenum >= GetUInt32(t->ptr, 8)) {
-            return SF_FONTNO;
-        }
-        if (withinBounds(12, 4 * facenum, sizeof(sal_uInt32), t->fsize)) {
-            tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum);
-        } else {
+        if (facenum >= GetUInt32(t->ptr, 8)) {
             return SF_FONTNO;
         }
-
+        tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum);
     } else {
         return SF_TTFORMAT;
     }
commit bb32616bdd6e3b327654bab0e1d790d8d50b893d
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Feb 8 17:38:59 2018 +0000

    bounds check
    
    Change-Id: I6d32a6b6f1dd91db42a3f154700ea55603f0e4dd

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index a00fe2a7b779..d2423c3dcc89 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1502,7 +1502,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         if (Version != 0x00010000 && Version != 0x00020000) {
             return SF_TTFORMAT;
         }
-        if (facenum >= GetUInt32(t->ptr, 8)) {
+        if (!withinBounds(8, 0, sizeof(sal_uInt32), t->fsize) || facenum >= GetUInt32(t->ptr, 8)) {
             return SF_FONTNO;
         }
         if (withinBounds(12, 4 * facenum, sizeof(sal_uInt32), t->fsize)) {
commit c7b0117f26a386c98a721ff3897479c268103d74
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Feb 8 15:45:16 2018 +0000

    extend to cover the last byte needed
    
    Change-Id: I5177d42b47a4bca614878dce4a69ab16b5cfe163

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 36c3ae73d602..a00fe2a7b779 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1505,7 +1505,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         if (facenum >= GetUInt32(t->ptr, 8)) {
             return SF_FONTNO;
         }
-        if (withinBounds(12, 0, 4 * facenum, t->fsize)) {
+        if (withinBounds(12, 4 * facenum, sizeof(sal_uInt32), t->fsize)) {
             tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum);
         } else {
             return SF_FONTNO;
commit e8b2aad1cb2107304761e68aa380b5c29d8ef22f
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Feb 8 09:25:53 2018 +0000

    simplify returns
    
    Change-Id: I1a67cb2f1c686032438852fec1267a59fbd04d7f

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index cae23c909759..36c3ae73d602 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1462,12 +1462,29 @@ bool withinBounds(sal_uInt32 tdoffset, sal_uInt32 moreoffset, sal_uInt32 len, sa
     return result <= available;
 }
 
+class TTFontCloser
+{
+    TrueTypeFont* m_font;
+public:
+    TTFontCloser(TrueTypeFont* t)
+        : m_font(t)
+    {
+    }
+    void clear() { m_font = nullptr; }
+    ~TTFontCloser()
+    {
+        if (m_font)
+            CloseTTFont(m_font);
+    }
+};
+
 }
 
 static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
 {
+    TTFontCloser aCloseGuard(t);
+
     if (t->fsize < 4) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
     int i;
@@ -1483,16 +1500,18 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     } else if (TTCTag == T_ttcf) {                         /* TrueType collection */
         sal_uInt32 Version = GetUInt32(t->ptr, 4);
         if (Version != 0x00010000 && Version != 0x00020000) {
-            CloseTTFont(t);
             return SF_TTFORMAT;
         }
         if (facenum >= GetUInt32(t->ptr, 8)) {
-            CloseTTFont(t);
             return SF_FONTNO;
         }
-        tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum);
+        if (withinBounds(12, 0, 4 * facenum, t->fsize)) {
+            tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum);
+        } else {
+            return SF_FONTNO;
+        }
+
     } else {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1501,7 +1520,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     }
 
     if (t->ntables >= 128 || t->ntables == 0) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1552,7 +1570,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     if( facenum == sal_uInt32(~0) ) {
         sal_uInt8* pHead = const_cast<sal_uInt8*>(t->tables[O_head]);
         if (!pHead) {
-            CloseTTFont(t);
             return SF_TTFORMAT;
         }
         /* limit Head candidate to TTC extract's limits */
@@ -1571,7 +1588,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
             }
         }
         if (p <= t->ptr) {
-            CloseTTFont(t);
             return SF_TTFORMAT;
         }
     }
@@ -1613,7 +1629,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
      */
 
     if( !(getTable(t, O_maxp) && getTable(t, O_head) && getTable(t, O_name) && getTable(t, O_cmap)) ) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1624,14 +1639,12 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     table = getTable(t, O_head);
     table_size = getTableSize(t, O_head);
     if (table_size < 52) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
     t->unitsPerEm = GetUInt16(table, 18);
     int indexfmt = GetInt16(table, 50);
 
     if( ((indexfmt != 0) && (indexfmt != 1)) || (t->unitsPerEm <= 0) ) {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1655,7 +1668,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         /* TODO: implement to get subsetting */
         assert(t->goffsets != nullptr);
     } else {
-        CloseTTFont(t);
         return SF_TTFORMAT;
     }
 
@@ -1670,6 +1682,8 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     GetNames(t);
     FindCmap(t);
 
+    aCloseGuard.clear();
+
     return SF_OK;
 }
 
commit 139b6c6cf898467098f3a6f29fa84013a182285f
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 21:24:34 2018 +0000

    use safeint on calculations
    
    Change-Id: Ic063786ba41aa9a985f505e62b43d3d543a0d48f

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 64beb34b28b1..cae23c909759 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -38,7 +38,7 @@
 #include "xlat.hxx"
 #include <rtl/crc.h>
 #include <rtl/ustring.hxx>
-
+#include <o3tl/safeint.hxx>
 #include <osl/endian.h>
 #include <algorithm>
 
@@ -1450,6 +1450,20 @@ int OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, T
     return doOpenTTFont( facenum, *ttf );
 }
 
+namespace {
+
+bool withinBounds(sal_uInt32 tdoffset, sal_uInt32 moreoffset, sal_uInt32 len, sal_uInt32 available)
+{
+    sal_uInt32 result;
+    if (o3tl::checked_add(tdoffset, moreoffset, result))
+        return false;
+    if (o3tl::checked_add(result, len, result))
+        return false;
+    return result <= available;
+}
+
+}
+
 static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
 {
     if (t->fsize < 4) {
@@ -1482,7 +1496,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         return SF_TTFORMAT;
     }
 
-    if (tdoffset + 4 + sizeof(sal_uInt16) <=  static_cast<sal_uInt32>(t->fsize)) {
+    if (withinBounds(tdoffset, 0, 4 + sizeof(sal_uInt16), t->fsize)) {
         t->ntables = GetUInt16(t->ptr + tdoffset, 4);
     }
 
@@ -1501,7 +1515,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         int nIndex;
         const sal_uInt32 nStart = tdoffset + 12;
         const sal_uInt32 nOffset = 16 * i;
-        if (nStart + nOffset + sizeof(sal_uInt32) <=  static_cast<sal_uInt32>(t->fsize))
+        if (withinBounds(nStart, nOffset, sizeof(sal_uInt32), t->fsize))
             tag = GetUInt32(t->ptr + nStart, nOffset);
         else
             tag = static_cast<sal_uInt32>(-1);
@@ -1526,7 +1540,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
             default: nIndex = -1; break;
         }
 
-        if ((nIndex >= 0) && (nStart + nOffset + 12 + sizeof(sal_uInt32) <= static_cast<sal_uInt32>(t->fsize))) {
+        if ((nIndex >= 0) && withinBounds(nStart, nOffset, 12 + sizeof(sal_uInt32), t->fsize)) {
             sal_uInt32 nTableOffset = GetUInt32(t->ptr + nStart, nOffset + 8);
             length = GetUInt32(t->ptr + nStart, nOffset + 12);
             t->tables[nIndex] = t->ptr + nTableOffset;
commit 75a171a405afd6eac236af93aa9d29a9c3ec9c64
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 21:10:16 2018 +0000

    check ntables offset
    
    Change-Id: Id75f5f4b578fd176c17e5763569f1403260c6594

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 474d07ba4266..64beb34b28b1 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1482,8 +1482,11 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         return SF_TTFORMAT;
     }
 
-    t->ntables = GetUInt16(t->ptr + tdoffset, 4);
-    if (t->ntables >= 128) {
+    if (tdoffset + 4 + sizeof(sal_uInt16) <=  static_cast<sal_uInt32>(t->fsize)) {
+        t->ntables = GetUInt16(t->ptr + tdoffset, 4);
+    }
+
+    if (t->ntables >= 128 || t->ntables == 0) {
         CloseTTFont(t);
         return SF_TTFORMAT;
     }
commit ae73c3ff112e1ed38eb4678ac5745990661a2e66
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 21:03:53 2018 +0000

    check tableoffset against size
    
    Change-Id: Ia79be052dd3f6b6ed38fb326558924c853af5fff

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 4f91edbe31aa..474d07ba4266 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1522,9 +1522,10 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
             case T_CFF:  nIndex = O_CFF; break;
             default: nIndex = -1; break;
         }
-        if( nIndex >= 0 ) {
-            sal_uInt32 nTableOffset = GetUInt32(t->ptr + tdoffset + 12, 16 * i + 8);
-            length = GetUInt32(t->ptr + tdoffset + 12, 16 * i + 12);
+
+        if ((nIndex >= 0) && (nStart + nOffset + 12 + sizeof(sal_uInt32) <= static_cast<sal_uInt32>(t->fsize))) {
+            sal_uInt32 nTableOffset = GetUInt32(t->ptr + nStart, nOffset + 8);
+            length = GetUInt32(t->ptr + nStart, nOffset + 12);
             t->tables[nIndex] = t->ptr + nTableOffset;
             t->tlens[nIndex] = length;
         }
@@ -1533,8 +1534,10 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     /* Fixup offsets when only a TTC extract was provided */
     if( facenum == sal_uInt32(~0) ) {
         sal_uInt8* pHead = const_cast<sal_uInt8*>(t->tables[O_head]);
-        if( !pHead )
+        if (!pHead) {
+            CloseTTFont(t);
             return SF_TTFORMAT;
+        }
         /* limit Head candidate to TTC extract's limits */
         if( pHead > t->ptr + (t->fsize - 54) )
             pHead = t->ptr + (t->fsize - 54);
@@ -1550,8 +1553,10 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
                 break;
             }
         }
-        if( p <= t->ptr )
+        if (p <= t->ptr) {
+            CloseTTFont(t);
             return SF_TTFORMAT;
+        }
     }
 
     /* Check the table offsets after TTC correction */
commit 683d9883ad8fd6568e6a7832e5bb347c1d043e4b
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 17:39:05 2018 +0000

    check cmap offset
    
    Change-Id: I5aae26c38f3645020f0e1d6d7b6877c2727af1b4

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index b4fa7fd71495..4f91edbe31aa 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1320,6 +1320,13 @@ static void FindCmap(TrueTypeFont *ttf)
     }
 
     if (ttf->cmapType != CMAP_NOT_USABLE) {
+        if( (ttf->cmap - ttf->ptr + 2) > static_cast<sal_uInt32>(ttf->fsize) ) {
+            ttf->cmapType = CMAP_NOT_USABLE;
+            ttf->cmap = nullptr;
+        }
+    }
+
+    if (ttf->cmapType != CMAP_NOT_USABLE) {
         switch (GetUInt16(ttf->cmap, 0)) {
             case 0: ttf->mapper = getGlyph0; break;
             case 2: ttf->mapper = getGlyph2; break;
commit 1828490bb22f1c8273c4a9f5b1db819b173ca70d
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 17:26:04 2018 +0000

    check more table sizes
    
    Change-Id: I004a6d322f60d916cc4635b362ce948e8a10d7c7

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index f216c34622fb..b4fa7fd71495 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -2403,14 +2403,18 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
     }
 
     table = getTable(ttf, O_head);      /* 'head' tables is always there */
-    info->xMin = XUnits(UPEm, GetInt16(table, 36));
-    info->yMin = XUnits(UPEm, GetInt16(table, 38));
-    info->xMax = XUnits(UPEm, GetInt16(table, 40));
-    info->yMax = XUnits(UPEm, GetInt16(table, 42));
-    info->macStyle = GetInt16(table, 44);
+    table_size = getTableSize(ttf, O_head);
+    if (table_size >= 46) {
+        info->xMin = XUnits(UPEm, GetInt16(table, 36));
+        info->yMin = XUnits(UPEm, GetInt16(table, 38));
+        info->xMax = XUnits(UPEm, GetInt16(table, 40));
+        info->yMax = XUnits(UPEm, GetInt16(table, 42));
+        info->macStyle = GetInt16(table, 44);
+    }
 
     table = getTable(ttf, O_hhea);
-    if (table) {
+    table_size = getTableSize(ttf, O_hhea);
+    if (table && table_size >= 10) {
         info->ascender  = XUnits(UPEm, GetInt16(table, 4));
         info->descender = XUnits(UPEm, GetInt16(table, 6));
         info->linegap   = XUnits(UPEm, GetInt16(table, 8));
commit 603cb6cf31a5212d03736a552770e5734b0e8066
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 17:21:39 2018 +0000

    fix mem leak
    
    Change-Id: I0d329357ac282d4652b0f7ebc401cbd51963461b

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 81184aaf9d75..f216c34622fb 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1476,8 +1476,10 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
     }
 
     t->ntables = GetUInt16(t->ptr + tdoffset, 4);
-    if( t->ntables >= 128 )
+    if (t->ntables >= 128) {
+        CloseTTFont(t);
         return SF_TTFORMAT;
+    }
 
     t->tables = static_cast<const sal_uInt8**>(calloc(NUM_TAGS, sizeof(sal_uInt8 *)));
     assert(t->tables != nullptr);
commit 5b426038a7befcaf0d05824ffb20200ff8833ad3
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Feb 7 17:17:14 2018 +0000

    use ptr diff rather than int
    
    Change-Id: Ia174fd94c57cc3c899c10e1c0dc5968965a50427

diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index cae835510712..81184aaf9d75 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1564,7 +1564,7 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
         }
         else if( const_cast<sal_uInt8*>(t->tables[i]) + t->tlens[i] > t->ptr + t->fsize )
         {
-            int nMaxLen = (t->ptr + t->fsize) - t->tables[i];
+            sal_PtrDiff nMaxLen = (t->ptr + t->fsize) - t->tables[i];
             if( nMaxLen < 0 )
                 nMaxLen = 0;
             t->tlens[i] = nMaxLen;


More information about the Libreoffice-commits mailing list