Fix reading of signed integers from files on 64bit platforms.

Previously, signed integers were converted to unsigned integers, but
this can fail because of sign extension.  For example, 0xa344a1eb
becomes 0xffffffffa344a1eb.

We now do the reverse which is always correct because the integer
size is the same during the cast from unsigned to signed.

* include/freetype/internal/ftstream.h, src/base/ftstream.c
(FT_Stream_Get*): Replace with...
(FT_Stream_GetU*): Functions which read unsigned integers.
Update all macros accordingly.

* src/gzip/ftgzip.c (ft_gzip_get_uncompressed_size): Updated.
This commit is contained in:
Kan-Ru Chen 2011-04-12 09:26:43 +02:00 committed by Werner Lemberg
parent 7f03a2465c
commit 21b1a0de7c
4 changed files with 113 additions and 95 deletions

View File

@ -1,3 +1,21 @@
2011-04-11 Kan-Ru Chen <kanru@kanru.info>
Fix reading of signed integers from files on 64bit platforms.
Previously, signed integers were converted to unsigned integers, but
this can fail because of sign extension. For example, 0xa344a1eb
becomes 0xffffffffa344a1eb.
We now do the reverse which is always correct because the integer
size is the same during the cast from unsigned to signed.
* include/freetype/internal/ftstream.h, src/base/ftstream.c
(FT_Stream_Get*): Replace with...
(FT_Stream_GetU*): Functions which read unsigned integers.
Update all macros accordingly.
* src/gzip/ftgzip.c (ft_gzip_get_uncompressed_size): Updated.
2011-04-07 Werner Lemberg <wl@gnu.org>
Update Unicode ranges for CJK autofitter; in particular, add Hangul.

View File

