diff --git a/src/gf/gfdrivr.c b/src/gf/gfdrivr.c index c28b42bc5..de156c4c4 100644 --- a/src/gf/gfdrivr.c +++ b/src/gf/gfdrivr.c @@ -143,7 +143,6 @@ memory = FT_FACE_MEMORY( face ); gf_free_font( gfface, memory ); - /* FT_FREE( ); */ } @@ -158,19 +157,47 @@ FT_Error error; FT_Memory memory = FT_FACE_MEMORY( face ); GF_Glyph go; - int i,count; + FT_UInt16 i,count; FT_UNUSED( num_params ); FT_UNUSED( params ); go=NULL; + FT_TRACE2(( "GF driver\n" )); /* load font */ error = gf_load_font( stream, memory, &go ); - if ( error ) + if ( FT_ERR_EQ( error, Unknown_File_Format ) ) + { + FT_TRACE2(( " not a GF file\n" )); + goto Fail; + } + else if ( error ) goto Exit; face->gf_glyph = go ; + + /* sanity check */ + if ( !face->gf_glyph->bm_table ) + { + FT_TRACE2(( "glyph bitmaps not allocated\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + /* GF cannot have multiple faces in a single font file. + * XXX: non-zero face_index is already invalid argument, but + * Type1, Type42 driver has a convention to return + * an invalid argument error when the font could be + * opened by the specified driver. + */ + if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + { + FT_ERROR(( "GF_Face_Init: invalid face index\n" )); + GF_Face_Done( gfface ); + return FT_THROW( Invalid_Argument ); + } + /* we now need to fill the root FT_Face fields */ /* with relevant information */ @@ -182,6 +209,7 @@ * XXX: TO-DO: gfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; * XXX: I have to check for this. */ + gfface->family_name = NULL; count=0; for (i = 0; i < 256; i++) @@ -189,9 +217,18 @@ if(go->bm_table[i].bitmap != NULL) count++; } - gfface->num_glyphs = (FT_Long)count;printf("count is %d", count); + gfface->num_glyphs = (FT_Long)count; + FT_TRACE4(( " number of glyphs: allocated %d\n",gfface->num_glyphs)); + if ( gfface->num_glyphs <= 0 ) + { + FT_ERROR(( "GF_Face_Init: glyphs not allocated\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + + gfface->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( gfface->available_sizes, 1 ) ) goto Exit; @@ -200,32 +237,36 @@ bsize->width = (FT_Short) face->gf_glyph->font_bbx_w ; bsize->height = (FT_Short) face->gf_glyph->font_bbx_h ; - bsize->size = (FT_Short) face->gf_glyph->ds ; /* Preliminary to be checked for 26.6 fractional points*/ + bsize->size = (FT_Pos) face->gf_glyph->ds ; /* Preliminary to be checked for 26.6 fractional points*/ /*x_res = ; To be Checked for x_resolution and y_resolution y_res = ;*/ - bsize->y_ppem = face->gf_glyph->font_bbx_yoff ; - bsize->x_ppem = face->gf_glyph->font_bbx_xoff ; + bsize->y_ppem = (FT_Pos)face->gf_glyph->font_bbx_yoff ; + bsize->x_ppem = (FT_Pos)face->gf_glyph->font_bbx_xoff ; } - /* Charmaps */ - - { - FT_CharMapRec charmap; - + /* Charmaps */ + { + FT_CharMapRec charmap; - charmap.encoding = FT_ENCODING_NONE; - /* initial platform/encoding should indicate unset status? */ - charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; /*Preliminary */ - charmap.encoding_id = TT_APPLE_ID_DEFAULT; - charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; + /* initial platform/encoding should indicate unset status? */ + charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; /*Preliminary */ + charmap.encoding_id = TT_APPLE_ID_DEFAULT; + charmap.face = FT_FACE( face ); - error = FT_CMap_New( &gf_cmap_class, NULL, &charmap, NULL ); + error = FT_CMap_New( &gf_cmap_class, NULL, &charmap, NULL ); - if ( error ) - goto Fail; - } + if ( error ) + goto Fail; + } + if ( go->code_max < go->code_min ) + { + FT_TRACE2(( "invalid number of glyphs\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } Fail: GF_Face_Done( gfface ); @@ -315,7 +356,8 @@ goto Exit; } - if ( glyph_index >= (FT_UInt)face->num_glyphs ) + if ( !go || + glyph_index >= (FT_UInt)( face->num_glyphs ) ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -328,15 +370,31 @@ if ((glyph_index < go->code_min) || (go->code_max < glyph_index)) { + FT_TRACE2(( "invalid glyph index\n" )); error = FT_THROW( Invalid_Argument ); goto Exit; } + if ( !go->bm_table ) + { + FT_TRACE2(( "invalid bitmap table\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + /* slot, bitmap => freetype, glyph => gflib */ bm = gf->gf_glyph->bm_table[glyph_index]; bitmap->rows = bm.mv_y ; /* Prelimiary */ bitmap->width = bm.mv_x ; /* Prelimiary */ + + if ( !bm.raster ) + { + FT_TRACE2(( "invalid bitmap width\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + bitmap->pitch = bm.raster ; /* Prelimiary */ /* note: we don't allocate a new array to hold the bitmap; */ diff --git a/src/gf/gflib.c b/src/gf/gflib.c index 95d9fad38..c97c1900a 100644 --- a/src/gf/gflib.c +++ b/src/gf/gflib.c @@ -155,6 +155,7 @@ unsigned char bit_table[] = { h = max_n - min_n + 1; if ((w < 0) || (h < 0)) { + FT_ERROR(( "gf_read_glyph: invalid w and h values\n" )); error = FT_THROW( Invalid_File_Format ); return -1; } @@ -289,75 +290,89 @@ unsigned char bit_table[] = { /* seek to post_post instr. */ /* fseek(fp, -1, SEEK_END); */ if( FT_STREAM_SEEK( stream->size - 1 ) ) - goto ErrExit; + goto Exit; if( FT_STREAM_SEEK( stream->size - 1 ) ) - goto ErrExit; + goto Exit; while ( READ_UINT1( stream ) == 223) { if( FT_STREAM_SEEK( stream->pos -2 ) ) - goto ErrExit; + goto Exit; /* fseek(fp, -2, SEEK_CUR); */ } if( FT_STREAM_SEEK( stream->pos -1 ) ) - goto ErrExit; + goto Exit; d= READ_UINT1( stream ); if (d != GF_ID) { + FT_ERROR(( "gf_load_font: missing GF_ID(131) field\n" )); error = FT_THROW( Invalid_File_Format ); - goto ErrExit; + goto Exit; } + FT_TRACE2(( "gf_load_font: GF_ID(131) found " )); + /* fseek(fp, -6, SEEK_CUR); */ if(FT_STREAM_SEEK( stream->pos -6 )) - goto ErrExit; + goto Exit; /* check if the code is post_post */ if (READ_UINT1( stream ) != GF_POST_POST) { + FT_ERROR(( "gf_load_font: missing GF_POST_POST(249) field\n" )); error = FT_THROW( Invalid_File_Format ); - goto ErrExit; + goto Exit; } + FT_TRACE2(( "gf_load_font: GF_POST_POST(249) found\n" )); + /* read pointer to post instr. */ if(FT_READ_ULONG( ptr_post )) - goto ErrExit; + goto Exit; if (ptr_post == -1) { + FT_ERROR(( "gf_load_font: invalid postamble pointer\n" )); error = FT_THROW( Invalid_File_Format ); - goto ErrExit; + goto Exit; } /* goto post instr. and read it */ /* fseek(fp, ptr_post, SEEK_SET); */ if(FT_STREAM_SEEK( ptr_post )) - goto ErrExit; + goto Exit; if (READ_UINT1( stream ) != GF_POST) { + FT_ERROR(( "gf_load_font: missing GF_POST(248) field\n" )); error = FT_THROW( Invalid_File_Format ); - goto ErrExit; + goto Exit; } + FT_TRACE2(( "gf_load_font: GF Postamble found\n" ));FT_TRACE2(( "gf_load_font: GF Postamble found\n" )); if(FT_READ_ULONG( ptr_p )) - goto ErrExit; + goto Exit; if(FT_READ_ULONG( ds )) - goto ErrExit; + goto Exit; if(FT_READ_ULONG( check_sum )) - goto ErrExit; + goto Exit; if(FT_READ_ULONG( hppp )) - goto ErrExit; + goto Exit; if(FT_READ_ULONG( vppp )) - goto ErrExit; + goto Exit; min_m = READ_INT4( stream ); max_m = READ_INT4( stream ); min_n = READ_INT4( stream ); max_n = READ_INT4( stream ); + if( ptr_p < 0 ) + { + FT_ERROR(( "gf_load_font: invalid pointer in postamble\n" )); + goto Exit; + } #if 0 gptr = ftell(fp); #endif @@ -386,7 +401,7 @@ unsigned char bit_table[] = { else { error = FT_THROW( Invalid_File_Format ); - goto ErrExit; + goto Exit; } if (code < bc) bc = code; @@ -401,11 +416,13 @@ unsigned char bit_table[] = { nchars = ec - bc + 1; /*go= malloc(sizeof(GF_GlyphRec));*/ if( FT_ALLOC(go, sizeof(GF_GlyphRec)) ) - goto ErrExit; + goto Exit; /*go->bm_table = (GF_Bitmap)malloc(nchars* sizeof(GF_BitmapRec));*/ if( FT_ALLOC_MULT(go->bm_table, sizeof(GF_BitmapRec), nchars) ) - goto ErrExit; + goto Exit; + + FT_TRACE2(( "gf_load_font: Allocated bitmap table\n" )); for (i = 0; i < nchars; i++) go->bm_table[i].bitmap = NULL; @@ -446,41 +463,38 @@ unsigned char bit_table[] = { ptr = READ_INT4( stream ); break; default: + FT_ERROR(( "gf_load_font: missing character locators in postamble\n" )); error = FT_THROW( Invalid_File_Format ); - goto ErrExit; + goto Exit; } /* optr = ft_ftell(fp); */ optr = stream->pos; /* ft_fseek(fp, ptr, SEEK_SET); */ if( FT_STREAM_SEEK( ptr ) ) - goto ErrExit; + goto Exit; bm = &go->bm_table[code - bc]; if (gf_read_glyph( stream, bm, memory ) < 0) - goto ErrExit; + goto Exit; bm->mv_x = dx; bm->mv_y = dy; /* ft_fseek(fp, optr, SEEK_SET); */ if(FT_STREAM_SEEK( optr )) - goto ErrExit; + goto Exit; } *goptr = go; return error; - ErrExit: + Exit: printf("*ERROR\n"); if (go != NULL) { - if (go->bm_table != NULL) - { - for (i = 0; i < nchars; i++){} - /* FT_FREE(go->bm_table[i].bitmap); */ - } - /* FT_FREE(go->bm_table); */ + FT_FREE(go->bm_table); + FT_FREE(go); } - /* FT_FREE(go); */ + return error; } @@ -490,7 +504,11 @@ unsigned char bit_table[] = { GF_Face gf = (GF_Face)gfface; GF_Glyph go; go = gf->gf_glyph; - + if (go != NULL) + { + FT_FREE(go->bm_table); + FT_FREE(go); + } } diff --git a/src/gf/module.mk b/src/gf/module.mk index b64a9370d..1eb534671 100644 --- a/src/gf/module.mk +++ b/src/gf/module.mk @@ -16,7 +16,7 @@ FTMODULE_H_COMMANDS += GF_DRIVER define GF_DRIVER $(OPEN_DRIVER) FT_Driver_ClassRec, gf_driver_class $(CLOSE_DRIVER) -$(ECHO_DRIVER)gf $(ECHO_DRIVER_DESC)gf TeX's bitmap fonts$(ECHO_DRIVER_DONE) +$(ECHO_DRIVER)gf $(ECHO_DRIVER_DESC)METAFONT bitmap fonts$(ECHO_DRIVER_DONE) endef # EOF