From f11f3ed15b5987e52a201df57771a09307c305d2 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 18 Aug 2021 06:54:34 +0200 Subject: [PATCH] [base] Fix ppem size overflow. Fixes #1086. * src/base/ftobjs.c (FT_Request_Metrics): Add return value. Check whether ppem values fit into unsigned short values. (FT_Request_Size): Updated. * include/freetype/internal/ftobjs.h: Updated. * src/cff/cffobjs.c (cff_size_request), src/cid/cidobjs.c (cid_size_request), src/truetype/ttdriver.c (tt_size_request), src/type1/t1objs.c (T1_Size_Request): Updated. --- include/freetype/internal/ftobjs.h | 2 +- src/base/ftobjs.c | 30 ++++++++++++++++++++++++------ src/cff/cffobjs.c | 9 +++++++-- src/cid/cidobjs.c | 9 +++++++-- src/truetype/ttdriver.c | 12 +++++++++++- src/type1/t1objs.c | 9 +++++++-- 6 files changed, 57 insertions(+), 14 deletions(-) diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 808eae879..e52a26aa0 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -673,7 +673,7 @@ FT_BEGIN_HEADER /* Set the metrics according to a size request. */ - FT_BASE( void ) + FT_BASE( FT_Error ) FT_Request_Metrics( FT_Face face, FT_Size_Request req ); diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 5c1a4d034..342ac4a27 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -3132,10 +3132,12 @@ } - FT_BASE_DEF( void ) + FT_BASE_DEF( FT_Error ) FT_Request_Metrics( FT_Face face, FT_Size_Request req ) { + FT_Error error = FT_Err_Ok; + FT_Size_Metrics* metrics; @@ -3226,8 +3228,18 @@ scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); } - metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); - metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); + scaled_w = ( scaled_w + 32 ) >> 6; + scaled_h = ( scaled_h + 32 ) >> 6; + if ( scaled_w > FT_USHORT_MAX || + scaled_h > FT_USHORT_MAX ) + { + FT_ERROR(( "FT_Request_Metrics: Resulting ppem size too large\n" )); + error = FT_ERR( Invalid_Pixel_Size ); + goto Exit; + } + + metrics->x_ppem = (FT_UShort)scaled_w; + metrics->y_ppem = (FT_UShort)scaled_h; ft_recompute_scaled_metrics( face, metrics ); } @@ -3237,6 +3249,9 @@ metrics->x_scale = 1L << 16; metrics->y_scale = 1L << 16; } + + Exit: + return error; } @@ -3300,7 +3315,7 @@ FT_Request_Size( FT_Face face, FT_Size_Request req ) { - FT_Error error = FT_Err_Ok; + FT_Error error; FT_Driver_Class clazz; FT_ULong strike_index; @@ -3336,13 +3351,15 @@ */ error = FT_Match_Size( face, req, 0, &strike_index ); if ( error ) - return error; + goto Exit; return FT_Select_Size( face, (FT_Int)strike_index ); } else { - FT_Request_Metrics( face, req ); + error = FT_Request_Metrics( face, req ); + if ( error ) + goto Exit; FT_TRACE5(( "FT_Request_Size:\n" )); } @@ -3365,6 +3382,7 @@ } #endif + Exit: return error; } diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index c50281342..9b5b17c25 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -283,6 +283,8 @@ cff_size_request( FT_Size size, FT_Size_Request req ) { + FT_Error error; + CFF_Size cffsize = (CFF_Size)size; PSH_Globals_Funcs funcs; @@ -304,7 +306,9 @@ #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - FT_Request_Metrics( size->face, req ); + error = FT_Request_Metrics( size->face, req ); + if ( error ) + goto Exit; funcs = cff_size_get_globals_funcs( cffsize ); @@ -345,7 +349,8 @@ } } - return FT_Err_Ok; + Exit: + return error; } diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c index c75681185..68ec84bc8 100644 --- a/src/cid/cidobjs.c +++ b/src/cid/cidobjs.c @@ -157,10 +157,14 @@ cid_size_request( FT_Size size, FT_Size_Request req ) { + FT_Error error; + PSH_Globals_Funcs funcs; - FT_Request_Metrics( size->face, req ); + error = FT_Request_Metrics( size->face, req ); + if ( error ) + goto Exit; funcs = cid_size_get_globals_funcs( (CID_Size)size ); @@ -170,7 +174,8 @@ size->metrics.y_scale, 0, 0 ); - return FT_Err_Ok; + Exit: + return error; } diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index eaa14aad8..6fcfdb23e 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -354,7 +354,16 @@ #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - FT_Request_Metrics( size->face, req ); + { + FT_Error err = FT_Request_Metrics( size->face, req ); + + + if ( err ) + { + error = err; + goto Exit; + } + } if ( FT_IS_SCALABLE( size->face ) ) { @@ -382,6 +391,7 @@ #endif } + Exit: return error; } diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c index ec202be29..50dad038f 100644 --- a/src/type1/t1objs.c +++ b/src/type1/t1objs.c @@ -116,11 +116,15 @@ T1_Size_Request( FT_Size t1size, /* T1_Size */ FT_Size_Request req ) { + FT_Error error; + T1_Size size = (T1_Size)t1size; PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); - FT_Request_Metrics( size->root.face, req ); + error = FT_Request_Metrics( size->root.face, req ); + if ( error ) + goto Exit; if ( funcs ) funcs->set_scale( (PSH_Globals)t1size->internal->module_data, @@ -128,7 +132,8 @@ size->root.metrics.y_scale, 0, 0 ); - return FT_Err_Ok; + Exit: + return error; }