Skip to content

[stream] Fix reading s32 when long is s64

Ben Wagner requested to merge bungeman/freetype:read_s32_into_s64 into master

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 (closed)

Edited by Ben Wagner

Merge request reports