Avoid undefined left-shifts. We really have to use double casts to avoid issues with C's and C++'s signedness propagation rules in implicit casts. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=41178 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=41182 * include/freetype/config/public-macros.h (FT_STATIC_CAST, FT_REINTERPRET_CAST): Modify macro to take two arguments. Update all callers. (FT_STATIC_BYTE_CAST): New macro. * include/freetype/freetype.h (FT_ENC_TAG): Use `FT_STATIC_BYTE_CAST`. * include/freetype/ftimage.h (FT_IMAGE_TAG): Ditto. * include/freetype/fttypes.h (FT_MAKE_TAG): Ditto. Use `FT_Tag` for casting. * src/ftraster/ftmisc.h (FT_MAKE_TAG): Removed, no longer needed. (FT_STATIC_BYTE_CAST): New macro. * src/smooth/ftgrays.c (FT_STATIC_CAST): Replace with... (FT_STATIC_BYTE_CAST): ... this.
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
diff --git a/include/freetype/config/public-macros.h b/include/freetype/config/public-macros.h
index 1b03640..9fbb327 100644
--- a/include/freetype/config/public-macros.h
+++ b/include/freetype/config/public-macros.h
@@ -120,11 +120,16 @@ FT_BEGIN_HEADER
* Support for casts in both C and C++.
*/
#ifdef __cplusplus
-#define FT_STATIC_CAST( type ) static_cast<type>
-#define FT_REINTERPRET_CAST( type ) reinterpret_cast<type>
+#define FT_STATIC_CAST( type, var ) static_cast<type>(var)
+#define FT_REINTERPRET_CAST( type, var ) reinterpret_cast<type>(var)
+
+#define FT_STATIC_BYTE_CAST( type, var ) \
+ static_cast<type>( static_cast<unsigned char>( var ) )
#else
-#define FT_STATIC_CAST( type ) (type)
-#define FT_REINTERPRET_CAST( type ) (type)
+#define FT_STATIC_CAST( type, var ) (type)(var)
+#define FT_REINTERPRET_CAST( type, var ) (type)(var)
+
+#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var)
#endif
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 7da4eb6..e3438f2 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -617,11 +617,11 @@ FT_BEGIN_HEADER
#ifndef FT_ENC_TAG
-#define FT_ENC_TAG( value, a, b, c, d ) \
- value = ( ( FT_STATIC_CAST( FT_Byte )(a) << 24 ) | \
- ( FT_STATIC_CAST( FT_Byte )(b) << 16 ) | \
- ( FT_STATIC_CAST( FT_Byte )(c) << 8 ) | \
- FT_STATIC_CAST( FT_Byte )(d) )
+#define FT_ENC_TAG( value, a, b, c, d ) \
+ value = ( ( FT_STATIC_BYTE_CAST( FT_UInt32, a ) << 24 ) | \
+ ( FT_STATIC_BYTE_CAST( FT_UInt32, b ) << 16 ) | \
+ ( FT_STATIC_BYTE_CAST( FT_UInt32, c ) << 8 ) | \
+ FT_STATIC_BYTE_CAST( FT_UInt32, d ) )
#endif /* FT_ENC_TAG */
@@ -3182,7 +3182,7 @@ FT_BEGIN_HEADER
* necessary to empty the cache after a mode switch to avoid false hits.
*
*/
-#define FT_LOAD_TARGET_( x ) ( FT_STATIC_CAST( FT_Int32 )( (x) & 15 ) << 16 )
+#define FT_LOAD_TARGET_( x ) ( FT_STATIC_CAST( FT_Int32, (x) & 15 ) << 16 )
#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL )
#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT )
@@ -3201,8 +3201,8 @@ FT_BEGIN_HEADER
* @FT_LOAD_TARGET_XXX value.
*
*/
-#define FT_LOAD_TARGET_MODE( x ) \
- FT_STATIC_CAST( FT_Render_Mode )( ( (x) >> 16 ) & 15 )
+#define FT_LOAD_TARGET_MODE( x ) \
+ FT_STATIC_CAST( FT_Render_Mode, ( (x) >> 16 ) & 15 )
/**************************************************************************
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index 6e33520..88533b8 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -696,11 +696,11 @@ FT_BEGIN_HEADER
*/
#ifndef FT_IMAGE_TAG
-#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \
- value = ( ( FT_STATIC_CAST( unsigned char )( _x1 ) << 24 ) | \
- ( FT_STATIC_CAST( unsigned char )( _x2 ) << 16 ) | \
- ( FT_STATIC_CAST( unsigned char )( _x3 ) << 8 ) | \
- FT_STATIC_CAST( unsigned char )( _x4 ) )
+#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \
+ value = ( ( FT_STATIC_BYTE_CAST( unsigned long, _x1 ) << 24 ) | \
+ ( FT_STATIC_BYTE_CAST( unsigned long, _x2 ) << 16 ) | \
+ ( FT_STATIC_BYTE_CAST( unsigned long, _x3 ) << 8 ) | \
+ FT_STATIC_BYTE_CAST( unsigned long, _x4 ) )
#endif /* FT_IMAGE_TAG */
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index 9d6c1b3..b77d356 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -347,9 +347,9 @@ FT_BEGIN_HEADER
* 2.11
*
*/
-#define FT_FACE_DRIVER_NAME( face ) \
- ( ( *FT_REINTERPRET_CAST( FT_Module_Class** ) \
- ( ( face )->driver ) )->module_name )
+#define FT_FACE_DRIVER_NAME( face ) \
+ ( ( *FT_REINTERPRET_CAST( FT_Module_Class**, \
+ ( face )->driver ) )->module_name )
/**************************************************************************
diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h
index 3b23358..eb7c472 100644
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -479,18 +479,19 @@ FT_BEGIN_HEADER
*
* @description:
* This macro converts four-letter tags that are used to label TrueType
- * tables into an unsigned long, to be used within FreeType.
+ * tables into an `FT_Tag` type, to be used within FreeType.
*
* @note:
* The produced values **must** be 32-bit integers. Don't redefine this
* macro.
*/
-#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
- FT_STATIC_CAST( FT_Tag ) \
- ( ( FT_STATIC_CAST( FT_Byte )( _x1 ) << 24 ) | \
- ( FT_STATIC_CAST( FT_Byte )( _x2 ) << 16 ) | \
- ( FT_STATIC_CAST( FT_Byte )( _x3 ) << 8 ) | \
- FT_STATIC_CAST( FT_Byte )( _x4 ) )
+#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
+ FT_STATIC_CAST( \
+ FT_Tag, \
+ ( ( FT_STATIC_BYTE_CAST( FT_Tag, _x1 ) << 24 ) | \
+ ( FT_STATIC_BYTE_CAST( FT_Tag, _x2 ) << 16 ) | \
+ ( FT_STATIC_BYTE_CAST( FT_Tag, _x3 ) << 8 ) | \
+ FT_STATIC_BYTE_CAST( FT_Tag, _x4 ) ) )
/*************************************************************************/
@@ -588,7 +589,7 @@ FT_BEGIN_HEADER
#define FT_IS_EMPTY( list ) ( (list).head == 0 )
-#define FT_BOOL( x ) FT_STATIC_CAST( FT_Bool )( (x) != 0 )
+#define FT_BOOL( x ) FT_STATIC_CAST( FT_Bool, (x) != 0 )
/* concatenate C tokens */
#define FT_ERR_XCAT( x, y ) x ## y
diff --git a/src/raster/ftmisc.h b/src/raster/ftmisc.h
index 9de0b12..b12a051 100644
--- a/src/raster/ftmisc.h
+++ b/src/raster/ftmisc.h
@@ -47,11 +47,8 @@
typedef signed long FT_F26Dot6;
typedef int FT_Error;
-#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
- ( ( (FT_ULong)_x1 << 24 ) | \
- ( (FT_ULong)_x2 << 16 ) | \
- ( (FT_ULong)_x3 << 8 ) | \
- (FT_ULong)_x4 )
+
+#define FT_STATIC_BYTE_CAST( type, var ) (type)(FT_Byte)(var)
/* from include/freetype/ftsystem.h */
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 37f4fe0..8235a94 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -152,7 +152,7 @@
#define ADD_INT( a, b ) \
(int)( (unsigned int)(a) + (unsigned int)(b) )
-#define FT_STATIC_CAST( type ) (type)
+#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var)
#define ft_memset memset