ref: b553fcb514a5e7131d34a117bf2d01e034ab7a08
parent: b653a2307921c0319043c5f5ecc1243ee9786d87
author: Werner Lemberg <[email protected]>
date: Tue Feb 28 10:11:21 EST 2017
[sfnt] Further generalize `sfnt_get_ps_name'; report invalid data. * src/sfnt/sfdriver.c (sfnt_ps_map): New array. (sfnt_is_postscript): New function. (char_type_func): New typedef. (get_win_string, get_apple_string): Add argument to specify character checking function. Add argument whether argument checking failures should be reported. Update callers. (search_name_id): Fix return value.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2017-02-23 Werner Lemberg <[email protected]>
+ [sfnt] Further generalize `sfnt_get_ps_name'; report invalid data.
+
+ * src/sfnt/sfdriver.c (sfnt_ps_map): New array.
+ (sfnt_is_postscript): New function.
+ (char_type_func): New typedef.
+ (get_win_string, get_apple_string): Add argument to specify
+ character checking function.
+ Add argument whether argument checking failures should be reported.
+ Update callers.
+ (search_name_id): Fix return value.
+
+2017-02-23 Werner Lemberg <[email protected]>
+
[sfnt] Split off another bit of `sfnt_get_ps_name'.
* src/sfnt/sfdriver.c (sfnt_get_ps_name): Split off some
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -220,6 +220,39 @@
*
*/
+ /* an array representing allowed ASCII characters in a PS string */
+ static const unsigned char sfnt_ps_map[16] =
+ {
+ /* 4 0 C 8 */
+ 0x00, 0x00, /* 0x00: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */
+ 0x00, 0x00, /* 0x10: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */
+ 0xDE, 0x7C, /* 0x20: 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 0 */
+ 0xFF, 0xAF, /* 0x30: 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 */
+ 0xFF, 0xFF, /* 0x40: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */
+ 0xFF, 0xD7, /* 0x50: 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 */
+ 0xFF, 0xFF, /* 0x60: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */
+ 0xFF, 0x57 /* 0x70: 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 */
+ };
+
+
+ static int
+ sfnt_is_postscript( int c )
+ {
+ unsigned int cc;
+
+
+ if ( c < 0 || c >= 0x80 )
+ return 0;
+
+ cc = (unsigned int)c;
+
+ return sfnt_ps_map[cc >> 3] & ( 1 << ( cc & 0x07 ) );
+ }
+
+
+ typedef int (*char_type_func)( int c );
+
+
/* handling of PID/EID 3/0 and 3/1 is the same */
#define IS_WIN( n ) ( (n)->platformID == 3 && \
( (n)->encodingID == 1 || (n)->encodingID == 0 ) && \
@@ -230,9 +263,11 @@
(n)->languageID == 0 )
static const char*
- get_win_string( FT_Memory memory,
- FT_Stream stream,
- TT_Name entry )
+ get_win_string( FT_Memory memory,
+ FT_Stream stream,
+ TT_Name entry,
+ char_type_func char_type,
+ FT_Bool report_invalid_characters )
{
FT_Error error = FT_Err_Ok;
@@ -263,8 +298,22 @@
for ( len = entry->stringLength / 2; len > 0; len--, p += 2 )
{
- if ( p[0] == 0 && p[1] >= 32 )
- *r++ = p[1];
+ if ( p[0] == 0 )
+ {
+ if ( char_type( p[1] ) )
+ *r++ = p[1];
+ else
+ {
+ if ( report_invalid_characters )
+ {
+ FT_TRACE0(( "get_win_string:"
+ " Character `%c' (0x%X) invalid in PS name string\n",
+ p[1], p[1] ));
+ /* it's not the job of FreeType to correct PS names... */
+ *r++ = p[1];
+ }
+ }
+ }
}
*r = '\0';
@@ -275,13 +324,18 @@
static const char*
- get_apple_string( FT_Memory memory,
- FT_Stream stream,
- TT_Name entry )
+ get_apple_string( FT_Memory memory,
+ FT_Stream stream,
+ TT_Name entry,
+ char_type_func char_type,
+ FT_Bool report_invalid_characters )
{
FT_Error error = FT_Err_Ok;
const char* result;
+ FT_String* r;
+ FT_Char* p;
+ FT_UInt len;
FT_UNUSED( error );
@@ -289,8 +343,8 @@
if ( FT_ALLOC( result, entry->stringLength + 1 ) )
return NULL;
- if ( FT_STREAM_SEEK( entry->stringOffset ) ||
- FT_STREAM_READ( result, entry->stringLength ) )
+ if ( FT_STREAM_SEEK( entry->stringOffset ) ||
+ FT_FRAME_ENTER( entry->stringLength ) )
{
FT_FREE( result );
entry->stringOffset = 0;
@@ -300,8 +354,29 @@
return NULL;
}
- ((char*)result)[entry->stringLength] = '\0';
+ r = (FT_String*)result;
+ p = (FT_Char*)stream->cursor;
+ for ( len = entry->stringLength; len > 0; len--, p++ )
+ {
+ if ( char_type( *p ) )
+ *r++ = *p;
+ else
+ {
+ if ( report_invalid_characters )
+ {
+ FT_TRACE0(( "get_apple_string:"
+ " Character `%c' (0x%X) invalid in PS name string\n",
+ *p, *p ));
+ /* it's not the job of FreeType to correct PS names... */
+ *r++ = *p;
+ }
+ }
+ }
+ *r = '\0';
+
+ FT_FRAME_EXIT();
+
return result;
}
@@ -333,7 +408,7 @@
}
}
- return *win || *apple;
+ return ( *win >= 0 ) || ( *apple >= 0 );
}
@@ -340,7 +415,7 @@
static const char*
sfnt_get_ps_name( TT_Face face )
{
- FT_Int found_win, found_apple;
+ FT_Int found, win, apple;
const char* result = NULL;
@@ -349,17 +424,24 @@
/* scan the name table to see whether we have a Postscript name here, */
/* either in Macintosh or Windows platform encodings */
- search_name_id( face, 6, &found_win, &found_apple );
+ found = search_name_id( face, 6, &win, &apple );
- /* prefer Windows entries over Apple */
- if ( found_win != -1 )
- result = get_win_string( face->root.memory,
- face->name_table.stream,
- face->name_table.names + found_win );
- else if ( found_apple != -1 )
- result = get_apple_string( face->root.memory,
+ if ( found )
+ {
+ /* prefer Windows entries over Apple */
+ if ( win != -1 )
+ result = get_win_string( face->root.memory,
face->name_table.stream,
- face->name_table.names + found_apple );
+ face->name_table.names + win,
+ sfnt_is_postscript,
+ 1 );
+ else
+ result = get_apple_string( face->root.memory,
+ face->name_table.stream,
+ face->name_table.names + apple,
+ sfnt_is_postscript,
+ 1 );
+ }
face->postscript_name = result;