Improve bitmap size or pixel variables for 16-bit systems.

This commit is contained in:
suzuki toshiya 2009-08-01 00:32:06 +09:00
parent d3ed6d1bba
commit e866cf3f55
13 changed files with 159 additions and 18 deletions

View File

@ -1,3 +1,61 @@
2009-07-31 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
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 <mpsuzuki@hiroshima-u.ac.jp>
psaux: Prevent invalid arguments to afm_parser_read_vals().

View File

@ -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

View File

@ -37,6 +37,7 @@ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */
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.) */

View File

@ -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;

View File

@ -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;
}

View File

@ -18,11 +18,21 @@
#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
/*************************************************************************/
/* */
/* 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
/*************************************************************************/
/*************************************************************************/
/**** ****/
@ -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 );
}

View File

@ -485,7 +485,12 @@ THE SOFTWARE.
(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 @@ THE SOFTWARE.
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 */

View File

@ -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:

View File

@ -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;
}

View File

@ -130,7 +130,7 @@ FT_BEGIN_HEADER
/* 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;

View File

@ -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 */
{

View File

@ -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;

View File

@ -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 )