Add macros for handling over-/underflowing `FT_Int64' values. * include/freetype/internal/ftcalc.h (ADD_INT64, SUB_INT64, MUL_INT64, DIV_INT64) [FT_LONG64]: New macros. * src/base/ftcalc.c (ft_corner_orientation) [FT_LONG64]: Use `SUB_INT64' and `MUL_INT64'. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10028
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
diff --git a/ChangeLog b/ChangeLog
index 69cdc1d..585011a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2018-08-23 Werner Lemberg <wl@gnu.org>
+
+ Add macros for handling over-/underflowing `FT_Int64' values.
+
+ * include/freetype/internal/ftcalc.h (ADD_INT64, SUB_INT64,
+ MUL_INT64, DIV_INT64) [FT_LONG64]: New macros.
+
+ * src/base/ftcalc.c (ft_corner_orientation) [FT_LONG64]: Use
+ `SUB_INT64' and `MUL_INT64'.
+
+ Reported as
+
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10028
+
2018-08-22 Werner Lemberg <wl@gnu.org>
[truetype] Improve legibility of `glyf' parsing.
diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index 733b674..dc1b664 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -489,6 +489,19 @@ FT_BEGIN_HEADER
#define NEG_INT32( a ) \
(FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) )
+#ifdef FT_LONG64
+
+#define ADD_INT64( a, b ) \
+ (FT_Int64)( (FT_UInt64)(a) + (FT_UInt64)(b) )
+#define SUB_INT64( a, b ) \
+ (FT_Int64)( (FT_UInt64)(a) - (FT_UInt64)(b) )
+#define MUL_INT64( a, b ) \
+ (FT_Int64)( (FT_UInt64)(a) * (FT_UInt64)(b) )
+#define NEG_INT64( a ) \
+ (FT_Int64)( (FT_UInt64)0 - (FT_UInt64)(a) )
+
+#endif /* FT_LONG64 */
+
FT_END_HEADER
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index f110c9e..7a42103 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -983,9 +983,13 @@
FT_Pos out_x,
FT_Pos out_y )
{
+ /* we silently ignore overflow errors since such large values */
+ /* lead to even more (harmless) rendering errors later on */
+
#ifdef FT_LONG64
- FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
+ FT_Int64 delta = SUB_INT64( MUL_INT64( in_x, out_y ),
+ MUL_INT64( in_y, out_x ) );
return ( delta > 0 ) - ( delta < 0 );
@@ -995,8 +999,6 @@
FT_Int result;
- /* we silently ignore overflow errors, since such large values */
- /* lead to even more (harmless) rendering errors later on */
if ( ADD_LONG( FT_ABS( in_x ), FT_ABS( out_y ) ) <= 131071L &&
ADD_LONG( FT_ABS( in_y ), FT_ABS( out_x ) ) <= 131071L )
{