Commit f7daf9d293c00cbb80c9f7bf4dc93717464a80e8

Ben Wagner 2022-06-17T12:37:02

[stream] Fix reading s32 when long is s64 `FT_READ_LONG`, `FT_GET_LONG`, and related macros did not return negative values when `long` is more than 32 bits. `FT_Stream_ReadULong` would read four bytes into the LSB of an `FT_ULong` and return that. Since this can never set the MSb of the `FT_ULong` when `FT_ULong` is more than 32 bits the cast to `FT_Long` never resulted in a negative value. Fix this by modifying `FT_Stream_Read*` to return a type of the same size as the bytes it is reading and changing the `FT_READ_*` and `FT_GET_*` macros to cast to the same type returned by `FT_Stream_Read*` but with the correctly signed type (instead of casting to what is assumed to be the type of `var` which will happen automatically anyway). There exist a few cases like with the `OFF3` variants where there isn't generally a type with the correct size. `FT_PEEK_OFF3` works around this loading the bytes into the three most significant bits and then doing a signed shift down. `FT_NEXT_OFF3` also already worked correctly by casting this signed value to another signed type. `FT_Stream_GetUOffset` works correctly but one must be careful not to attempt to cast the returned value to a signed type. Fortunately there is only `FT_GET_UOFF3` and no `FT_GET_OFF3`. All of these cases are handled correctly when reading values through `FT_Stream_ReadFields` since it generically computes the signed value through an `FT_Int32`. This change is essentially doing the same for these macros. * include/freetype/internal/ftstream.h (FT_NEXT_*, FT_GET_*, FT_READ*): Update macros and return types to use fixed size types for fixed size values. * src/base/ftstream.c (FT_StreamGet*, FT_StreamRead*): Dito. Issue: #1161

diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h
index aa51fe5..a12e41a 100644
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -238,42 +238,42 @@ FT_BEGIN_HEADER
 #define FT_NEXT_BYTE( buffer )         \
           ( (unsigned char)*buffer++ )
 
-#define FT_NEXT_SHORT( buffer )                                   \
-          ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) )
+#define FT_NEXT_SHORT( buffer )                        \
+          ( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) )
 
-#define FT_NEXT_USHORT( buffer )                                            \
-          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) )
+#define FT_NEXT_USHORT( buffer )                        \
+          ( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) )
 
-#define FT_NEXT_OFF3( buffer )                                  \
-          ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) )
+#define FT_NEXT_OFF3( buffer )                        \
+          ( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) )
 
-#define FT_NEXT_UOFF3( buffer )                                           \
-          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) )
+#define FT_NEXT_UOFF3( buffer )                        \
+          ( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) )
 
-#define FT_NEXT_LONG( buffer )                                  \
-          ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) )
+#define FT_NEXT_LONG( buffer )                        \
+          ( buffer += 4, FT_PEEK_LONG( buffer - 4 ) )
 
-#define FT_NEXT_ULONG( buffer )                                           \
-          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) )
+#define FT_NEXT_ULONG( buffer )                        \
+          ( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) )
 
 
-#define FT_NEXT_SHORT_LE( buffer )                                   \
-          ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) )
+#define FT_NEXT_SHORT_LE( buffer )                        \
+          ( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) )
 
-#define FT_NEXT_USHORT_LE( buffer )                                            \
-          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) )
+#define FT_NEXT_USHORT_LE( buffer )                        \
+          ( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) )
 
-#define FT_NEXT_OFF3_LE( buffer )                                  \
-          ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) )
+#define FT_NEXT_OFF3_LE( buffer )                        \
+          ( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) )
 
-#define FT_NEXT_UOFF3_LE( buffer )                                           \
-          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) )
+#define FT_NEXT_UOFF3_LE( buffer )                        \
+          ( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) )
 
-#define FT_NEXT_LONG_LE( buffer )                                  \
-          ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) )
+#define FT_NEXT_LONG_LE( buffer )                        \
+          ( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) )
 
-#define FT_NEXT_ULONG_LE( buffer )                                           \
-          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) )
+#define FT_NEXT_ULONG_LE( buffer )                        \
+          ( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) )
 
 
   /**************************************************************************
@@ -307,17 +307,17 @@ FT_BEGIN_HEADER
 
 #define FT_GET_CHAR()       FT_GET_MACRO( FT_Stream_GetByte, FT_Char )
 #define FT_GET_BYTE()       FT_GET_MACRO( FT_Stream_GetByte, FT_Byte )
-#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetUShort, FT_Short )
-#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort )
-#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong )
-#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetULong, FT_Long )
-#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
-#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
-
-#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short )
-#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort )
-#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long )
-#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong )
+#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetUShort, FT_Int16 )
+#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetUShort, FT_UInt16 )
+#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetUOffset, FT_UInt32 )
+#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetULong, FT_Int32 )
+#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
+#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
+
+#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Int32 )
+#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UInt32 )
+#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetULongLE, FT_Int32 )
+#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetULongLE, FT_UInt32 )
 #endif
 
 
@@ -334,16 +334,16 @@ FT_BEGIN_HEADER
    */
 #define FT_READ_BYTE( var )       FT_READ_MACRO( FT_Stream_ReadByte, FT_Byte, var )
 #define FT_READ_CHAR( var )       FT_READ_MACRO( FT_Stream_ReadByte, FT_Char, var )
