summaryrefslogtreecommitdiffstats
path: root/src/truetype/ttpload.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-18 22:20:25 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-18 22:20:25 -0700
commit0a9d06e2b5cf75c3d6ba958026bfdf4745f576d6 (patch)
treebda73f0de3896a97ff4231e4600fccd89a3f9118 /src/truetype/ttpload.c
parent049d6fea481044fcc000e7782e5bc7046fc70844 (diff)
downloadandroid_external_freetype-0a9d06e2b5cf75c3d6ba958026bfdf4745f576d6.tar.gz
android_external_freetype-0a9d06e2b5cf75c3d6ba958026bfdf4745f576d6.tar.bz2
android_external_freetype-0a9d06e2b5cf75c3d6ba958026bfdf4745f576d6.zip
auto import //branches/master/...@140412
Diffstat (limited to 'src/truetype/ttpload.c')
-rw-r--r--src/truetype/ttpload.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index 9d3381b..dc538fb 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
/* */
/* TrueType-specific tables loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -65,11 +65,17 @@
{
FT_Error error;
FT_ULong table_len;
+ FT_Int shift;
/* we need the size of the `glyf' table for malformed `loca' tables */
error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
- if ( error )
+
+ /* it is possible that a font doesn't have a glyf table at all */
+ /* or its size is zero */
+ if ( error == TT_Err_Table_Missing )
+ face->glyf_len = 0;
+ else if ( error )
goto Exit;
FT_TRACE2(( "Locations " ));
@@ -82,23 +88,65 @@
if ( face->header.Index_To_Loc_Format != 0 )
{
+ shift = 2;
+
if ( table_len >= 0x40000L )
{
FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
- face->num_locations = (FT_UInt)( table_len >> 2 );
+ face->num_locations = (FT_UInt)( table_len >> shift );
}
else
{
+ shift = 1;
+
if ( table_len >= 0x20000L )
{
FT_TRACE2(( "table too large!\n" ));
error = TT_Err_Invalid_Table;
goto Exit;
}
- face->num_locations = (FT_UInt)( table_len >> 1 );
+ face->num_locations = (FT_UInt)( table_len >> shift );
+ }
+
+ if ( face->num_locations != (FT_UInt)face->root.num_glyphs )
+ {
+ FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
+ face->num_locations, face->root.num_glyphs ));
+
+ /* we only handle the case where `maxp' gives a larger value */
+ if ( face->num_locations < (FT_UInt)face->root.num_glyphs )
+ {
+ FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift;
+
+ TT_Table entry = face->dir_tables;
+ TT_Table limit = entry + face->num_tables;
+
+ FT_Long pos = FT_Stream_Pos( stream );
+ FT_Long dist = 0x7FFFFFFFL;
+
+
+ /* compute the distance to next table in font file */
+ for ( ; entry < limit; entry++ )
+ {
+ FT_Long diff = entry->Offset - pos;
+
+
+ if ( diff > 0 && diff < dist )
+ dist = diff;
+ }
+
+ if ( new_loca_len <= dist )
+ {
+ face->num_locations = (FT_Long)face->root.num_glyphs;
+ table_len = new_loca_len;
+
+ FT_TRACE2(( "adjusting num_locations to %d\n",
+ face->num_locations ));
+ }
+ }
}
/*
@@ -162,6 +210,9 @@
/* Anyway, there do exist (malformed) fonts which don't obey */
/* this rule, so we are only able to provide an upper bound for */
/* the size. */
+ /* */
+ /* We get (intentionally) a wrong, non-zero result in case the */
+ /* `glyf' table is missing. */
if ( pos2 >= pos1 )
*asize = (FT_UInt)( pos2 - pos1 );
else