... |
... |
@@ -728,7 +728,7 @@ |
728
|
728
|
{
|
729
|
729
|
FT_ULong fpgm_length = 0;
|
730
|
730
|
FT_ULong prep_length = 0;
|
731
|
|
- FT_ULong loca_length = 0;
|
|
731
|
+ FT_ULong loca_length;
|
732
|
732
|
FT_ULong glyf_length = 0;
|
733
|
733
|
FT_UShort i;
|
734
|
734
|
FT_Byte* buffer = NULL;
|
... |
... |
@@ -770,50 +770,68 @@ |
770
|
770
|
Print_Bytecode( buffer, (FT_UShort)prep_length, "prep" );
|
771
|
771
|
|
772
|
772
|
Glyf:
|
773
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
|
774
|
|
- if ( error || glyf_length == 0 )
|
|
773
|
+ head = (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
|
|
774
|
+ maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
|
|
775
|
+
|
|
776
|
+ if ( head == NULL || maxp == NULL )
|
775
|
777
|
goto Exit;
|
776
|
778
|
|
777
|
|
- buffer = (FT_Byte*)realloc( buffer, glyf_length );
|
778
|
|
- if ( buffer == NULL )
|
|
779
|
+ loca_length = head->Index_To_Loc_Format ? 4 * maxp->numGlyphs + 4
|
|
780
|
+ : 2 * maxp->numGlyphs + 2;
|
|
781
|
+
|
|
782
|
+ offset = (FT_Byte*)malloc( loca_length );
|
|
783
|
+ if ( offset == NULL )
|
779
|
784
|
goto Exit;
|
780
|
785
|
|
781
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
|
|
786
|
+ error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
|
782
|
787
|
if ( error )
|
783
|
788
|
goto Exit;
|
784
|
789
|
|
785
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, NULL, &loca_length );
|
786
|
|
- if ( error || loca_length == 0 )
|
|
790
|
+ error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
|
|
791
|
+ if ( error || glyf_length == 0 )
|
787
|
792
|
goto Exit;
|
788
|
793
|
|
789
|
|
- offset = (FT_Byte*)malloc( loca_length );
|
790
|
|
- if ( offset == NULL )
|
|
794
|
+ buffer = (FT_Byte*)realloc( buffer, glyf_length );
|
|
795
|
+ if ( buffer == NULL )
|
791
|
796
|
goto Exit;
|
792
|
797
|
|
793
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
|
|
798
|
+ error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
|
794
|
799
|
if ( error )
|
795
|
800
|
goto Exit;
|
796
|
801
|
|
797
|
|
- head = (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
|
798
|
|
- maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
|
799
|
|
-
|
800
|
802
|
for ( i = 0; i < maxp->numGlyphs; i++ )
|
801
|
803
|
{
|
802
|
|
- FT_UInt32 loc;
|
|
804
|
+ FT_UInt32 loc, end;
|
803
|
805
|
FT_UInt16 len;
|
804
|
806
|
char tag[5];
|
805
|
807
|
|
806
|
808
|
|
807
|
809
|
if ( head->Index_To_Loc_Format )
|
|
810
|
+ {
|
808
|
811
|
loc = (FT_UInt32)offset[4 * i ] << 24 |
|
809
|
812
|
(FT_UInt32)offset[4 * i + 1] << 16 |
|
810
|
813
|
(FT_UInt32)offset[4 * i + 2] << 8 |
|
811
|
814
|
(FT_UInt32)offset[4 * i + 3];
|
|
815
|
+ end = (FT_UInt32)offset[4 * i + 4] << 24 |
|
|
816
|
+ (FT_UInt32)offset[4 * i + 5] << 16 |
|
|
817
|
+ (FT_UInt32)offset[4 * i + 6] << 8 |
|
|
818
|
+ (FT_UInt32)offset[4 * i + 7];
|
|
819
|
+ }
|
812
|
820
|
else
|
|
821
|
+ {
|
813
|
822
|
loc = (FT_UInt32)offset[2 * i ] << 9 |
|
814
|
823
|
(FT_UInt32)offset[2 * i + 1] << 1;
|
|
824
|
+ end = (FT_UInt32)offset[2 * i + 2] << 9 |
|
|
825
|
+ (FT_UInt32)offset[2 * i + 3] << 1;
|
|
826
|
+ }
|
|
827
|
+
|
|
828
|
+ if ( end > glyf_length )
|
|
829
|
+ end = glyf_length;
|
815
|
830
|
|
816
|
|
- if ( loc >= glyf_length )
|
|
831
|
+ if ( loc == end )
|
|
832
|
+ continue;
|
|
833
|
+
|
|
834
|
+ if ( loc + 1 >= end )
|
817
|
835
|
{
|
818
|
836
|
printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
|
819
|
837
|
continue;
|
... |
... |
@@ -829,7 +847,7 @@ |
829
|
847
|
|
830
|
848
|
do
|
831
|
849
|
{
|
832
|
|
- if ( loc >= glyf_length )
|
|
850
|
+ if ( loc + 1 >= end )
|
833
|
851
|
{
|
834
|
852
|
printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
|
835
|
853
|
goto Continue;
|
... |
... |
@@ -852,7 +870,7 @@ |
852
|
870
|
else
|
853
|
871
|
loc += 2 * len;
|
854
|
872
|
|
855
|
|
- if ( loc >= glyf_length )
|
|
873
|
+ if ( loc + 1 >= end )
|
856
|
874
|
{
|
857
|
875
|
printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
|
858
|
876
|
continue;
|
... |
... |
@@ -865,7 +883,7 @@ |
865
|
883
|
|
866
|
884
|
loc += 2;
|
867
|
885
|
|
868
|
|
- if ( len >= glyf_length || loc >= glyf_length - len )
|
|
886
|
+ if ( loc + len > end )
|
869
|
887
|
{
|
870
|
888
|
printf( "\nglyf program %hd: invalid size (%d)\n", i, len );
|
871
|
889
|
continue;
|
... |
... |
@@ -888,7 +906,7 @@ |
888
|
906
|
static void
|
889
|
907
|
Print_Glyfs( FT_Face face )
|
890
|
908
|
{
|
891
|
|
- FT_ULong loca_length = 0;
|
|
909
|
+ FT_ULong loca_length;
|
892
|
910
|
FT_ULong glyf_length = 0;
|
893
|
911
|
FT_UShort i;
|
894
|
912
|
FT_Byte* buffer = NULL;
|
... |
... |
@@ -898,55 +916,77 @@ |
898
|
916
|
FT_Int simple_overlap = 0;
|
899
|
917
|
FT_Int composite = 0;
|
900
|
918
|
FT_Int composite_overlap = 0;
|
|
919
|
+ FT_Int empty = 0;
|
901
|
920
|
|
902
|
921
|
TT_Header* head;
|
903
|
922
|
TT_MaxProfile* maxp;
|
904
|
923
|
|
905
|
924
|
|
906
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
|
907
|
|
- if ( error || glyf_length == 0 )
|
908
|
|
- goto Exit;
|
|
925
|
+ head = (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
|
|
926
|
+ maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
|
909
|
927
|
|
910
|
|
- buffer = (FT_Byte*)malloc( glyf_length );
|
911
|
|
- if ( buffer == NULL )
|
|
928
|
+ if ( head == NULL || maxp == NULL )
|
|
929
|
+ return;
|
|
930
|
+
|
|
931
|
+ loca_length = head->Index_To_Loc_Format ? 4 * maxp->numGlyphs + 4
|
|
932
|
+ : 2 * maxp->numGlyphs + 2;
|
|
933
|
+
|
|
934
|
+ offset = (FT_Byte*)malloc( loca_length );
|
|
935
|
+ if ( offset == NULL )
|
912
|
936
|
goto Exit;
|
913
|
937
|
|
914
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
|
|
938
|
+ error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
|
915
|
939
|
if ( error )
|
916
|
940
|
goto Exit;
|
917
|
941
|
|
918
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, NULL, &loca_length );
|
919
|
|
- if ( error || loca_length == 0 )
|
|
942
|
+ error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
|
|
943
|
+ if ( error || glyf_length == 0 )
|
920
|
944
|
goto Exit;
|
921
|
945
|
|
922
|
|
- offset = (FT_Byte*)malloc( loca_length );
|
923
|
|
- if ( offset == NULL )
|
|
946
|
+ buffer = (FT_Byte*)malloc( glyf_length );
|
|
947
|
+ if ( buffer == NULL )
|
924
|
948
|
goto Exit;
|
925
|
949
|
|
926
|
|
- error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
|
|
950
|
+ error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
|
927
|
951
|
if ( error )
|
928
|
952
|
goto Exit;
|
929
|
953
|
|
930
|
|
- head = (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
|
931
|
|
- maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
|
932
|
|
-
|
933
|
954
|
for ( i = 0; i < maxp->numGlyphs; i++ )
|
934
|
955
|
{
|
935
|
|
- FT_UInt32 loc;
|
|
956
|
+ FT_UInt32 loc, end;
|
936
|
957
|
FT_UInt16 len;
|
937
|
958
|
FT_UShort flags;
|
938
|
959
|
|
939
|
960
|
|
940
|
961
|
if ( head->Index_To_Loc_Format )
|
|
962
|
+ {
|
941
|
963
|
loc = (FT_UInt32)offset[4 * i ] << 24 |
|
942
|
964
|
(FT_UInt32)offset[4 * i + 1] << 16 |
|
943
|
965
|
(FT_UInt32)offset[4 * i + 2] << 8 |
|
944
|
966
|
(FT_UInt32)offset[4 * i + 3];
|
|
967
|
+ end = (FT_UInt32)offset[4 * i + 4] << 24 |
|
|
968
|
+ (FT_UInt32)offset[4 * i + 5] << 16 |
|
|
969
|
+ (FT_UInt32)offset[4 * i + 6] << 8 |
|
|
970
|
+ (FT_UInt32)offset[4 * i + 7];
|
|
971
|
+ }
|
945
|
972
|
else
|
|
973
|
+ {
|
946
|
974
|
loc = (FT_UInt32)offset[2 * i ] << 9 |
|
947
|
975
|
(FT_UInt32)offset[2 * i + 1] << 1;
|
|
976
|
+ end = (FT_UInt32)offset[2 * i + 2] << 9 |
|
|
977
|
+ (FT_UInt32)offset[2 * i + 3] << 1;
|
|
978
|
+ }
|
|
979
|
+
|
|
980
|
+ if ( end > glyf_length )
|
|
981
|
+ end = glyf_length;
|
|
982
|
+
|
|
983
|
+ if ( loc == end )
|
|
984
|
+ {
|
|
985
|
+ empty++;
|
|
986
|
+ continue;
|
|
987
|
+ }
|
948
|
988
|
|
949
|
|
- if ( loc >= glyf_length )
|
|
989
|
+ if ( loc + 1 >= end )
|
950
|
990
|
{
|
951
|
991
|
printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
|
952
|
992
|
continue;
|
... |
... |
@@ -959,7 +999,7 @@ |
959
|
999
|
{
|
960
|
1000
|
composite++;
|
961
|
1001
|
|
962
|
|
- if ( loc >= glyf_length )
|
|
1002
|
+ if ( loc + 1 >= end )
|
963
|
1003
|
{
|
964
|
1004
|
printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
|
965
|
1005
|
continue;
|
... |
... |
@@ -976,7 +1016,7 @@ |
976
|
1016
|
|
977
|
1017
|
loc += 2 * len;
|
978
|
1018
|
|
979
|
|
- if ( loc >= glyf_length )
|
|
1019
|
+ if ( loc + 1 >= end )
|
980
|
1020
|
{
|
981
|
1021
|
printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
|
982
|
1022
|
continue;
|
... |
... |
@@ -986,7 +1026,7 @@ |
986
|
1026
|
|
987
|
1027
|
loc += 2 + len;
|
988
|
1028
|
|
989
|
|
- if ( len >= glyf_length )
|
|
1029
|
+ if ( len >= end )
|
990
|
1030
|
{
|
991
|
1031
|
printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
|
992
|
1032
|
continue;
|
... |
... |
@@ -1005,6 +1045,8 @@ |
1005
|
1045
|
printf( composite_overlap ? ", with overlap flagged in %d\n"
|
1006
|
1046
|
: "\n",
|
1007
|
1047
|
composite_overlap );
|
|
1048
|
+ if ( empty )
|
|
1049
|
+ printf( "%s%d\n", Name_Field( " empty" ), empty );
|
1008
|
1050
|
|
1009
|
1051
|
Exit:
|
1010
|
1052
|
free( buffer );
|