* src/sfnt/sfdriver.c, src/sfnt/ttbdf.c: Clean up interface.

Ensure that all driver functions use the signature of the service or driver.
This avoids pointer mismatches, which are technically undefined behaviour.
Recent compilers are more picky in catching them as part of Control Flow
Integrity tests.

* src/sfnt/sfdriver.c (sfnt_load_table): New wrapper function.
(sfnt_service_sfnt_table): Use it.
This commit is contained in:
Werner Lemberg 2023-05-06 23:59:25 +02:00
parent ceba488cf8
commit e245951c43
3 changed files with 66 additions and 44 deletions

View File

@ -79,41 +79,57 @@
* *
*/ */
static void* FT_CALLBACK_DEF( FT_Error )
get_sfnt_table( TT_Face face, sfnt_load_table( FT_Face face, /* TT_Face */
FT_ULong tag,
FT_Long offset,
FT_Byte* buffer,
FT_ULong* length )
{
TT_Face ttface = (TT_Face)face;
return tt_face_load_any( ttface, tag, offset, buffer, length );
}
FT_CALLBACK_DEF( void* )
get_sfnt_table( FT_Face face, /* TT_Face */
FT_Sfnt_Tag tag ) FT_Sfnt_Tag tag )
{ {
TT_Face ttface = (TT_Face)face;
void* table; void* table;
switch ( tag ) switch ( tag )
{ {
case FT_SFNT_HEAD: case FT_SFNT_HEAD:
table = &face->header; table = &ttface->header;
break; break;
case FT_SFNT_HHEA: case FT_SFNT_HHEA:
table = &face->horizontal; table = &ttface->horizontal;
break; break;
case FT_SFNT_VHEA: case FT_SFNT_VHEA:
table = face->vertical_info ? &face->vertical : NULL; table = ttface->vertical_info ? &ttface->vertical : NULL;
break; break;
case FT_SFNT_OS2: case FT_SFNT_OS2:
table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2; table = ( ttface->os2.version == 0xFFFFU ) ? NULL : &ttface->os2;
break; break;
case FT_SFNT_POST: case FT_SFNT_POST:
table = &face->postscript; table = &ttface->postscript;
break; break;
case FT_SFNT_MAXP: case FT_SFNT_MAXP:
table = &face->max_profile; table = &ttface->max_profile;
break; break;
case FT_SFNT_PCLT: case FT_SFNT_PCLT:
table = face->pclt.Version ? &face->pclt : NULL; table = ttface->pclt.Version ? &ttface->pclt : NULL;
break; break;
default: default:
@ -124,26 +140,29 @@
} }
static FT_Error FT_CALLBACK_DEF( FT_Error )
sfnt_table_info( TT_Face face, sfnt_table_info( FT_Face face, /* TT_Face */
FT_UInt idx, FT_UInt idx,
FT_ULong *tag, FT_ULong *tag,
FT_ULong *offset, FT_ULong *offset,
FT_ULong *length ) FT_ULong *length )
{ {
TT_Face ttface = (TT_Face)face;
if ( !offset || !length ) if ( !offset || !length )
return FT_THROW( Invalid_Argument ); return FT_THROW( Invalid_Argument );
if ( !tag ) if ( !tag )
*length = face->num_tables; *length = ttface->num_tables;
else else
{ {
if ( idx >= face->num_tables ) if ( idx >= ttface->num_tables )
return FT_THROW( Table_Missing ); return FT_THROW( Table_Missing );
*tag = face->dir_tables[idx].Tag; *tag = ttface->dir_tables[idx].Tag;
*offset = face->dir_tables[idx].Offset; *offset = ttface->dir_tables[idx].Offset;
*length = face->dir_tables[idx].Length; *length = ttface->dir_tables[idx].Length;
} }
return FT_Err_Ok; return FT_Err_Ok;
@ -153,7 +172,7 @@
FT_DEFINE_SERVICE_SFNT_TABLEREC( FT_DEFINE_SERVICE_SFNT_TABLEREC(
sfnt_service_sfnt_table, sfnt_service_sfnt_table,
(FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ (FT_SFNT_TableLoadFunc)sfnt_load_table, /* load_table */
(FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */
(FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */ (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */
) )
@ -166,7 +185,7 @@
* *
*/ */
static FT_Error FT_CALLBACK_DEF( FT_Error )
sfnt_get_glyph_name( FT_Face face, sfnt_get_glyph_name( FT_Face face,
FT_UInt glyph_index, FT_UInt glyph_index,
FT_Pointer buffer, FT_Pointer buffer,
@ -184,7 +203,7 @@
} }
static FT_UInt FT_CALLBACK_DEF( FT_UInt )
sfnt_get_name_index( FT_Face face, sfnt_get_name_index( FT_Face face,
const FT_String* glyph_name ) const FT_String* glyph_name )
{ {
@ -600,7 +619,7 @@
} }
static FT_Bool FT_CALLBACK_DEF( FT_Bool )
sfnt_get_name_id( TT_Face face, sfnt_get_name_id( TT_Face face,
FT_UShort id, FT_UShort id,
FT_Int *win, FT_Int *win,
@ -1043,47 +1062,49 @@
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
static const char* FT_CALLBACK_DEF( const char* )
sfnt_get_ps_name( TT_Face face ) sfnt_get_ps_name( FT_Face face ) /* TT_Face */
{ {
TT_Face ttface = (TT_Face)face;
FT_Int found, win, apple; FT_Int found, win, apple;
const char* result = NULL; const char* result = NULL;
if ( face->postscript_name ) if ( ttface->postscript_name )
return face->postscript_name; return ttface->postscript_name;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( face->blend && if ( ttface->blend &&
( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || ( FT_IS_NAMED_INSTANCE( face ) ||
FT_IS_VARIATION( FT_FACE( face ) ) ) ) FT_IS_VARIATION( face ) ) )
{ {
face->postscript_name = sfnt_get_var_ps_name( face ); ttface->postscript_name = sfnt_get_var_ps_name( ttface );
return face->postscript_name; return ttface->postscript_name;
} }
#endif #endif
/* scan the name table to see whether we have a Postscript name here, */ /* scan the name table to see whether we have a Postscript name here, */
/* either in Macintosh or Windows platform encodings */ /* either in Macintosh or Windows platform encodings */
found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple ); found = sfnt_get_name_id( ttface, TT_NAME_ID_PS_NAME, &win, &apple );
if ( !found ) if ( !found )
return NULL; return NULL;
/* prefer Windows entries over Apple */ /* prefer Windows entries over Apple */
if ( win != -1 ) if ( win != -1 )
result = get_win_string( face->root.memory, result = get_win_string( FT_FACE_MEMORY( face ),
face->name_table.stream, ttface->name_table.stream,
face->name_table.names + win, ttface->name_table.names + win,
sfnt_is_postscript, sfnt_is_postscript,
1 ); 1 );
if ( !result && apple != -1 ) if ( !result && apple != -1 )
result = get_apple_string( face->root.memory, result = get_apple_string( FT_FACE_MEMORY( face ),
face->name_table.stream, ttface->name_table.stream,
face->name_table.names + apple, ttface->name_table.names + apple,
sfnt_is_postscript, sfnt_is_postscript,
1 ); 1 );
face->postscript_name = result; ttface->postscript_name = result;
return result; return result;
} }
@ -1109,7 +1130,7 @@
#ifdef TT_CONFIG_OPTION_BDF #ifdef TT_CONFIG_OPTION_BDF
static FT_Error static FT_Error
sfnt_get_charset_id( TT_Face face, sfnt_get_charset_id( FT_Face face,
const char* *acharset_encoding, const char* *acharset_encoding,
const char* *acharset_registry ) const char* *acharset_registry )
{ {

View File

@ -136,13 +136,14 @@
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
tt_face_find_bdf_prop( TT_Face face, tt_face_find_bdf_prop( FT_Face face, /* TT_Face */
const char* property_name, const char* property_name,
BDF_PropertyRec *aprop ) BDF_PropertyRec *aprop )
{ {
TT_BDF bdf = &face->bdf; TT_Face ttface = (TT_Face)face;
FT_Size size = FT_FACE( face )->size; TT_BDF bdf = &ttface->bdf;
FT_Error error = FT_Err_Ok; FT_Size size = FT_FACE_SIZE( face );
FT_Error error = FT_Err_Ok;
FT_Byte* p; FT_Byte* p;
FT_UInt count; FT_UInt count;
FT_Byte* strike; FT_Byte* strike;
@ -153,7 +154,7 @@
if ( bdf->loaded == 0 ) if ( bdf->loaded == 0 )
{ {
error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); error = tt_face_load_bdf_props( ttface, FT_FACE_STREAM( face ) );
if ( error ) if ( error )
goto Exit; goto Exit;
} }

View File

@ -34,7 +34,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error ) FT_LOCAL( FT_Error )
tt_face_find_bdf_prop( TT_Face face, tt_face_find_bdf_prop( FT_Face face,
const char* property_name, const char* property_name,
BDF_PropertyRec *aprop ); BDF_PropertyRec *aprop );