[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
This commit is contained in:
Ben Wagner 2022-06-17 12:37:02 -04:00
parent d9b8a69e9a
commit f7daf9d293
2 changed files with 70 additions and 70 deletions

View File

@ -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() 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_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_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 );

View File

@ -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 );