ref: e866cf3f5537cfb03cfb87e3e607f13f41f5d299
parent: d3ed6d1bba27aaae4774db957a82caa6d5b67632
author: suzuki toshiya <[email protected]>
date: Fri Jul 31 20:32:06 EDT 2009
Improve bitmap size or pixel variables for 16-bit systems.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,63 @@
2009-07-31 suzuki toshiya <[email protected]>
+ Improve bitmap size or pixel variables for 16-bit systems.
+
+ * include/freetype/config/ftstdlib.h: Introduce
+ FT_INT_MIN, to use in signed integer overflow in
+ 16-bit and 64-bit platforms.
+
+ * include/freetype/internal/fttrace.h: Add a tracer
+ to ftsynth.c.
+
+ * src/base/ftbitmap.c (FT_Bitmap_Embolden): Check
+ invalid strength causing integer overflow on 16-bit
+ platform.
+
+ * src/base/ftcalc.c (ft_corner_orientation): Change
+ the internal calculation from FT_Int to FT_Long, to
+ avoid an overflow on 16-bit platforms. The caller of
+ this function should use only the sign of result,
+ so the cast to FT_Int is acceptable.
+
+ * src/base/ftsynth.c: Introduce a tracer for synth module.
+ (FT_GlyphSlot_Embolden): Check invalid strength causing
+ integer overflow on 16-bit platform.
+
+ * src/bdf/bdfdrivr.c (BDF_Face_Init): The glyph index
+ in FT2 API is typed as FT_UInt, although BDF driver
+ can handle unsigned long glyph index internally. To
+ avoid integer overflow on 16-bit platform, too large
+ glyph index should be excluded.
+ (BDF_Glyph_Load): The glyph pitch in FT2 is typed as
+ FT_UInt, although BDF driver can handle unsigned long
+ glyph pitch internally. To avoid integer overflow on
+ 16-bit platform, too large glyph pitch should not be
+ returned.
+
+ * src/pfr/pfrsbit.c (pfr_slot_load_bitmap): The glyph
+ pitch in FT2 is typed as FT_UInt, although PFR font
+ format can include huge bitmap glyph with 24-bit pitch
+ (however, a glyph spends 16.7 pixel, it's not realistic).
+ To avoid integer overflow on 16-bit platform, huge
+ bitmap glyph should be excluded.
+
+ * src/smooth/ftgrays.c (gray_hline): As FT_Span.x is
+ truncated to fit its type (16-bit short), FT_Span.y
+ should be truncated to fit its type (FT_Int).
+
+ * src/cff/cffdrivr.c (cff_get_ros): CFF specification
+ defines the supplement in ROS as a real number.
+ Truncate it to fit public FT2 API.
+
+ * src/cff/cffparse.c (cff_parse_cid_ros): Warn the
+ supplement if it is truncated or rounded in cff_get_ros().
+
+ * src/cff/cfftypes.h: Change the type of internal variable
+ `supplement' from FT_Long to FT_ULong to fit the signedness
+ to the type in public API.
+
+2009-07-31 suzuki toshiya <[email protected]>
+
psaux: Prevent invalid arguments to afm_parser_read_vals().
* src/psaux/afmparse.c (afm_parser_read_vals): Change
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -61,6 +61,7 @@
#define FT_CHAR_BIT CHAR_BIT
#define FT_INT_MAX INT_MAX
+#define FT_INT_MIN INT_MIN
#define FT_UINT_MAX UINT_MAX
#define FT_ULONG_MAX ULONG_MAX
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -37,6 +37,7 @@
FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */
FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */
FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */
+FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */
/* Cache sub-system */
FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -228,8 +228,12 @@
if ( !bitmap || !bitmap->buffer )
return FT_Err_Invalid_Argument;
- xstr = FT_PIX_ROUND( xStrength ) >> 6;
- ystr = FT_PIX_ROUND( yStrength ) >> 6;
+ if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
+ ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
+ return FT_Err_Invalid_Argument;
+
+ xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
+ ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
if ( xstr == 0 && ystr == 0 )
return FT_Err_Ok;
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -842,7 +842,7 @@
FT_Pos out_x,
FT_Pos out_y )
{
- FT_Int result;
+ FT_Long result; /* avoid overflow on 16-bit system */
/* deal with the trivial cases quickly */
@@ -909,7 +909,8 @@
#endif
}
- return result;
+ /* XXX: only the sign of return value, +1/0/-1 must be used */
+ return (FT_Int)result;
}
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -18,6 +18,7 @@
#include <ft2build.h>
#include FT_SYNTHESIS_H
+#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
#include FT_OUTLINE_H
#include FT_BITMAP_H
@@ -24,7 +25,16 @@
/*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_synth
+
/*************************************************************************/
+ /*************************************************************************/
/**** ****/
/**** EXPERIMENTAL OBLIQUING SUPPORT ****/
/**** ****/
@@ -106,6 +116,18 @@
xstr = 1 << 6;
ystr &= ~63;
+ /*
+ * XXX: overflow check for 16-bit system, for compatibility
+ * with FT_GlyphSlot_Embolden() since freetype-2.1.10.
+ * unfortunately, this function return no informations
+ * about the cause of error.
+ */
+ if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )
+ {
+ FT_TRACE1(( "FT_GlyphSlot_Embolden:" ));
+ FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr ));
+ return;
+ }
error = FT_GlyphSlot_Own_Bitmap( slot );
if ( error )
return;
@@ -129,8 +151,9 @@
slot->metrics.vertBearingY += ystr;
slot->metrics.vertAdvance += ystr;
+ /* XXX: 16-bit overflow case must be excluded before here */
if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
- slot->bitmap_top += ystr >> 6;
+ slot->bitmap_top += (FT_Int)( ystr >> 6 );
}
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -485,7 +485,12 @@
(face->en_table[n]).glyph = (FT_Short)n;
if ( cur[n].encoding == font->default_char )
- face->default_glyph = n;
+ {
+ if ( n < FT_UINT_MAX )
+ face->default_glyph = (FT_UInt)n;
+ else
+ FT_TRACE1(( "idx %d is too large for this system\n", n ));
+ }
}
}
@@ -677,7 +682,10 @@
bitmap->rows = glyph.bbx.height;
bitmap->width = glyph.bbx.width;
- bitmap->pitch = glyph.bpr;
+ if ( glyph.bpr > INT_MAX )
+ FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n",
+ glyph.bpr ));
+ bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */
/* note: we don't allocate a new array to hold the bitmap; */
/* we can simply point to it */
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -495,8 +495,19 @@
*ordering = cff->ordering;
}
+ /*
+ * XXX: According to Adobe TechNote #5176, the supplement in CFF
+ * can be a real number. We truncate it to fit public API
+ * since freetype-2.3.6.
+ */
if ( supplement )
- *supplement = dict->cid_supplement;
+ {
+ if ( dict->cid_supplement < FT_INT_MIN ||
+ dict->cid_supplement > FT_INT_MAX )
+ FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
+ dict->cid_supplement ));
+ *supplement = (FT_Int)dict->cid_supplement;
+ }
}
Fail:
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -554,7 +554,12 @@
{
dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
- dict->cid_supplement = (FT_ULong)cff_parse_num( data );
+ if ( **data == 30 )
+ FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
+ dict->cid_supplement = cff_parse_num( data );
+ if ( dict->cid_supplement < 0 )
+ FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
+ dict->cid_supplement ));
error = CFF_Err_Ok;
}
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -130,7 +130,7 @@
/* these should only be used for the top-level font dictionary */
FT_UInt cid_registry;
FT_UInt cid_ordering;
- FT_ULong cid_supplement;
+ FT_Long cid_supplement;
FT_Long cid_font_version;
FT_Long cid_font_revision;
--- a/src/pfr/pfrsbit.c
+++ b/src/pfr/pfrsbit.c
@@ -630,18 +630,35 @@
&xpos, &ypos,
&xsize, &ysize,
&advance, &format );
+
+ /*
+ * XXX: on 16bit system, we return an error for huge bitmap
+ * which causes a size truncation, because truncated
+ * size properties makes bitmap glyph broken.
+ */
+ if ( xpos > FT_INT_MAX || ( ypos + ysize ) > FT_INT_MAX )
+ {
+ FT_TRACE1(( "pfr_slot_load_bitmap:" ));
+ FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n",
+ xpos, ypos ));
+ error = PFR_Err_Invalid_Pixel_Size;
+ }
+
if ( !error )
{
glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
/* Set up glyph bitmap and metrics */
+
+ /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */
glyph->root.bitmap.width = (FT_Int)xsize;
glyph->root.bitmap.rows = (FT_Int)ysize;
- glyph->root.bitmap.pitch = (FT_Long)( xsize + 7 ) >> 3;
+ glyph->root.bitmap.pitch = (FT_Int)( xsize + 7 ) >> 3;
glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
- glyph->root.metrics.width = (FT_Long)xsize << 6;
- glyph->root.metrics.height = (FT_Long)ysize << 6;
+ /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */
+ glyph->root.metrics.width = (FT_Pos)xsize << 6;
+ glyph->root.metrics.height = (FT_Pos)ysize << 6;
glyph->root.metrics.horiBearingX = xpos << 6;
glyph->root.metrics.horiBearingY = ypos << 6;
glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) );
@@ -649,8 +666,9 @@
glyph->root.metrics.vertBearingY = 0;
glyph->root.metrics.vertAdvance = size->root.metrics.height;
- glyph->root.bitmap_left = xpos;
- glyph->root.bitmap_top = ypos + ysize;
+ /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */
+ glyph->root.bitmap_left = (FT_Int)xpos;
+ glyph->root.bitmap_top = (FT_Int)(ypos + ysize);
/* Allocate and read bitmap data */
{
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -1271,6 +1271,10 @@
if ( x >= 32767 )
x = 32767;
+ /* FT_Span.y is an integer, so limit our coordinates appropriately */
+ if ( y >= FT_INT_MAX )
+ y = FT_INT_MAX;
+
if ( coverage )
{
/* see whether we can add this span to the current list */
@@ -1309,7 +1313,7 @@
#endif /* FT_DEBUG_LEVEL_TRACE */
ras.num_gray_spans = 0;
- ras.span_y = y;
+ ras.span_y = (int)y;
count = 0;
span = ras.gray_spans;
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -321,12 +321,19 @@
FT_Outline_Translate( outline, x_shift, y_shift );
+ /*
+ * XXX: on 16bit system, we return an error for huge bitmap
+ * to prevent an overflow.
+ */
+ if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )
+ return Smooth_Err_Invalid_Pixel_Size;
+
if ( error )
goto Exit;
slot->format = FT_GLYPH_FORMAT_BITMAP;
- slot->bitmap_left = x_left;
- slot->bitmap_top = y_top;
+ slot->bitmap_left = (FT_Int)x_left;
+ slot->bitmap_top = (FT_Int)y_top;
Exit:
if ( outline && origin )