... |
... |
@@ -27,6 +27,16 @@ |
27
|
27
|
#include "psauxerr.h"
|
28
|
28
|
|
29
|
29
|
|
|
30
|
+ /**************************************************************************
|
|
31
|
+ *
|
|
32
|
+ * The macro FT_COMPONENT is used in trace mode. It is an implicit
|
|
33
|
+ * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
|
|
34
|
+ * messages during execution.
|
|
35
|
+ */
|
|
36
|
+#undef FT_COMPONENT
|
|
37
|
+#define FT_COMPONENT afmparse
|
|
38
|
+
|
|
39
|
+
|
30
|
40
|
/**************************************************************************
|
31
|
41
|
*
|
32
|
42
|
* AFM_Stream
|
... |
... |
@@ -586,21 +596,38 @@ |
586
|
596
|
static FT_Error
|
587
|
597
|
afm_parse_track_kern( AFM_Parser parser )
|
588
|
598
|
{
|
589
|
|
- AFM_FontInfo fi = parser->FontInfo;
|
|
599
|
+ AFM_FontInfo fi = parser->FontInfo;
|
|
600
|
+ AFM_Stream stream = parser->stream;
|
590
|
601
|
AFM_TrackKern tk;
|
591
|
|
- char* key;
|
592
|
|
- FT_Offset len;
|
593
|
|
- int n = -1;
|
594
|
|
- FT_Int tmp;
|
|
602
|
+
|
|
603
|
+ char* key;
|
|
604
|
+ FT_Offset len;
|
|
605
|
+ int n = -1;
|
|
606
|
+ FT_Int tmp;
|
595
|
607
|
|
596
|
608
|
|
597
|
609
|
if ( afm_parser_read_int( parser, &tmp ) )
|
598
|
610
|
goto Fail;
|
599
|
611
|
|
600
|
612
|
if ( tmp < 0 )
|
|
613
|
+ {
|
|
614
|
+ FT_ERROR(( "afm_parse_track_kern: invalid number of track kerns\n" ));
|
601
|
615
|
goto Fail;
|
|
616
|
+ }
|
602
|
617
|
|
603
|
618
|
fi->NumTrackKern = (FT_UInt)tmp;
|
|
619
|
+ FT_TRACE3(( "afm_parse_track_kern: %u track kern%s expected\n",
|
|
620
|
+ fi->NumTrackKern,
|
|
621
|
+ fi->NumTrackKern == 1 ? "" : "s" ));
|
|
622
|
+
|
|
623
|
+ /* Rough sanity check: The minimum line length of the `TrackKern` */
|
|
624
|
+ /* command is 20 characters (including the EOL character). */
|
|
625
|
+ if ( ( stream->limit - stream->cursor ) / 20 < fi->NumTrackKern )
|
|
626
|
+ {
|
|
627
|
+ FT_ERROR(( "afm_parse_track_kern:"
|
|
628
|
+ " number of track kern entries exceeds stream size\n" ));
|
|
629
|
+ goto Fail;
|
|
630
|
+ }
|
604
|
631
|
|
605
|
632
|
if ( fi->NumTrackKern )
|
606
|
633
|
{
|
... |
... |
@@ -623,7 +650,10 @@ |
623
|
650
|
n++;
|
624
|
651
|
|
625
|
652
|
if ( n >= (int)fi->NumTrackKern )
|
626
|
|
- goto Fail;
|
|
653
|
+ {
|
|
654
|
+ FT_ERROR(( "afm_parse_track_kern: too many track kern data\n" ));
|
|
655
|
+ goto Fail;
|
|
656
|
+ }
|
627
|
657
|
|
628
|
658
|
tk = fi->TrackKerns + n;
|
629
|
659
|
|
... |
... |
@@ -633,7 +663,12 @@ |
633
|
663
|
shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
|
634
|
664
|
shared_vals[4].type = AFM_VALUE_TYPE_FIXED;
|
635
|
665
|
if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 )
|
|
666
|
+ {
|
|
667
|
+ FT_ERROR(( "afm_parse_track_kern:"
|
|
668
|
+ " insufficient number of parameters for entry %d\n",
|
|
669
|
+ n ));
|
636
|
670
|
goto Fail;
|
|
671
|
+ }
|
637
|
672
|
|
638
|
673
|
tk->degree = shared_vals[0].u.i;
|
639
|
674
|
tk->min_ptsize = shared_vals[1].u.f;
|
... |
... |
@@ -646,7 +681,19 @@ |
646
|
681
|
case AFM_TOKEN_ENDTRACKKERN:
|
647
|
682
|
case AFM_TOKEN_ENDKERNDATA:
|
648
|
683
|
case AFM_TOKEN_ENDFONTMETRICS:
|
649
|
|
- fi->NumTrackKern = (FT_UInt)( n + 1 );
|
|
684
|
+ tmp = n + 1;
|
|
685
|
+ if ( (FT_UInt)tmp != fi->NumTrackKern )
|
|
686
|
+ {
|
|
687
|
+ FT_TRACE1(( "afm_parse_track_kern: %s%d track kern entr%s seen\n",
|
|
688
|
+ tmp == 0 ? "" : "only ",
|
|
689
|
+ tmp,
|
|
690
|
+ tmp == 1 ? "y" : "ies" ));
|
|
691
|
+ fi->NumTrackKern = (FT_UInt)tmp;
|
|
692
|
+ }
|
|
693
|
+ else
|
|
694
|
+ FT_TRACE3(( "afm_parse_track_kern: %d track kern entr%s seen\n",
|
|
695
|
+ tmp,
|
|
696
|
+ tmp == 1 ? "y" : "ies" ));
|
650
|
697
|
return FT_Err_Ok;
|
651
|
698
|
|
652
|
699
|
case AFM_TOKEN_UNKNOWN:
|
... |
... |
@@ -690,7 +737,8 @@ |
690
|
737
|
static FT_Error
|
691
|
738
|
afm_parse_kern_pairs( AFM_Parser parser )
|
692
|
739
|
{
|
693
|
|
- AFM_FontInfo fi = parser->FontInfo;
|
|
740
|
+ AFM_FontInfo fi = parser->FontInfo;
|
|
741
|
+ AFM_Stream stream = parser->stream;
|
694
|
742
|
AFM_KernPair kp;
|
695
|
743
|
char* key;
|
696
|
744
|
FT_Offset len;
|
... |
... |
@@ -702,9 +750,25 @@ |
702
|
750
|
goto Fail;
|
703
|
751
|
|
704
|
752
|
if ( tmp < 0 )
|
|
753
|
+ {
|
|
754
|
+ FT_ERROR(( "afm_parse_kern_pairs: invalid number of kern pairs\n" ));
|
705
|
755
|
goto Fail;
|
|
756
|
+ }
|
706
|
757
|
|
707
|
758
|
fi->NumKernPair = (FT_UInt)tmp;
|
|
759
|
+ FT_TRACE3(( "afm_parse_kern_pairs: %u kern pair%s expected\n",
|
|
760
|
+ fi->NumKernPair,
|
|
761
|
+ fi->NumKernPair == 1 ? "" : "s" ));
|
|
762
|
+
|
|
763
|
+ /* Rough sanity check: The minimum line length of the `KP`, */
|
|
764
|
+ /* `KPH`,`KPX`, and `KPY` commands is 10 characters (including */
|
|
765
|
+ /* the EOL character). */
|
|
766
|
+ if ( ( stream->limit - stream->cursor ) / 10 < fi->NumKernPair )
|
|
767
|
+ {
|
|
768
|
+ FT_ERROR(( "afm_parse_kern_pairs:"
|
|
769
|
+ " number of kern pairs exceeds stream size\n" ));
|
|
770
|
+ goto Fail;
|
|
771
|
+ }
|
708
|
772
|
|
709
|
773
|
if ( fi->NumKernPair )
|
710
|
774
|
{
|
... |
... |
@@ -734,7 +798,10 @@ |
734
|
798
|
n++;
|
735
|
799
|
|
736
|
800
|
if ( n >= (int)fi->NumKernPair )
|
|
801
|
+ {
|
|
802
|
+ FT_ERROR(( "afm_parse_kern_pairs: too many kern pairs\n" ));
|
737
|
803
|
goto Fail;
|
|
804
|
+ }
|
738
|
805
|
|
739
|
806
|
kp = fi->KernPairs + n;
|
740
|
807
|
|
... |
... |
@@ -744,7 +811,12 @@ |
744
|
811
|
shared_vals[3].type = AFM_VALUE_TYPE_INTEGER;
|
745
|
812
|
r = afm_parser_read_vals( parser, shared_vals, 4 );
|
746
|
813
|
if ( r < 3 )
|
|
814
|
+ {
|
|
815
|
+ FT_ERROR(( "afm_parse_kern_pairs:"
|
|
816
|
+ " insufficient number of parameters for entry %d\n",
|
|
817
|
+ n ));
|
747
|
818
|
goto Fail;
|
|
819
|
+ }
|
748
|
820
|
|
749
|
821
|
/* index values can't be negative */
|
750
|
822
|
kp->index1 = shared_vals[0].u.u;
|
... |
... |
@@ -766,7 +838,20 @@ |
766
|
838
|
case AFM_TOKEN_ENDKERNPAIRS:
|
767
|
839
|
case AFM_TOKEN_ENDKERNDATA:
|
768
|
840
|
case AFM_TOKEN_ENDFONTMETRICS:
|
769
|
|
- fi->NumKernPair = (FT_UInt)( n + 1 );
|
|
841
|
+ tmp = n + 1;
|
|
842
|
+ if ( (FT_UInt)tmp != fi->NumKernPair )
|
|
843
|
+ {
|
|
844
|
+ FT_TRACE1(( "afm_parse_kern_pairs: %s%d kern pair%s seen\n",
|
|
845
|
+ tmp == 0 ? "" : "only ",
|
|
846
|
+ tmp,
|
|
847
|
+ tmp == 1 ? "" : "s" ));
|
|
848
|
+ fi->NumKernPair = (FT_UInt)tmp;
|
|
849
|
+ }
|
|
850
|
+ else
|
|
851
|
+ FT_TRACE3(( "afm_parse_kern_pairs: %d kern pair%s seen\n",
|
|
852
|
+ tmp,
|
|
853
|
+ tmp == 1 ? "" : "s" ));
|
|
854
|
+
|
770
|
855
|
ft_qsort( fi->KernPairs, fi->NumKernPair,
|
771
|
856
|
sizeof ( AFM_KernPairRec ),
|
772
|
857
|
afm_compare_kern_pairs );
|
... |
... |
@@ -792,22 +877,43 @@ |
792
|
877
|
char* key;
|
793
|
878
|
FT_Offset len;
|
794
|
879
|
|
|
880
|
+ int have_trackkern = 0;
|
|
881
|
+ int have_kernpairs = 0;
|
|
882
|
+
|
795
|
883
|
|
796
|
884
|
while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
|
797
|
885
|
{
|
798
|
886
|
switch ( afm_tokenize( key, len ) )
|
799
|
887
|
{
|
800
|
888
|
case AFM_TOKEN_STARTTRACKKERN:
|
|
889
|
+ if ( have_trackkern )
|
|
890
|
+ {
|
|
891
|
+ FT_ERROR(( "afm_parse_kern_data:"
|
|
892
|
+ " invalid second horizontal track kern section\n" ));
|
|
893
|
+ goto Fail;
|
|
894
|
+ }
|
|
895
|
+
|
801
|
896
|
error = afm_parse_track_kern( parser );
|
802
|
897
|
if ( error )
|
803
|
898
|
return error;
|
|
899
|
+
|
|
900
|
+ have_trackkern = 1;
|
804
|
901
|
break;
|
805
|
902
|
|
806
|
903
|
case AFM_TOKEN_STARTKERNPAIRS:
|
807
|
904
|
case AFM_TOKEN_STARTKERNPAIRS0:
|
|
905
|
+ if ( have_kernpairs )
|
|
906
|
+ {
|
|
907
|
+ FT_ERROR(( "afm_parse_kern_data:"
|
|
908
|
+ " invalid second horizontal kern pair section\n" ));
|
|
909
|
+ goto Fail;
|
|
910
|
+ }
|
|
911
|
+
|
808
|
912
|
error = afm_parse_kern_pairs( parser );
|
809
|
913
|
if ( error )
|
810
|
914
|
return error;
|
|
915
|
+
|
|
916
|
+ have_kernpairs = 1;
|
811
|
917
|
break;
|
812
|
918
|
|
813
|
919
|
case AFM_TOKEN_ENDKERNDATA:
|