Hi Werner,
As per our discussion I propose the following patch to limit the outline scaling so that ppem values do not exceed 65535. As far as I can see, no such limits are currently in place, ppem values are simply truncated while the scaling factors are not limited.
My secret goal is to limit those integer addition/subtraction overflows in the future and, perhaps, revisit the old ones. To that effect, if this is accepted, I propose turning the ADD_ and SUB_ macros back to normal arithmetic and see how many overflows truly survive. I hope to see some of the macros gone if they are triggered by crazy scaling.
Alexei
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 79e7511..54771d7 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -3014,7 +3014,7 @@
}
- FT_BASE_DEF( void )
+ FT_BASE_DEF( FT_Error )
FT_Request_Metrics( FT_Face face,
FT_Size_Request req )
{
@@ -3108,6 +3108,10 @@
scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
}
+ /* limit scaling and make sure that ppem is indeed less than 65536 */
+ if ( scaled_w > 0x3FFFDFL || scaled_h > 0x3FFFDFL )
+ return FT_THROW( Invalid_Argument );
+
metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );
metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );
@@ -3131,6 +3135,8 @@
FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 ));
FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem ));
FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem ));
+
+ return FT_Err_Ok;
}
@@ -3257,9 +3263,7 @@
return FT_Select_Size( face, (FT_Int)strike_index );
}
- FT_Request_Metrics( face, req );
-
- return FT_Err_Ok;
+ return FT_Request_Metrics( face, req );
}
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index 538f483..f22ac5e 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -683,7 +683,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 );