@ -4,7 +4,7 @@
/* */
/* Stream handling (specification). */
/* */
/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */
/* Copyright 1996-2002, 2004-2006, 2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -292,18 +292,18 @@ FT_BEGIN_HEADER
#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char )
#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte )
#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_Short )
#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_UShort )
#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_Long )
#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong )
#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetLong, FT_Long )
#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )
#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong )
#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_OFF3() FT_GET_MACRO( FT_Stream_GetUOffset, FT_Long )
#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_GetShortLE, FT_Short )
#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort )
#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long )
#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, 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 )
#endif
#define FT_READ_MACRO( func, type, var ) \
@ -312,17 +312,17 @@ FT_BEGIN_HEADER
#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var )
#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var )
#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_Short, var )
#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var )
#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var )
#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var )
#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var )
#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, 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_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadUOffset, FT_Long, 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_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var )
#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var )
#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var )
#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, 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 )
#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
@ -431,25 +431,25 @@ FT_BEGIN_HEADER
FT_BASE( FT_Char )
FT_Stream_GetChar( FT_Stream stream );
/* read a 16-bit big-endian integer from an entered frame */
FT_BASE( FT_Short )
FT_Stream_GetShort( FT_Stream stream );
/* read a 16-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_UShort )
FT_Stream_GetUShort( FT_Stream stream );
/* read a 24-bit big-endian integer from an entered frame */
FT_BASE( FT_Long )
FT_Stream_GetOffset( FT_Stream stream );
/* read a 24-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_Stream_GetUOffset( FT_Stream stream );
/* read a 32-bit big-endian integer from an entered frame */
FT_BASE( FT_Long )
FT_Stream_GetLong( FT_Stream stream );
/* read a 32-bit big-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_Stream_GetULong( FT_Stream stream );
/* read a 16-bit little-endian integer from an entered frame */
FT_BASE( FT_Short )
FT_Stream_GetShortLE( FT_Stream stream );
/* read a 16-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_UShort )
FT_Stream_GetUShortLE( FT_Stream stream );
/* read a 32-bit little-endian integer from an entered frame */
FT_BASE( FT_Long )
FT_Stream_GetLongLE( FT_Stream stream );
/* read a 32-bit little-endian unsigned integer from an entered frame */
FT_BASE( FT_ULong )
FT_Stream_GetULongLE( FT_Stream stream );
/* read a byte from a stream */
@ -457,30 +457,30 @@ FT_BEGIN_HEADER
FT_Stream_ReadChar( FT_Stream stream,
FT_Error* error );
/* read a 16-bit big-endian integer from a stream */
FT_BASE( FT_Short )
FT_Stream_ReadShort( FT_Stream stream,
FT_Error* error );
/* read a 24-bit big-endian integer from a stream */
FT_BASE( FT_Long )
FT_Stream_ReadOffset( FT_Stream stream,
/* read a 16-bit big-endian unsigned integer from a stream */
FT_BASE( FT_UShort )
FT_Stream_ReadUShort( FT_Stream stream,
FT_Error* error );
/* read a 32-bit big-endian integer from a stream */
FT_BASE( FT_Long )
FT_Stream_ReadLong( FT_Stream stream,
FT_Error* error );
/* read a 16-bit little-endian integer from a stream */
FT_BASE( FT_Short )
FT_Stream_ReadShortLE( FT_Stream stream,
/* read a 24-bit big-endian unsigned integer from a stream */
FT_BASE( FT_ULong )
FT_Stream_ReadUOffset( FT_Stream stream,
FT_Error* error );
/* read a 32-bit little-endian integer from a stream */
FT_BASE( FT_Long )
FT_Stream_ReadLongLE( FT_Stream stream,
FT_Error* error );
/* read a 32-bit big-endian integer from a stream */
FT_BASE( FT_ULong )
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_Stream_ReadUShortLE( FT_Stream stream,
FT_Error* error );
/* read a 32-bit little-endian unsigned integer from a stream */
FT_BASE( FT_ULong )
FT_Stream_ReadULongLE( FT_Stream stream,
FT_Error* error );
/* Read a structure from a stream. The structure must be described */
/* by an array of FT_Frame_Field records. */

View File

@ -4,7 +4,7 @@
/* */
/* I/O stream support (body). */
/* */
/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009, 2010 by */
/* Copyright 2000-2002, 2004-2006, 2008-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -354,8 +354,8 @@
}
FT_BASE_DEF( FT_Short )
FT_Stream_GetShort( FT_Stream stream )
FT_BASE_DEF( FT_UShort )
FT_Stream_GetUShort( FT_Stream stream )
{
FT_Byte* p;
FT_Short result;
@ -366,15 +366,15 @@
result = 0;
p = stream->cursor;
if ( p + 1 < stream->limit )
result = FT_NEXT_SHORT( p );
result = FT_NEXT_USHORT( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Short )
FT_Stream_GetShortLE( FT_Stream stream )
FT_BASE_DEF( FT_UShort )
FT_Stream_GetUShortLE( FT_Stream stream )
{
FT_Byte* p;
FT_Short result;
@ -385,15 +385,15 @@
result = 0;
p = stream->cursor;
if ( p + 1 < stream->limit )
result = FT_NEXT_SHORT_LE( p );
result = FT_NEXT_USHORT_LE( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetOffset( FT_Stream stream )
FT_BASE_DEF( FT_ULong )
FT_Stream_GetUOffset( FT_Stream stream )
{
FT_Byte* p;
FT_Long result;
@ -404,14 +404,14 @@
result = 0;
p = stream->cursor;
if ( p + 2 < stream->limit )
result = FT_NEXT_OFF3( p );
result = FT_NEXT_UOFF3( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetLong( FT_Stream stream )
FT_BASE_DEF( FT_ULong )
FT_Stream_GetULong( FT_Stream stream )
{
FT_Byte* p;
FT_Long result;
@ -422,14 +422,14 @@
result = 0;
p = stream->cursor;
if ( p + 3 < stream->limit )
result = FT_NEXT_LONG( p );
result = FT_NEXT_ULONG( p );
stream->cursor = p;
return result;
}
FT_BASE_DEF( FT_Long )
FT_Stream_GetLongLE( FT_Stream stream )
FT_BASE_DEF( FT_ULong )
FT_Stream_GetULongLE( FT_Stream stream )
{
FT_Byte* p;
FT_Long result;
@ -440,7 +440,7 @@
result = 0;
p = stream->cursor;
if ( p + 3 < stream->limit )
result = FT_NEXT_LONG_LE( p );
result = FT_NEXT_ULONG_LE( p );
stream->cursor = p;
return result;
}
@ -483,8 +483,8 @@
}
FT_BASE_DEF( FT_Short )
FT_Stream_ReadShort( FT_Stream stream,
FT_BASE_DEF( FT_UShort )
FT_Stream_ReadUShort( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[2];
@ -511,7 +511,7 @@
}
if ( p )
result = FT_NEXT_SHORT( p );
result = FT_NEXT_USHORT( p );
}
else
goto Fail;
@ -522,7 +522,7 @@
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadShort:"
FT_ERROR(( "FT_Stream_ReadUShort:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@ -530,8 +530,8 @@
}
FT_BASE_DEF( FT_Short )
FT_Stream_ReadShortLE( FT_Stream stream,
FT_BASE_DEF( FT_UShort )
FT_Stream_ReadUShortLE( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[2];
@ -558,7 +558,7 @@
}
if ( p )
result = FT_NEXT_SHORT_LE( p );
result = FT_NEXT_USHORT_LE( p );
}
else
goto Fail;
@ -569,7 +569,7 @@
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadShortLE:"
FT_ERROR(( "FT_Stream_ReadUShortLE:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@ -577,8 +577,8 @@
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadOffset( FT_Stream stream,
FT_BASE_DEF( FT_ULong )
FT_Stream_ReadUOffset( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[3];
@ -605,7 +605,7 @@
}
if ( p )
result = FT_NEXT_OFF3( p );
result = FT_NEXT_UOFF3( p );
}
else
goto Fail;
@ -616,7 +616,7 @@
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadOffset:"
FT_ERROR(( "FT_Stream_ReadUOffset:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@ -624,8 +624,8 @@
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadLong( FT_Stream stream,
FT_BASE_DEF( FT_ULong )
FT_Stream_ReadULong( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[4];
@ -652,7 +652,7 @@
}
if ( p )
result = FT_NEXT_LONG( p );
result = FT_NEXT_ULONG( p );
}
else
goto Fail;
@ -663,7 +663,7 @@
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadLong:"
FT_ERROR(( "FT_Stream_ReadULong:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));
@ -671,8 +671,8 @@
}
FT_BASE_DEF( FT_Long )
FT_Stream_ReadLongLE( FT_Stream stream,
FT_BASE_DEF( FT_ULong )
FT_Stream_ReadULongLE( FT_Stream stream,
FT_Error* error )
{
FT_Byte reads[4];
@ -699,7 +699,7 @@
}
if ( p )
result = FT_NEXT_LONG_LE( p );
result = FT_NEXT_ULONG_LE( p );
}
else
goto Fail;
@ -710,7 +710,7 @@
Fail:
*error = FT_Err_Invalid_Stream_Operation;
FT_ERROR(( "FT_Stream_ReadLongLE:"
FT_ERROR(( "FT_Stream_ReadULongLE:"
" invalid i/o; pos = 0x%lx, size = 0x%lx\n",
stream->pos, stream->size ));

View File

@ -8,7 +8,7 @@
/* parse compressed PCF fonts, as found with many X11 server */
/* distributions. */
/* */
/* Copyright 2002, 2003, 2004, 2005, 2006, 2009, 2010 by */
/* Copyright 2002-2006, 2009-2011 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -571,7 +571,7 @@
old_pos = stream->pos;
if ( !FT_Stream_Seek( stream, stream->size - 4 ) )
{
result = (FT_ULong)FT_Stream_ReadLong( stream, &error );
result = FT_Stream_ReadULong( stream, &error );
if ( error )
result = 0;