Restrict the number of the charmaps in a rogue-compatible mode.

Fix for Savannah bug #30059.

* src/cache/ftccmap.c (FTC_CMapCache_Lookup): Replace `16' the
minimum character code passed by a legacy rogue client by...
* include/freetype/config/ftoption.h (FT_MAX_CHARMAP_CACHEABLE):
This.  It is undefined when FT_CONFIG_OPTION_OLD_INTERNALS is
undefined (thus the rogue client compatibility is not required).

* src/cff/cffobjs.c (cff_face_init): Abort the automatic
selection or synthesis of Unicode cmap subtable when the charmap
index exceeds FT_MAX_CHARMAP_CACHEABLE.
* src/sfnt/ttcmap.c (tt_face_build_cmaps): Issue error message
when the charmap index exceeds FT_MAX_CHARMAP_CACHEABLE.

* src/base/ftobjs.c (find_unicode_charmap): When Unicode charmap
is found after FT_MAX_CHARMAP_CACHEABLE, ignore it and search
earlier one.
(find_variant_selector_charmap): When UVS charmap is found after
FT_MAX_CHARMAP_CACHEABLE, ignore it and search earlier one.
(FT_Select_Charmap): When a charmap matching with requested
encoding but after FT_MAX_CHARMAP_CACHEABLE, ignore and search
earlier one.
(FT_Set_Charmap): When a charmap matching with requested
charmap but after FT_MAX_CHARMAP_CACHEABLE, ignore and search
earlier one.
(FT_Get_Charmap_Index): When a requested charmap is found
after FT_MAX_CHARMAP_CACHEABLE, return the inverted charmap
index.
This commit is contained in:
suzuki toshiya 2010-07-04 20:14:18 +09:00
parent 8a6f3280f5
commit 0ae3271814
6 changed files with 140 additions and 13 deletions

View File

@ -1,3 +1,35 @@
2010-07-04 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
Restrict the number of the charmaps in a rogue-compatible mode.
Fix for Savannah bug #30059.
* src/cache/ftccmap.c (FTC_CMapCache_Lookup): Replace `16' the
minimum character code passed by a legacy rogue client by...
* include/freetype/config/ftoption.h (FT_MAX_CHARMAP_CACHEABLE):
This. It is undefined when FT_CONFIG_OPTION_OLD_INTERNALS is
undefined (thus the rogue client compatibility is not required).
* src/cff/cffobjs.c (cff_face_init): Abort the automatic
selection or synthesis of Unicode cmap subtable when the charmap
index exceeds FT_MAX_CHARMAP_CACHEABLE.
* src/sfnt/ttcmap.c (tt_face_build_cmaps): Issue error message
when the charmap index exceeds FT_MAX_CHARMAP_CACHEABLE.
* src/base/ftobjs.c (find_unicode_charmap): When Unicode charmap
is found after FT_MAX_CHARMAP_CACHEABLE, ignore it and search
earlier one.
(find_variant_selector_charmap): When UVS charmap is found after
FT_MAX_CHARMAP_CACHEABLE, ignore it and search earlier one.
(FT_Select_Charmap): When a charmap matching with requested
encoding but after FT_MAX_CHARMAP_CACHEABLE, ignore and search
earlier one.
(FT_Set_Charmap): When a charmap matching with requested
charmap but after FT_MAX_CHARMAP_CACHEABLE, ignore and search
earlier one.
(FT_Get_Charmap_Index): When a requested charmap is found
after FT_MAX_CHARMAP_CACHEABLE, return the inverted charmap
index.
2010-07-04 Werner Lemberg <wl@gnu.org> 2010-07-04 Werner Lemberg <wl@gnu.org>
TrueType hinting is no longer patented. TrueType hinting is no longer patented.

View File

