[cid] Fix scanning for StartData' and
/sfnts' (#47892).
* src/cid/cidparse.c (STARTDATA, STARTDATA_LEN, SFNTS, SFNTS_LEN): New macros. (cid_parser_new): Fix and document algorithm.
This commit is contained in:
parent
a7d8bdbcfe
commit
09f0e0fcbe
@ -1,3 +1,11 @@
|
||||
2016-05-16 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[cid] Fix scanning for `StartData' and `/sfnts' (#47892).
|
||||
|
||||
* src/cid/cidparse.c (STARTDATA, STARTDATA_LEN, SFNTS, SFNTS_LEN):
|
||||
New macros.
|
||||
(cid_parser_new): Fix and document algorithm.
|
||||
|
||||
2016-05-16 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
|
||||
|
||||
[truetype] Improve the recursive reference detector.
|
||||
|
@ -47,6 +47,12 @@
|
||||
/*************************************************************************/
|
||||
|
||||
|
||||
#define STARTDATA "StartData"
|
||||
#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 )
|
||||
#define SFNTS "/sfnts"
|
||||
#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 )
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_parser_new( CID_Parser* parser,
|
||||
FT_Stream stream,
|
||||
@ -85,9 +91,29 @@
|
||||
/* now, read the rest of the file until we find */
|
||||
/* `StartData' or `/sfnts' */
|
||||
{
|
||||
FT_Byte buffer[256 + 10];
|
||||
FT_ULong read_len = 256 + 10;
|
||||
FT_Byte* p = buffer;
|
||||
/*
|
||||
* The algorithm is as follows (omitting the case with less than 256
|
||||
* bytes to fill for simplicity).
|
||||
*
|
||||
* 1. Fill the buffer with 256 + STARTDATA_LEN bytes.
|
||||
*
|
||||
* 2. Search for the STARTDATA and SFNTS strings at positions
|
||||
* buffer[0], buffer[1], ...,
|
||||
* buffer[255 + STARTDATA_LEN - SFNTS_LEN].
|
||||
*
|
||||
* 3. Move the last STARTDATA_LEN bytes to buffer[0].
|
||||
*
|
||||
* 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN.
|
||||
*
|
||||
* 5. Repeat with step 2.
|
||||
*
|
||||
*/
|
||||
FT_Byte buffer[256 + STARTDATA_LEN + 1];
|
||||
|
||||
/* values for the first loop */
|
||||
FT_ULong read_len = 256 + STARTDATA_LEN;
|
||||
FT_ULong read_offset = 0;
|
||||
FT_Byte* p = buffer;
|
||||
|
||||
|
||||
for ( offset = FT_STREAM_POS(); ; offset += 256 )
|
||||
@ -96,40 +122,48 @@
|
||||
|
||||
|
||||
stream_len = stream->size - FT_STREAM_POS();
|
||||
if ( stream_len == 0 )
|
||||
|
||||
read_len = FT_MIN( read_len, stream_len );
|
||||
if ( FT_STREAM_READ( p, read_len ) )
|
||||
goto Exit;
|
||||
|
||||
/* ensure that we do not compare with data beyond the buffer */
|
||||
p[read_len] = '\0';
|
||||
|
||||
limit = p + read_len - SFNTS_LEN;
|
||||
|
||||
for ( p = buffer; p < limit; p++ )
|
||||
{
|
||||
if ( p[0] == 'S' &&
|
||||
ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 )
|
||||
{
|
||||
/* save offset of binary data after `StartData' */
|
||||
offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN;
|
||||
goto Found;
|
||||
}
|
||||
else if ( p[1] == 's' &&
|
||||
ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 )
|
||||
{
|
||||
offset += (FT_ULong)( p - buffer ) + SFNTS_LEN;
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
|
||||
if ( read_offset + read_len < STARTDATA_LEN )
|
||||
{
|
||||
FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
|
||||
error = FT_THROW( Invalid_File_Format );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
read_len = FT_MIN( read_len, stream_len );
|
||||
if ( FT_STREAM_READ( p, read_len ) )
|
||||
goto Exit;
|
||||
FT_MEM_MOVE( buffer,
|
||||
buffer + read_offset + read_len - STARTDATA_LEN,
|
||||
STARTDATA_LEN );
|
||||
|
||||
if ( read_len < 256 )
|
||||
p[read_len] = '\0';
|
||||
|
||||
limit = p + read_len - 10;
|
||||
|
||||
for ( p = buffer; p < limit; p++ )
|
||||
{
|
||||
if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
|
||||
{
|
||||
/* save offset of binary data after `StartData' */
|
||||
offset += (FT_ULong)( p - buffer + 10 );
|
||||
goto Found;
|
||||
}
|
||||
else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
|
||||
{
|
||||
offset += (FT_ULong)( p - buffer + 7 );
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
|
||||
FT_MEM_MOVE( buffer, p, 10 );
|
||||
read_len = 256;
|
||||
p = buffer + 10;
|
||||
/* values for the next loop */
|
||||
read_len = 256;
|
||||
read_offset = STARTDATA_LEN;
|
||||
p = buffer + read_offset;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +199,7 @@
|
||||
limit = parser->root.limit;
|
||||
cur = parser->root.cursor;
|
||||
|
||||
while ( cur < limit )
|
||||
while ( cur < limit - SFNTS_LEN )
|
||||
{
|
||||
if ( parser->root.error )
|
||||
{
|
||||
@ -173,7 +207,9 @@
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
|
||||
if ( cur[0] == 'S' &&
|
||||
cur < limit - STARTDATA_LEN &&
|
||||
ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
|
||||
{
|
||||
if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
|
||||
{
|
||||
@ -191,7 +227,8 @@
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
|
||||
else if ( cur[1] == 's' &&
|
||||
ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 )
|
||||
{
|
||||
FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
|
||||
error = FT_THROW( Unknown_File_Format );
|
||||
@ -216,6 +253,12 @@
|
||||
}
|
||||
|
||||
|
||||
#undef STARTDATA
|
||||
#undef STARTDATA_LEN
|
||||
#undef SFNTS
|
||||
#undef SFNTS_LEN
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
cid_parser_done( CID_Parser* parser )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user