diff --git a/ChangeLog b/ChangeLog index 94cc9a51b..45ce49cf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2009-07-08 suzuki toshiya + + Prevent the overflows by a glyph with too many points or contours. + The bug is reported by Boris Letocha . See + http://lists.nongnu.org/archive/html/freetype-devel/2009-06/msg00031.html + http://lists.nongnu.org/archive/html/freetype-devel/2009-07/msg00002.html + + * include/freetype/ftimage.h (FT_OUTLINE_CONTOURS_MAX, + FT_OUTLINE_POINTS_MAX): New macros to declare the maximum + values of FT_Outline.{n_contours,n_points}. + * src/base/ftgloadr.c (FT_GlyphLoader_CheckPoints): Check the + total numbers of points and contours cause no overflows in + FT_Outline.{n_contours,n_points}. + + * include/freetype/internal/ftgloadr.h (FT_GLYPHLOADER_CHECK_P, + FT_GLYPHLOADER_CHECK_C): Compare the numbers of points and + contours as unsigned long number, instead of signed int, to + prevent the overflows on 16-bit systems. + 2009-07-05 Bram Tassyns Improve compatibility to Acroread. diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index 171f1b3a2..2fcc113ad 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h @@ -364,6 +364,11 @@ FT_BEGIN_HEADER } FT_Outline; + /* Following limits must be consistent with */ + /* FT_Outline.{n_contours,n_points} */ +#define FT_OUTLINE_CONTOURS_MAX SHRT_MAX +#define FT_OUTLINE_POINTS_MAX SHRT_MAX + /*************************************************************************/ /* */ diff --git a/include/freetype/internal/ftgloadr.h b/include/freetype/internal/ftgloadr.h index 548481ac8..ce4dc6c9c 100644 --- a/include/freetype/internal/ftgloadr.h +++ b/include/freetype/internal/ftgloadr.h @@ -121,15 +121,15 @@ FT_BEGIN_HEADER FT_UInt n_contours ); -#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_points + \ - (_loader)->current.outline.n_points + \ - (_count)) <= (int)(_loader)->max_points ) +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_points + \ + (_loader)->current.outline.n_points + \ + (unsigned long)(_count)) <= (_loader)->max_points ) -#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ - ( (_count) == 0 || (int)((_loader)->base.outline.n_contours + \ - (_loader)->current.outline.n_contours + \ - (_count)) <= (int)(_loader)->max_contours ) +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || ((_loader)->base.outline.n_contours + \ + (_loader)->current.outline.n_contours + \ + (unsigned long)(_count)) <= (_loader)->max_contours ) #define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c index ab52621ea..ac0010ddd 100644 --- a/src/base/ftgloadr.c +++ b/src/base/ftgloadr.c @@ -218,6 +218,9 @@ { new_max = FT_PAD_CEIL( new_max, 8 ); + if ( new_max > FT_OUTLINE_POINTS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) goto Exit; @@ -246,6 +249,10 @@ if ( new_max > old_max ) { new_max = FT_PAD_CEIL( new_max, 4 ); + + if ( new_max > FT_OUTLINE_CONTOURS_MAX ) + return FT_Err_Array_Too_Large; + if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) goto Exit;