From eaf0afb4c75e18d323b7b762ac0c5dd0a8e5202c Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sat, 20 Oct 2012 11:27:25 +0200 Subject: [PATCH] [psaux] Fix some value overflows and improve tracing. * src/psaux/psconv.c: Include FT_INTERNAL_DEBUG_H. (FT_COMPONENT): Define. (PS_Conv_Strtol): Return FT_Long. Handle bad data and overflow. Emit some tracing messages in case of error. (PS_Conv_ToInt): Return FT_Long. (PS_Conv_ToFixed): Updated. * src/psaux/psconv.h: Updated. * include/freetype/internal/fttrace.h: Add `psconv'. --- ChangeLog | 15 ++++++++ include/freetype/internal/fttrace.h | 1 + src/psaux/psconv.c | 56 +++++++++++++++++++++++------ src/psaux/psconv.h | 10 +++--- 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6aeca3d9..d6612c652 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2012-10-20 Werner Lemberg + + [psaux] Fix some value overflows and improve tracing. + + * src/psaux/psconv.c: Include FT_INTERNAL_DEBUG_H. + (FT_COMPONENT): Define. + (PS_Conv_Strtol): Return FT_Long. + Handle bad data and overflow. + Emit some tracing messages in case of error. + (PS_Conv_ToInt): Return FT_Long. + (PS_Conv_ToFixed): Updated. + * src/psaux/psconv.h: Updated. + + * include/freetype/internal/fttrace.h: Add `psconv'. + 2012-10-20 Werner Lemberg [autofit] Fix `make multi CC=c++'. diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h index e807a617a..6e6cb49fa 100644 --- a/include/freetype/internal/fttrace.h +++ b/include/freetype/internal/fttrace.h @@ -73,6 +73,7 @@ FT_TRACE_DEF( t1parse ) /* PostScript helper module `psaux' */ FT_TRACE_DEF( t1decode ) FT_TRACE_DEF( psobjs ) +FT_TRACE_DEF( psconv ) /* PostScript hinting module `pshinter' */ FT_TRACE_DEF( pshrec ) diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c index df5308356..5747c1105 100644 --- a/src/psaux/psconv.c +++ b/src/psaux/psconv.c @@ -18,11 +18,22 @@ #include #include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_DEBUG_H #include "psconv.h" #include "psauxerr.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_psconv + + /* The following array is used by various functions to quickly convert */ /* digits (both decimal and non-decimal) into numbers. */ @@ -69,18 +80,27 @@ #endif /* 'A' == 193 */ - FT_LOCAL_DEF( FT_Int ) + FT_LOCAL_DEF( FT_Long ) PS_Conv_Strtol( FT_Byte** cursor, FT_Byte* limit, - FT_Int base ) + FT_Long base ) { FT_Byte* p = *cursor; - FT_Int num = 0; + FT_Long num = 0; FT_Bool sign = 0; + FT_Long num_limit; + FT_Char c_limit; - if ( p >= limit || base < 2 || base > 36 ) + + if ( p >= limit ) + goto Bad; + + if ( base < 2 || base > 36 ) + { + FT_TRACE4(( "!!!INVALID BASE:!!!" )); return 0; + } if ( *p == '-' || *p == '+' ) { @@ -88,9 +108,12 @@ p++; if ( p == limit ) - return 0; + goto Bad; } + num_limit = 0x7FFFFFFFL / base; + c_limit = (FT_Char)( 0x7FFFFFFFL % base ); + for ( ; p < limit; p++ ) { FT_Char c; @@ -104,25 +127,38 @@ if ( c < 0 || c >= base ) break; + if ( num > num_limit || ( num == num_limit && c > c_limit ) ) + goto Overflow; num = num * base + c; } + *cursor = p; + + Exit: if ( sign ) num = -num; - *cursor = p; - return num; + + Overflow: + num = 0x7FFFFFFFL; + FT_TRACE4(( "!!!OVERFLOW:!!!" )); + goto Exit; + + Bad: + num = 0; + FT_TRACE4(( "!!!END OF DATA:!!!" )); + goto Exit; } - FT_LOCAL_DEF( FT_Int ) + FT_LOCAL_DEF( FT_Long ) PS_Conv_ToInt( FT_Byte** cursor, FT_Byte* limit ) { FT_Byte* p; - FT_Int num; + FT_Long num; num = PS_Conv_Strtol( cursor, limit, 10 ); @@ -142,7 +178,7 @@ FT_LOCAL_DEF( FT_Fixed ) PS_Conv_ToFixed( FT_Byte** cursor, FT_Byte* limit, - FT_Int power_ten ) + FT_Long power_ten ) { FT_Byte* p = *cursor; FT_Fixed integral; diff --git a/src/psaux/psconv.h b/src/psaux/psconv.h index 84854ba0d..d91c76221 100644 --- a/src/psaux/psconv.h +++ b/src/psaux/psconv.h @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (specification). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2012 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,20 +26,20 @@ FT_BEGIN_HEADER - FT_LOCAL( FT_Int ) + FT_LOCAL( FT_Long ) PS_Conv_Strtol( FT_Byte** cursor, FT_Byte* limit, - FT_Int base ); + FT_Long base ); - FT_LOCAL( FT_Int ) + FT_LOCAL( FT_Long ) PS_Conv_ToInt( FT_Byte** cursor, FT_Byte* limit ); FT_LOCAL( FT_Fixed ) PS_Conv_ToFixed( FT_Byte** cursor, FT_Byte* limit, - FT_Int power_ten ); + FT_Long power_ten ); #if 0 FT_LOCAL( FT_UInt )