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) <Fail>: Behave correctly if `node' is NULL.
(FT_Destroy_Module) <Fail>: Check that `renderer_clazz' is valid.
This commit is contained in:
Andrew Church 2013-06-18 09:35:34 +02:00 committed by Werner Lemberg
parent d7e3444b8a
commit 67cf7a8841
3 changed files with 33 additions and 10 deletions

View File

@ -1,4 +1,23 @@
2013-06-14 Werner Lemberg <wl@gnu.org>. 2013-06-18 Andrew Church <achurch+savannah@achurch.org>
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) <Fail>: Behave correctly if `node' is NULL.
(FT_Destroy_Module) <Fail>: Check that `renderer_clazz' is valid.
2013-06-14 Werner Lemberg <wl@gnu.org>
* src/smooth/ftgrays.c One final pragma to silence 64-bit MSVC. * 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 * src/cff/cffgload.c (cff_slot_load): If we get
FT_Err_Glyph_Too_Big, retry unhinted and scale up later on. FT_Err_Glyph_Too_Big, retry unhinted and scale up later on.
2013-06-12 Werner Lemberg <wl@gnu.org>. 2013-06-12 Werner Lemberg <wl@gnu.org>
Another try on pragmas. Another try on pragmas.

View File

@ -363,7 +363,7 @@ FT_BEGIN_HEADER
#endif #endif
FT_Bool ignore_unpatented_hinter; FT_Bool ignore_unpatented_hinter;
FT_UInt refcount; FT_Int refcount;
} FT_Face_InternalRec; } FT_Face_InternalRec;
@ -883,7 +883,7 @@ FT_BEGIN_HEADER
FT_PIC_Container pic_container; FT_PIC_Container pic_container;
#endif #endif
FT_UInt refcount; FT_Int refcount;
} FT_LibraryRec; } FT_LibraryRec;

View File

@ -1153,15 +1153,15 @@
if ( FT_ALLOC( face, clazz->face_object_size ) ) if ( FT_ALLOC( face, clazz->face_object_size ) )
goto Fail; goto Fail;
face->driver = driver;
face->memory = memory;
face->stream = stream;
if ( FT_NEW( internal ) ) if ( FT_NEW( internal ) )
goto Fail; goto Fail;
face->internal = internal; face->internal = internal;
face->driver = driver;
face->memory = memory;
face->stream = stream;
#ifdef FT_CONFIG_OPTION_INCREMENTAL #ifdef FT_CONFIG_OPTION_INCREMENTAL
{ {
int i; int i;
@ -2265,7 +2265,10 @@
goto Exit; goto Exit;
Fail: 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: Exit:
FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
@ -4308,7 +4311,8 @@
FT_Renderer renderer = FT_RENDERER( module ); 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->raster )
renderer->clazz->raster_class->raster_done( renderer->raster ); renderer->clazz->raster_class->raster_done( renderer->raster );
} }