summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/sft.hxx14
-rw-r--r--vcl/source/fontsubset/sft.cxx111
2 files changed, 73 insertions, 52 deletions
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index 80c62c11b878..0b3c3afcfbef 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -189,21 +189,15 @@ namespace vcl
int descender; /**< typographic descent. */
int linegap; /**< typographic line gap.\ Negative values are treated as
zero in Win 3.1, System 6 and System 7. */
- int vascent; /**< typographic ascent for vertical writing mode */
- int vdescent; /**< typographic descent for vertical writing mode */
int typoAscender; /**< OS/2 portable typographic ascender */
int typoDescender; /**< OS/2 portable typographic descender */
int typoLineGap; /**< OS/2 portable typographic line gap */
int winAscent; /**< ascender metric for Windows */
int winDescent; /**< descender metric for Windows */
bool symbolEncoded; /**< true: MS symbol encoded */
- int rangeFlag; /**< if set to 1 Unicode Range flags are applicable */
- sal_uInt32 ur1; /**< bits 0 - 31 of Unicode Range flags */
- sal_uInt32 ur2; /**< bits 32 - 63 of Unicode Range flags */
- sal_uInt32 ur3; /**< bits 64 - 95 of Unicode Range flags */
- sal_uInt32 ur4; /**< bits 96 - 127 of Unicode Range flags */
- sal_uInt8 panose[10]; /**< PANOSE classification number */
- sal_uInt32 typeFlags; /**< type flags (copyright bits + PS-OpenType flag) */
+ sal_uInt8 panose[10]; /**< PANOSE classification number */
+ sal_uInt32 typeFlags; /**< type flags (copyright bits + PS-OpenType flag) */
+ sal_uInt16 fsSelection; /**< OS/2 fsSelection */
} TTGlobalFontInfo;
#define TYPEFLAG_INVALID 0x8000000
@@ -521,8 +515,6 @@ namespace vcl
/*- private definitions */
struct TrueTypeFont {
- sal_uInt32 tag;
-
char *fname;
sal_Int32 fsize;
sal_uInt8 *ptr;
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 150b21ec676a..e6bfd7509da3 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -39,7 +39,7 @@
#include "xlat.hxx"
#include <rtl/crc.h>
#include <rtl/ustring.hxx>
-
+#include <o3tl/safeint.hxx>
#include <osl/endian.h>
#include <algorithm>
@@ -104,9 +104,6 @@ typedef struct {
sal_uInt32 *offs; /* array of nGlyphs offsets */
} GlyphOffsets;
-/* private tags */
-static const sal_uInt32 TTFontClassTag = 0x74746663; /* 'ttfc' */
-
static const sal_uInt32 T_true = 0x74727565; /* 'true' */
static const sal_uInt32 T_ttcf = 0x74746366; /* 'ttcf' */
static const sal_uInt32 T_otto = 0x4f54544f; /* 'OTTO' */
@@ -1341,6 +1338,13 @@ static void FindCmap(TrueTypeFont *ttf)
}
if (ttf->cmapType != CMAP_NOT_USABLE) {
+ if( (ttf->cmap - ttf->ptr + 2U) > 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, 1)) {
case 0: ttf->mapper = getGlyph0; break;
case 2: ttf->mapper = getGlyph2; break;
@@ -1461,7 +1465,6 @@ static void allocTrueTypeFont( TrueTypeFont** ttf )
*ttf = static_cast<TrueTypeFont*>(calloc(1,sizeof(TrueTypeFont)));
if( *ttf != nullptr )
{
- (*ttf)->tag = 0;
(*ttf)->fname = nullptr;
(*ttf)->fsize = -1;
(*ttf)->ptr = nullptr;
@@ -1546,10 +1549,41 @@ 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;
+}
+
+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;
@@ -1563,27 +1597,28 @@ 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, 1);
if (Version != 0x00010000 && Version != 0x00020000) {
- CloseTTFont(t);
return SF_TTFORMAT;
}
if (facenum >= GetUInt32(t->ptr, 8, 1)) {
- CloseTTFont(t);
return SF_FONTNO;
}
tdoffset = GetUInt32(t->ptr, 12 + 4 * facenum, 1);
} else {
- CloseTTFont(t);
return SF_TTFORMAT;
}
- /* magic number */
- t->tag = TTFontClassTag;
+ if (withinBounds(tdoffset, 0, 4 + sizeof(sal_uInt16), t->fsize)) {
+ t->ntables = GetUInt16(t->ptr + tdoffset, 4, 1);
+ }
- t->ntables = GetUInt16(t->ptr + tdoffset, 4, 1);
- if( t->ntables >= 128 )
+ if (t->ntables >= 128 || t->ntables == 0) {
return SF_TTFORMAT;
+ }
t->tables = static_cast<const sal_uInt8**>(calloc(NUM_TAGS, sizeof(sal_uInt8 *)));
assert(t->tables != nullptr);
@@ -1595,7 +1630,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, 1);
else
tag = static_cast<sal_uInt32>(-1);
@@ -1620,9 +1655,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, 1);
- length = GetUInt32(t->ptr + tdoffset + 12, 16 * i + 12, 1);
+
+ if ((nIndex >= 0) && withinBounds(nStart, nOffset, 12 + sizeof(sal_uInt32), t->fsize)) {
+ sal_uInt32 nTableOffset = GetUInt32(t->ptr + nStart, nOffset + 8, 1);
+ length = GetUInt32(t->ptr + nStart, nOffset + 12, 1);
t->tables[nIndex] = t->ptr + nTableOffset;
t->tlens[nIndex] = length;
}
@@ -1631,8 +1667,9 @@ 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) {
return SF_TTFORMAT;
+ }
/* limit Head candidate to TTC extract's limits */
if( pHead > t->ptr + (t->fsize - 54) )
pHead = t->ptr + (t->fsize - 54);
@@ -1648,8 +1685,9 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
break;
}
}
- if( p <= t->ptr )
+ if (p <= t->ptr) {
return SF_TTFORMAT;
+ }
}
/* Check the table offsets after TTC correction */
@@ -1671,7 +1709,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;
@@ -1689,7 +1727,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;
}
@@ -1700,14 +1737,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, 1);
int indexfmt = GetInt16(table, 50, 1);
if( ((indexfmt != 0) && (indexfmt != 1)) || (t->unitsPerEm <= 0) ) {
- CloseTTFont(t);
return SF_TTFORMAT;
}
@@ -1731,7 +1766,6 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
/* TODO: implement to get subsetting */
assert(t->goffsets != nullptr);
} else {
- CloseTTFont(t);
return SF_TTFORMAT;
}
@@ -1748,6 +1782,8 @@ static int doOpenTTFont( sal_uInt32 facenum, TrueTypeFont* t )
GetKern(t);
ReadGSUB( t, 0, 0 );
+ aCloseGuard.clear();
+
return SF_OK;
}
@@ -2590,13 +2626,6 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
if( info->winDescent > 5*UPEm )
info->winDescent = XUnits(UPEm, GetInt16(table, 76,1));
}
- if (ttf->cmapType == CMAP_MS_Unicode) {
- info->rangeFlag = 1;
- info->ur1 = GetUInt32(table, 42, 1);
- info->ur2 = GetUInt32(table, 46, 1);
- info->ur3 = GetUInt32(table, 50, 1);
- info->ur4 = GetUInt32(table, 54, 1);
- }
memcpy(info->panose, table + 32, 10);
info->typeFlags = GetUInt16( table, 8, 1 );
if( getTable(ttf, O_CFF) )
@@ -2610,24 +2639,24 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
}
table = getTable(ttf, O_head); /* 'head' tables is always there */
- info->xMin = XUnits(UPEm, GetInt16(table, 36, 1));
- info->yMin = XUnits(UPEm, GetInt16(table, 38, 1));
- info->xMax = XUnits(UPEm, GetInt16(table, 40, 1));
- info->yMax = XUnits(UPEm, GetInt16(table, 42, 1));
- info->macStyle = GetInt16(table, 44, 1);
+ table_size = getTableSize(ttf, O_head);
+ if (table_size >= 46) {
+ info->xMin = XUnits(UPEm, GetInt16(table, 36, 1));
+ info->yMin = XUnits(UPEm, GetInt16(table, 38, 1));
+ info->xMax = XUnits(UPEm, GetInt16(table, 40, 1));
+ info->yMax = XUnits(UPEm, GetInt16(table, 42, 1));
+ info->macStyle = GetInt16(table, 44, 1);
+ }
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, 1));
info->descender = XUnits(UPEm, GetInt16(table, 6, 1));
info->linegap = XUnits(UPEm, GetInt16(table, 8, 1));
}
table = getTable(ttf, O_vhea);
- if (table) {
- info->vascent = XUnits(UPEm, GetInt16(table, 4, 1));
- info->vdescent = XUnits(UPEm, GetInt16(table, 6, 1));
- }
}
GlyphData *GetTTRawGlyphData(TrueTypeFont *ttf, sal_uInt32 glyphID)