diff --git a/ChangeLog b/ChangeLog index 9e9297b02..51c884e78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,23 @@ -2013-06-14 Werner Lemberg . +2013-06-18 Andrew Church + + Fix Savannah bug #39266. + + If memory allocations fail at certain points while opening a font, + FreeType can either crash due to a NULL dereference or leak memory. + + * include/freetype/internal/ftobjs.c (FT_Face_InternalRec, + FT_LibraryRec): Make `refcount' a signed integer. If, for example, + FT_Open_Face() fails in a memory allocation before the face's + reference count is set to 1, a subsequent `FT_Done_Library' call + would otherwise loop over `FT_Done_Face' 2^32 times before freeing + the face. + + * src/base/ftobjs.c (open_face): Initialize `stream' and friends + earlier. + (FT_Open_Face) : Behave correctly if `node' is NULL. + (FT_Destroy_Module) : Check that `renderer_clazz' is valid. + +2013-06-14 Werner Lemberg * src/smooth/ftgrays.c One final pragma to silence 64-bit MSVC. @@ -10,7 +29,7 @@ * src/cff/cffgload.c (cff_slot_load): If we get FT_Err_Glyph_Too_Big, retry unhinted and scale up later on. -2013-06-12 Werner Lemberg . +2013-06-12 Werner Lemberg Another try on pragmas. diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 8a309b8d9..701c850eb 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -363,7 +363,7 @@ FT_BEGIN_HEADER #endif FT_Bool ignore_unpatented_hinter; - FT_UInt refcount; + FT_Int refcount; } FT_Face_InternalRec; @@ -883,7 +883,7 @@ FT_BEGIN_HEADER FT_PIC_Container pic_container; #endif - FT_UInt refcount; + FT_Int refcount; } FT_LibraryRec; diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index d6b2126be..e9a2981b4 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -1153,15 +1153,15 @@ if ( FT_ALLOC( face, clazz->face_object_size ) ) goto Fail; + face->driver = driver; + face->memory = memory; + face->stream = stream; + if ( FT_NEW( internal ) ) goto Fail; face->internal = internal; - face->driver = driver; - face->memory = memory; - face->stream = stream; - #ifdef FT_CONFIG_OPTION_INCREMENTAL { int i; @@ -2265,7 +2265,10 @@ goto Exit; Fail: - FT_Done_Face( face ); + if ( node ) + FT_Done_Face( face ); /* face must be in the driver's list */ + else if ( face ) + destroy_face( memory, face, driver ); Exit: FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); @@ -4308,7 +4311,8 @@ FT_Renderer renderer = FT_RENDERER( module ); - if ( renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && + if ( renderer->clazz && + renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && renderer->raster ) renderer->clazz->raster_class->raster_done( renderer->raster ); }