-#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var )
-#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var )
-#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var )
-#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var )
-#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var )
+#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadUShort, FT_Int16, var )
+#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadUShort, FT_UInt16, var )
+#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadUOffset, FT_UInt32, var )
+#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadULong, FT_Int32, var )
+#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadULong, FT_UInt32, var )
 
-#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var )
-#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var )
-#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var )
-#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var )
+#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Int16, var )
+#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UInt16, var )
+#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Int32, var )
+#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadULongLE, FT_UInt32, var )
 
 
 #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
@@ -459,23 +459,23 @@ FT_BEGIN_HEADER
   FT_Stream_GetByte( FT_Stream  stream );
 
   /* read a 16-bit big-endian unsigned integer from an entered frame */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_GetUShort( FT_Stream  stream );
 
   /* read a 24-bit big-endian unsigned integer from an entered frame */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_GetUOffset( FT_Stream  stream );
 
   /* read a 32-bit big-endian unsigned integer from an entered frame */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_GetULong( FT_Stream  stream );
 
   /* read a 16-bit little-endian unsigned integer from an entered frame */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_GetUShortLE( FT_Stream  stream );
 
   /* read a 32-bit little-endian unsigned integer from an entered frame */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_GetULongLE( FT_Stream  stream );
 
 
@@ -485,7 +485,7 @@ FT_BEGIN_HEADER
                       FT_Error*  error );
 
   /* read a 16-bit big-endian unsigned integer from a stream */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_ReadUShort( FT_Stream  stream,
                         FT_Error*  error );
 
@@ -495,17 +495,17 @@ FT_BEGIN_HEADER
                          FT_Error*  error );
 
   /* read a 32-bit big-endian integer from a stream */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_ReadULong( FT_Stream  stream,
                        FT_Error*  error );
 
   /* read a 16-bit little-endian unsigned integer from a stream */
-  FT_BASE( FT_UShort )
+  FT_BASE( FT_UInt16 )
   FT_Stream_ReadUShortLE( FT_Stream  stream,
                           FT_Error*  error );
 
   /* read a 32-bit little-endian unsigned integer from a stream */
-  FT_BASE( FT_ULong )
+  FT_BASE( FT_UInt32 )
   FT_Stream_ReadULongLE( FT_Stream  stream,
                          FT_Error*  error );
 
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
index cc92656..3877e0c 100644
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -363,11 +363,11 @@
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_GetUShort( FT_Stream  stream )
   {
     FT_Byte*   p;
-    FT_UShort  result;
+    FT_UInt16  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -382,11 +382,11 @@
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_GetUShortLE( FT_Stream  stream )
   {
     FT_Byte*   p;
-    FT_UShort  result;
+    FT_UInt16  result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -401,11 +401,11 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_GetUOffset( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_ULong  result;
+    FT_UInt32 result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -419,11 +419,11 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_GetULong( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_ULong  result;
+    FT_UInt32 result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -437,11 +437,11 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_GetULongLE( FT_Stream  stream )
   {
     FT_Byte*  p;
-    FT_ULong  result;
+    FT_UInt32 result;
 
 
     FT_ASSERT( stream && stream->cursor );
@@ -493,13 +493,13 @@
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_ReadUShort( FT_Stream  stream,
                         FT_Error*  error )
   {
     FT_Byte    reads[2];
     FT_Byte*   p;
-    FT_UShort  result = 0;
+    FT_UInt16  result = 0;
 
 
     FT_ASSERT( stream );
@@ -538,13 +538,13 @@
   }
 
 
-  FT_BASE_DEF( FT_UShort )
+  FT_BASE_DEF( FT_UInt16 )
   FT_Stream_ReadUShortLE( FT_Stream  stream,
                           FT_Error*  error )
   {
     FT_Byte    reads[2];
     FT_Byte*   p;
-    FT_UShort  result = 0;
+    FT_UInt16  result = 0;
 
 
     FT_ASSERT( stream );
@@ -628,13 +628,13 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_ReadULong( FT_Stream  stream,
                        FT_Error*  error )
   {
     FT_Byte   reads[4];
     FT_Byte*  p;
-    FT_ULong  result = 0;
+    FT_UInt32 result = 0;
 
 
     FT_ASSERT( stream );
@@ -673,13 +673,13 @@
   }
 
 
-  FT_BASE_DEF( FT_ULong )
+  FT_BASE_DEF( FT_UInt32 )
   FT_Stream_ReadULongLE( FT_Stream  stream,
                          FT_Error*  error )
   {
     FT_Byte   reads[4];
     FT_Byte*  p;
-    FT_ULong  result = 0;
+    FT_UInt32 result = 0;
 
 
     FT_ASSERT( stream );