summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/psaux/afmparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/psaux/afmparse.c')
-rw-r--r--src/3rdparty/freetype/src/psaux/afmparse.c143
1 files changed, 125 insertions, 18 deletions
diff --git a/src/3rdparty/freetype/src/psaux/afmparse.c b/src/3rdparty/freetype/src/psaux/afmparse.c
index f78adbba3d..db08941def 100644
--- a/src/3rdparty/freetype/src/psaux/afmparse.c
+++ b/src/3rdparty/freetype/src/psaux/afmparse.c
@@ -4,7 +4,7 @@
*
* AFM parser (body).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -15,10 +15,9 @@
*
*/
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include <freetype/freetype.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/psaux.h>
#ifndef T1_CONFIG_OPTION_NO_AFM
@@ -30,6 +29,16 @@
/**************************************************************************
*
+ * The macro FT_COMPONENT is used in trace mode. It is an implicit
+ * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+ * messages during execution.
+ */
+#undef FT_COMPONENT
+#define FT_COMPONENT afmparse
+
+
+ /**************************************************************************
+ *
* AFM_Stream
*
* The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib.
@@ -554,7 +563,7 @@
}
- FT_LOCAL( void )
+ FT_LOCAL_DEF( void )
afm_parser_done( AFM_Parser parser )
{
FT_Memory memory = parser->memory;
@@ -587,21 +596,39 @@
static FT_Error
afm_parse_track_kern( AFM_Parser parser )
{
- AFM_FontInfo fi = parser->FontInfo;
+ AFM_FontInfo fi = parser->FontInfo;
+ AFM_Stream stream = parser->stream;
AFM_TrackKern tk;
- char* key;
- FT_Offset len;
- int n = -1;
- FT_Int tmp;
+
+ char* key;
+ FT_Offset len;
+ int n = -1;
+ FT_Int tmp;
if ( afm_parser_read_int( parser, &tmp ) )
goto Fail;
if ( tmp < 0 )
+ {
+ FT_ERROR(( "afm_parse_track_kern: invalid number of track kerns\n" ));
goto Fail;
+ }
fi->NumTrackKern = (FT_UInt)tmp;
+ FT_TRACE3(( "afm_parse_track_kern: %u track kern%s expected\n",
+ fi->NumTrackKern,
+ fi->NumTrackKern == 1 ? "" : "s" ));
+
+ /* Rough sanity check: The minimum line length of the `TrackKern` */
+ /* command is 20 characters (including the EOL character). */
+ if ( (FT_ULong)( stream->limit - stream->cursor ) / 20 <
+ fi->NumTrackKern )
+ {
+ FT_ERROR(( "afm_parse_track_kern:"
+ " number of track kern entries exceeds stream size\n" ));
+ goto Fail;
+ }
if ( fi->NumTrackKern )
{
@@ -624,7 +651,10 @@
n++;
if ( n >= (int)fi->NumTrackKern )
- goto Fail;
+ {
+ FT_ERROR(( "afm_parse_track_kern: too many track kern data\n" ));
+ goto Fail;
+ }
tk = fi->TrackKerns + n;
@@ -634,7 +664,12 @@
shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
shared_vals[4].type = AFM_VALUE_TYPE_FIXED;
if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 )
+ {
+ FT_ERROR(( "afm_parse_track_kern:"
+ " insufficient number of parameters for entry %d\n",
+ n ));
goto Fail;
+ }
tk->degree = shared_vals[0].u.i;
tk->min_ptsize = shared_vals[1].u.f;
@@ -647,7 +682,19 @@
case AFM_TOKEN_ENDTRACKKERN:
case AFM_TOKEN_ENDKERNDATA:
case AFM_TOKEN_ENDFONTMETRICS:
- fi->NumTrackKern = (FT_UInt)( n + 1 );
+ tmp = n + 1;
+ if ( (FT_UInt)tmp != fi->NumTrackKern )
+ {
+ FT_TRACE1(( "afm_parse_track_kern: %s%d track kern entr%s seen\n",
+ tmp == 0 ? "" : "only ",
+ tmp,
+ tmp == 1 ? "y" : "ies" ));
+ fi->NumTrackKern = (FT_UInt)tmp;
+ }
+ else
+ FT_TRACE3(( "afm_parse_track_kern: %d track kern entr%s seen\n",
+ tmp,
+ tmp == 1 ? "y" : "ies" ));
return FT_Err_Ok;
case AFM_TOKEN_UNKNOWN:
@@ -668,7 +715,7 @@
/* compare two kerning pairs */
- FT_CALLBACK_DEF( int )
+ FT_COMPARE_DEF( int )
afm_compare_kern_pairs( const void* a,
const void* b )
{
@@ -691,7 +738,8 @@
static FT_Error
afm_parse_kern_pairs( AFM_Parser parser )
{
- AFM_FontInfo fi = parser->FontInfo;
+ AFM_FontInfo fi = parser->FontInfo;
+ AFM_Stream stream = parser->stream;
AFM_KernPair kp;
char* key;
FT_Offset len;
@@ -703,9 +751,26 @@
goto Fail;
if ( tmp < 0 )
+ {
+ FT_ERROR(( "afm_parse_kern_pairs: invalid number of kern pairs\n" ));
goto Fail;
+ }
fi->NumKernPair = (FT_UInt)tmp;
+ FT_TRACE3(( "afm_parse_kern_pairs: %u kern pair%s expected\n",
+ fi->NumKernPair,
+ fi->NumKernPair == 1 ? "" : "s" ));
+
+ /* Rough sanity check: The minimum line length of the `KP`, */
+ /* `KPH`,`KPX`, and `KPY` commands is 10 characters (including */
+ /* the EOL character). */
+ if ( (FT_ULong)( stream->limit - stream->cursor ) / 10 <
+ fi->NumKernPair )
+ {
+ FT_ERROR(( "afm_parse_kern_pairs:"
+ " number of kern pairs exceeds stream size\n" ));
+ goto Fail;
+ }
if ( fi->NumKernPair )
{
@@ -735,7 +800,10 @@
n++;
if ( n >= (int)fi->NumKernPair )
+ {
+ FT_ERROR(( "afm_parse_kern_pairs: too many kern pairs\n" ));
goto Fail;
+ }
kp = fi->KernPairs + n;
@@ -745,7 +813,12 @@
shared_vals[3].type = AFM_VALUE_TYPE_INTEGER;
r = afm_parser_read_vals( parser, shared_vals, 4 );
if ( r < 3 )
+ {
+ FT_ERROR(( "afm_parse_kern_pairs:"
+ " insufficient number of parameters for entry %d\n",
+ n ));
goto Fail;
+ }
/* index values can't be negative */
kp->index1 = shared_vals[0].u.u;
@@ -767,7 +840,20 @@
case AFM_TOKEN_ENDKERNPAIRS:
case AFM_TOKEN_ENDKERNDATA:
case AFM_TOKEN_ENDFONTMETRICS:
- fi->NumKernPair = (FT_UInt)( n + 1 );
+ tmp = n + 1;
+ if ( (FT_UInt)tmp != fi->NumKernPair )
+ {
+ FT_TRACE1(( "afm_parse_kern_pairs: %s%d kern pair%s seen\n",
+ tmp == 0 ? "" : "only ",
+ tmp,
+ tmp == 1 ? "" : "s" ));
+ fi->NumKernPair = (FT_UInt)tmp;
+ }
+ else
+ FT_TRACE3(( "afm_parse_kern_pairs: %d kern pair%s seen\n",
+ tmp,
+ tmp == 1 ? "" : "s" ));
+
ft_qsort( fi->KernPairs, fi->NumKernPair,
sizeof ( AFM_KernPairRec ),
afm_compare_kern_pairs );
@@ -793,22 +879,43 @@
char* key;
FT_Offset len;
+ int have_trackkern = 0;
+ int have_kernpairs = 0;
+
while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
{
switch ( afm_tokenize( key, len ) )
{
case AFM_TOKEN_STARTTRACKKERN:
+ if ( have_trackkern )
+ {
+ FT_ERROR(( "afm_parse_kern_data:"
+ " invalid second horizontal track kern section\n" ));
+ goto Fail;
+ }
+
error = afm_parse_track_kern( parser );
if ( error )
return error;
+
+ have_trackkern = 1;
break;
case AFM_TOKEN_STARTKERNPAIRS:
case AFM_TOKEN_STARTKERNPAIRS0:
+ if ( have_kernpairs )
+ {
+ FT_ERROR(( "afm_parse_kern_data:"
+ " invalid second horizontal kern pair section\n" ));
+ goto Fail;
+ }
+
error = afm_parse_kern_pairs( parser );
if ( error )
return error;
+
+ have_kernpairs = 1;
break;
case AFM_TOKEN_ENDKERNDATA:
@@ -954,7 +1061,7 @@
if ( error )
goto Fail;
/* we only support kern data, so ... */
- /* fall through */
+ FALL_THROUGH;
case AFM_TOKEN_ENDFONTMETRICS:
return FT_Err_Ok;
@@ -979,7 +1086,7 @@
#else /* T1_CONFIG_OPTION_NO_AFM */
/* ANSI C doesn't like empty source files */
- typedef int _afm_parse_dummy;
+ typedef int afm_parse_dummy_;
#endif /* T1_CONFIG_OPTION_NO_AFM */