[gs-cvs] rev 8200 - trunk/gs/src

mpsuzuki at ghostscript.com mpsuzuki at ghostscript.com
Tue Aug 21 23:38:36 PDT 2007


Author: mpsuzuki
Date: 2007-08-21 23:38:36 -0700 (Tue, 21 Aug 2007)
New Revision: 8200

Modified:
   trunk/gs/src/gstype42.c
Log:
Fix (TT fonts) : Ignore invalid entries in loca table.

DETAILS : 

Some problematic TrueType fonts have loca table that
the offset to a data in glyf table is larger than
the size of glyf table. In previous implementation
since trunk revision 5707 (ghostscript-8.57), when
such invalid entry is found, the font loading procedure
is immediately aborted and invalid font error is
returned. To continue the problematic TrueType object,
the invalid entries of loca tables now are ignored and
the font loading procedure is continued. If all entries
are invalid, the invalid font error is returned.

After the sorting of loca table entries by their values,
the invalid entries with too large offsets are collected
in the end of the sorted loca entries (psortary[]).
By this patch, the sorted loca entries are scanned from
from the end to the beginning, and the number of valid
entry is counted (num_valid_loca_elm). By this number,
the invalid loca entries are initialized to have null
glyph (the data size of glyph is set to 0).

By this patch, bug 689347 is fixed.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gstype42.c
===================================================================
--- trunk/gs/src/gstype42.c	2007-08-21 22:26:58 UTC (rev 8199)
+++ trunk/gs/src/gstype42.c	2007-08-22 06:38:36 UTC (rev 8200)
@@ -289,6 +289,7 @@
 	 * It assumes no overlapping and no duplicate glyphs.
 	 */
 	ulong last_glyph_offset = glyph_size;
+	ulong num_valid_loca_elm = loca_size;
 	gs_type42_font_init_sort_t *psort;
 	gs_type42_font_init_sort_t *psortary = 
 	    (gs_type42_font_init_sort_t *)gs_alloc_byte_array(pfont->memory, 
@@ -301,13 +302,19 @@
 	    psort->glyph_offset = get_glyph_offset(pfont, i);
 	    }
 	qsort(psortary, loca_size, sizeof(gs_type42_font_init_sort_t), gs_type42_font_init_compare);
-	if (psortary[loca_size - 1].glyph_offset > glyph_size)
+	while (num_valid_loca_elm > 0 && psortary[num_valid_loca_elm - 1].glyph_offset > glyph_size)
+	    num_valid_loca_elm --;
+	if (0 == num_valid_loca_elm)
 	    return_error(gs_error_invalidfont);
-	for (i = loca_size; i--;) {
+	for (i = num_valid_loca_elm; i--;) {
 	    psort = psortary + i;
 	    pfont->data.len_glyphs[psort->glyph_num] = last_glyph_offset - psort->glyph_offset;
 	    last_glyph_offset = psort->glyph_offset;
 	}
+	for (i = num_valid_loca_elm; i < loca_size; i++) {
+	    psort = psortary + i;
+	    pfont->data.len_glyphs[psort->glyph_num] = 0;
+	}
 	/* Well the last element of len_glyphs is never used.
 	   We compute it because we're interesting whether it is not zero sometimes. 
 	   To know that, set a conditional breakpoint at the next statement.



More information about the gs-cvs mailing list