@ -692,6 +692,27 @@ FT_BEGIN_HEADER
#define FT_CONFIG_OPTION_OLD_INTERNALS #define FT_CONFIG_OPTION_OLD_INTERNALS
/*
* To detect legacy cache-lookup call from a rogue client (<= 2.1.7),
* we restrict the number of charmaps in a font. The current API of
* FTC_CMapCache_Lookup() takes cmap_index & charcode, but old API
* takes charcode only. To determine the passed value is for cmap_index
* or charcode, the possible cmap_index is restricted not to exceed
* the minimum possible charcode by a rogue client. It is also very
* unlikely that a rogue client is interested in Unicode values 0 to 15.
*
* NOTE: The original threshold was 4 deduced from popular number of
* cmap subtables in UCS-4 TrueType fonts, but now it is not
* irregular for OpenType fonts to have more than 4 subtables,
* because variation selector subtables are available for Apple
* and Microsoft platforms.
*/
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
#define FT_MAX_CHARMAP_CACHEABLE 15
#endif
/* /*
* This macro is defined if either unpatented or native TrueType * This macro is defined if either unpatented or native TrueType
* hinting is requested by the definitions above. * hinting is requested by the definitions above.

View File

@ -991,6 +991,14 @@
( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) )
{ {
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found "
"at too late position (%d)\n", cur - first ));
continue;
}
#endif
face->charmap = cur[0]; face->charmap = cur[0];
return FT_Err_Ok; return FT_Err_Ok;
} }
@ -1005,6 +1013,14 @@
{ {
if ( cur[0]->encoding == FT_ENCODING_UNICODE ) if ( cur[0]->encoding == FT_ENCODING_UNICODE )
{ {
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found "
"at too late position (%d)\n", cur - first ));
continue;
}
#endif
face->charmap = cur[0]; face->charmap = cur[0];
return FT_Err_Ok; return FT_Err_Ok;
} }
@ -1046,6 +1062,14 @@
if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
FT_Get_CMap_Format( cur[0] ) == 14 ) FT_Get_CMap_Format( cur[0] ) == 14 )
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "find_unicode_charmap: UVS cmap is found "
"at too late position (%d)\n", cur - first ));
continue;
}
#endif
return cur[0]; return cur[0];
} }
@ -2922,6 +2946,15 @@
{ {
if ( cur[0]->encoding == encoding ) if ( cur[0]->encoding == encoding )
{ {
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), "
"but in too late position to cache\n",
cur - face->charmaps ));
continue;
}
#endif
face->charmap = cur[0]; face->charmap = cur[0];
return 0; return 0;
} }
@ -2956,6 +2989,15 @@
{ {
if ( cur[0] == charmap ) if ( cur[0] == charmap )
{ {
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), "
"but in too late position to cache\n",
cur - face->charmaps ));
continue;
}
#endif
face->charmap = cur[0]; face->charmap = cur[0];
return 0; return 0;
} }
@ -2981,6 +3023,15 @@
FT_ASSERT( i < charmap->face->num_charmaps ); FT_ASSERT( i < charmap->face->num_charmaps );
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( i > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), "
"but in too late position to cache\n",
i ));
return -i;
}
#endif
return i; return i;
} }

24
src/cache/ftccmap.c vendored
View File

@ -310,19 +310,11 @@
#ifdef FT_CONFIG_OPTION_OLD_INTERNALS #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
/* /*
* Detect a call from a rogue client that thinks it is linking * If cmap_index is greater than the maximum number of cachable
* to FreeType 2.1.7. This is possible because the third parameter * charmaps, we assume the request is from a legacy rogue client
* is then a character code, and we have never seen any font with * using old internal header. See include/config/ftoption.h.
* more than a few charmaps, so if the index is very large...
*
* It is also very unlikely that a rogue client is interested
* in Unicode values 0 to 15.
*
* NOTE: The original threshold was 4, but we found a font from the
* Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf',
* which contains more than 5 charmaps.
*/ */
if ( cmap_index >= 16 && !no_cmap_change ) if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change )
{ {
FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id; FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id;
@ -384,7 +376,7 @@
/* something rotten can happen with rogue clients */ /* something rotten can happen with rogue clients */
if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
FTC_CMAP_INDICES_MAX ) ) FTC_CMAP_INDICES_MAX ) )
return 0; return 0; /* XXX: should return appropriate error */
gindex = FTC_CMAP_NODE( node )->indices[char_code - gindex = FTC_CMAP_NODE( node )->indices[char_code -
FTC_CMAP_NODE( node )->first]; FTC_CMAP_NODE( node )->first];
@ -401,6 +393,12 @@
if ( error ) if ( error )
goto Exit; goto Exit;
#ifdef FT_MAX_CHARMAP_CACHEABLE
/* something rotten can happen with rogue clients */
if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE )
return 0; /* XXX: should return appropriate error */
#endif
if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
{ {
FT_CharMap old, cmap = NULL; FT_CharMap old, cmap = NULL;

View File

@ -879,6 +879,16 @@
if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
goto Exit; goto Exit;
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "cff_face_init: no Unicode cmap is found, "
"and too many subtables (%d) to add synthesized cmap\n",
nn ));
goto Exit;
}
#endif
/* we didn't find a Unicode charmap -- synthesize one */ /* we didn't find a Unicode charmap -- synthesize one */
cmaprec.face = cffface; cmaprec.face = cffface;
cmaprec.platform_id = 3; cmaprec.platform_id = 3;
@ -897,6 +907,15 @@
cffface->charmap = cffface->charmaps[nn]; cffface->charmap = cffface->charmaps[nn];
Skip_Unicode: Skip_Unicode:
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( nn > FT_MAX_CHARMAP_CACHEABLE )
{
FT_ERROR(( "cff_face_init: Unicode cmap is found, "
"but too many preceding subtables (%d) to access\n",
nn - 1 ));
goto Exit;
}
#endif
if ( encoding->count > 0 ) if ( encoding->count > 0 )
{ {
FT_CMap_Class clazz; FT_CMap_Class clazz;

View File

@ -3411,6 +3411,12 @@
} }
num_cmaps = TT_NEXT_USHORT( p ); num_cmaps = TT_NEXT_USHORT( p );
#ifdef FT_MAX_CHARMAP_CACHEABLE
if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE )
FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables(%d) "
"subtable#%d and later are loaded but cannot be searched\n",
num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 ));
#endif
for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
{ {