Commit 4c531460ed677d9aaa06f79de160bfe3d03d9b3c

suzuki toshiya 2009-07-08T14:26:51

Prevent the overflows by a glyph with too many points or contours.

diff --git a/ChangeLog b/ChangeLog
index 94cc9a5..45ce49c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2009-07-08  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
+
+	Prevent the overflows by a glyph with too many points or contours.
+	The bug is reported by Boris Letocha <b.letocha@gmc.net>. 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  <bramt@enfocus.be>
 
 	Improve compatibility to Acroread.
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index 171f1b3..2fcc113 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 548481a..ce4dc6c 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_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_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 || ((_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 ab52621..ac0010d 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;