[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2] master 5339c75 3/3: [sfnt] Better checks for invalid cmaps (
From: |
Werner LEMBERG |
Subject: |
[freetype2] master 5339c75 3/3: [sfnt] Better checks for invalid cmaps (2/2) (#46019). |
Date: |
Thu, 24 Sep 2015 11:40:16 +0000 |
branch: master
commit 5339c75ee6d71fc15a86f2946d3189003359c37d
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>
[sfnt] Better checks for invalid cmaps (2/2) (#46019).
While the current code in `FT_Get_Next_Char' correctly rejects
out-of-bounds glyph indices, it can be extremely slow for malformed
cmaps that use 32bit values. This commit tries to improve that.
* src/sfnt/ttcmap.c (tt_cmap8_char_next, tt_cmap12_next,
tt_cmap12_char_map_binary, tt_cmap13_next,
tt_cmap13_char_map_binary): Reject glyph indices larger than or
equal to the number of glyphs.
---
ChangeLog | 13 +++++++++++++
include/freetype/freetype.h | 7 +++++++
include/freetype/internal/services/svttcmap.h | 5 +++--
src/sfnt/ttcmap.c | 23 ++++++++++++++++++++++-
4 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d60579d..1cc65ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2015-09-23 Werner Lemberg <address@hidden>
+ [sfnt] Better checks for invalid cmaps (2/2) (#46019).
+
+ While the current code in `FT_Get_Next_Char' correctly rejects
+ out-of-bounds glyph indices, it can be extremely slow for malformed
+ cmaps that use 32bit values. This commit tries to improve that.
+
+ * src/sfnt/ttcmap.c (tt_cmap8_char_next, tt_cmap12_next,
+ tt_cmap12_char_map_binary, tt_cmap13_next,
+ tt_cmap13_char_map_binary): Reject glyph indices larger than or
+ equal to the number of glyphs.
+
+2015-09-23 Werner Lemberg <address@hidden>
+
[base, sfnt] Better checks for invalid cmaps (1/2).
* src/base/ftobjs.c (FT_Get_Char_Index): Don't return out-of-bounds
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index aafbdfd..68aa269 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -3372,6 +3372,13 @@ FT_BEGIN_HEADER
/* } */
/* } */
/* */
+ /* Be aware that character codes can have values up to 0xFFFFFFFF; */
+ /* this might happen for non-Unicode or malformed cmaps. However, */
+ /* even with regular Unicode encoding, so-called `last resort fonts' */
+ /* (using SFNT cmap format 13, see function @FT_Get_CMap_Format) */
+ /* normally have entries for all Unicode characters up to 0x1FFFFF, */
+ /* which can cause *a lot* of iterations. */
+ /* */
/* Note that `*agindex' is set to~0 if the charmap is empty. The */
/* result itself can be~0 in two cases: if the charmap is empty or */
/* if the value~0 is the first valid character code. */
diff --git a/include/freetype/internal/services/svttcmap.h
b/include/freetype/internal/services/svttcmap.h
index 4351a9a..cd95b9a 100644
--- a/include/freetype/internal/services/svttcmap.h
+++ b/include/freetype/internal/services/svttcmap.h
@@ -48,11 +48,12 @@ FT_BEGIN_HEADER
/* `ttnameid.h'. */
/* */
/* format :: */
- /* The cmap format. OpenType 1.5 defines the formats 0 (byte */
+ /* The cmap format. OpenType 1.6 defines the formats 0 (byte */
/* encoding table), 2~(high-byte mapping through table), 4~(segment */
/* mapping to delta values), 6~(trimmed table mapping), 8~(mixed */
/* 16-bit and 32-bit coverage), 10~(trimmed array), 12~(segmented */
- /* coverage), and 14 (Unicode Variation Sequences). */
+ /* coverage), 13~(last resort font), and 14 (Unicode Variation */
+ /* Sequences). */
/* */
typedef struct TT_CMapInfo_
{
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 3d10d7a..6acba73 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -1797,6 +1797,7 @@
tt_cmap8_char_next( TT_CMap cmap,
FT_UInt32 *pchar_code )
{
+ FT_Face face = cmap->cmap.charmap.face;
FT_UInt32 result = 0;
FT_UInt32 char_code;
FT_UInt gindex = 0;
@@ -1841,6 +1842,11 @@
goto Again;
}
+ /* if `gindex' is invalid, the remaining values */
+ /* in this group are invalid, too */
+ if ( gindex >= (FT_UInt)face->num_glyphs )
+ continue;
+
result = char_code;
break;
}
@@ -2181,6 +2187,7 @@
static void
tt_cmap12_next( TT_CMap12 cmap )
{
+ FT_Face face = cmap->cmap.cmap.charmap.face;
FT_Byte* p;
FT_ULong start, end, start_id, char_code;
FT_ULong n;
@@ -2221,6 +2228,11 @@
goto Again;
}
+ /* if `gindex' is invalid, the remaining values */
+ /* in this group are invalid, too */
+ if ( gindex >= (FT_UInt)face->num_glyphs )
+ continue;
+
cmap->cur_charcode = char_code;
cmap->cur_gindex = gindex;
cmap->cur_group = n;
@@ -2293,6 +2305,7 @@
if ( next )
{
+ FT_Face face = cmap->cmap.charmap.face;
TT_CMap12 cmap12 = (TT_CMap12)cmap;
@@ -2310,6 +2323,9 @@
cmap12->cur_charcode = char_code;
cmap12->cur_group = mid;
+ if ( gindex >= (FT_UInt)face->num_glyphs )
+ gindex = 0;
+
if ( !gindex )
{
tt_cmap12_next( cmap12 );
@@ -2517,6 +2533,7 @@
static void
tt_cmap13_next( TT_CMap13 cmap )
{
+ FT_Face face = cmap->cmap.cmap.charmap.face;
FT_Byte* p;
FT_ULong start, end, glyph_id, char_code;
FT_ULong n;
@@ -2542,7 +2559,7 @@
{
gindex = (FT_UInt)glyph_id;
- if ( gindex )
+ if ( gindex && gindex < (FT_UInt)face->num_glyphs )
{
cmap->cur_charcode = char_code;
cmap->cur_gindex = gindex;
@@ -2612,6 +2629,7 @@
if ( next )
{
+ FT_Face face = cmap->cmap.charmap.face;
TT_CMap13 cmap13 = (TT_CMap13)cmap;
@@ -2629,6 +2647,9 @@
cmap13->cur_charcode = char_code;
cmap13->cur_group = mid;
+ if ( gindex >= (FT_UInt)face->num_glyphs )
+ gindex = 0;
+
if ( !gindex )
{
tt_cmap13_next( cmap13 );
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2] master 5339c75 3/3: [sfnt] Better checks for invalid cmaps (2/2) (#46019).,
Werner LEMBERG <=