... |
... |
@@ -538,7 +538,8 @@ |
538
|
538
|
FT_Byte* limit = parser->root.limit;
|
539
|
539
|
FT_Error error;
|
540
|
540
|
FT_Int num_tables = 0;
|
541
|
|
- FT_Long count;
|
|
541
|
+ FT_Long ttf_count;
|
|
542
|
+ FT_Long ttf_reserved;
|
542
|
543
|
|
543
|
544
|
FT_ULong n, string_size, old_string_size, real_size;
|
544
|
545
|
FT_Byte* string_buf = NULL;
|
... |
... |
@@ -546,6 +547,9 @@ |
546
|
547
|
|
547
|
548
|
T42_Load_Status status;
|
548
|
549
|
|
|
550
|
+ /** There should only be one sfnts array, but free any previous. */
|
|
551
|
+ FT_FREE( face->ttf_data );
|
|
552
|
+ face->ttf_size = 0;
|
549
|
553
|
|
550
|
554
|
/* The format is */
|
551
|
555
|
/* */
|
... |
... |
@@ -574,7 +578,10 @@ |
574
|
578
|
status = BEFORE_START;
|
575
|
579
|
string_size = 0;
|
576
|
580
|
old_string_size = 0;
|
577
|
|
- count = 0;
|
|
581
|
+ ttf_count = 0;
|
|
582
|
+ ttf_reserved = 12;
|
|
583
|
+ if ( FT_QALLOC( face->ttf_data, ttf_reserved ) )
|
|
584
|
+ goto Fail;
|
578
|
585
|
|
579
|
586
|
FT_TRACE2(( "\n" ));
|
580
|
587
|
FT_TRACE2(( "t42_parse_sfnts:\n" ));
|
... |
... |
@@ -589,6 +596,7 @@ |
589
|
596
|
if ( *cur == ']' )
|
590
|
597
|
{
|
591
|
598
|
parser->root.cursor++;
|
|
599
|
+ face->ttf_size = ttf_count;
|
592
|
600
|
goto Exit;
|
593
|
601
|
}
|
594
|
602
|
|
... |
... |
@@ -684,7 +692,7 @@ |
684
|
692
|
}
|
685
|
693
|
|
686
|
694
|
FT_TRACE2(( " PS string size %5lu bytes, offset 0x%08lx (%lu)\n",
|
687
|
|
- string_size, count, count ));
|
|
695
|
+ string_size, ttf_count, ttf_count ));
|
688
|
696
|
|
689
|
697
|
/* The whole TTF is now loaded into `string_buf'. We are */
|
690
|
698
|
/* checking its contents while copying it to `ttf_data'. */
|
... |
... |
@@ -697,45 +705,48 @@ |
697
|
705
|
{
|
698
|
706
|
case BEFORE_START:
|
699
|
707
|
/* load offset table, 12 bytes */
|
700
|
|
- if ( count < 12 )
|
|
708
|
+ if ( ttf_count < 12 )
|
701
|
709
|
{
|
702
|
|
- face->ttf_data[count++] = string_buf[n];
|
|
710
|
+ face->ttf_data[ttf_count++] = string_buf[n];
|
703
|
711
|
continue;
|
704
|
712
|
}
|
705
|
713
|
else
|
706
|
714
|
{
|
707
|
|
- num_tables = 16 * face->ttf_data[4] + face->ttf_data[5];
|
708
|
|
- status = BEFORE_TABLE_DIR;
|
709
|
|
- face->ttf_size = 12 + 16 * num_tables;
|
|
715
|
+ FT_Long ttf_reserved_prev = ttf_reserved;
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+ num_tables = 16 * face->ttf_data[4] + face->ttf_data[5];
|
|
719
|
+ status = BEFORE_TABLE_DIR;
|
|
720
|
+ ttf_reserved = 12 + 16 * num_tables;
|
710
|
721
|
|
711
|
722
|
FT_TRACE2(( " SFNT directory contains %d tables\n",
|
712
|
723
|
num_tables ));
|
713
|
724
|
|
714
|
|
- if ( (FT_Long)size < face->ttf_size )
|
|
725
|
+ if ( (FT_Long)size < ttf_reserved )
|
715
|
726
|
{
|
716
|
727
|
FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
|
717
|
728
|
error = FT_THROW( Invalid_File_Format );
|
718
|
729
|
goto Fail;
|
719
|
730
|
}
|
720
|
731
|
|
721
|
|
- /* To handle bad fonts with an invalid table directory */
|
722
|
|
- /* we don't use `FT_QREALLOC` here. */
|
723
|
|
- if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) )
|
|
732
|
+ if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev,
|
|
733
|
+ ttf_reserved ) )
|
724
|
734
|
goto Fail;
|
725
|
735
|
}
|
726
|
736
|
/* fall through */
|
727
|
737
|
|
728
|
738
|
case BEFORE_TABLE_DIR:
|
729
|
739
|
/* the offset table is read; read the table directory */
|
730
|
|
- if ( count < face->ttf_size )
|
|
740
|
+ if ( ttf_count < ttf_reserved )
|
731
|
741
|
{
|
732
|
|
- face->ttf_data[count++] = string_buf[n];
|
|
742
|
+ face->ttf_data[ttf_count++] = string_buf[n];
|
733
|
743
|
continue;
|
734
|
744
|
}
|
735
|
745
|
else
|
736
|
746
|
{
|
737
|
747
|
int i;
|
738
|
748
|
FT_ULong len;
|
|
749
|
+ FT_Long ttf_reserved_prev = ttf_reserved;
|
739
|
750
|
|
740
|
751
|
|
741
|
752
|
FT_TRACE2(( "\n" ));
|
... |
... |
@@ -751,7 +762,7 @@ |
751
|
762
|
FT_TRACE2(( " %4i 0x%08lx (%lu)\n", i, len, len ));
|
752
|
763
|
|
753
|
764
|
if ( len > size ||
|
754
|
|
- face->ttf_size > (FT_Long)( size - len ) )
|
|
765
|
+ ttf_reserved > (FT_Long)( size - len ) )
|
755
|
766
|
{
|
756
|
767
|
FT_ERROR(( "t42_parse_sfnts:"
|
757
|
768
|
" invalid data in sfnts array\n" ));
|
... |
... |
@@ -760,35 +771,31 @@ |
760
|
771
|
}
|
761
|
772
|
|
762
|
773
|
/* Pad to a 4-byte boundary length */
|
763
|
|
- face->ttf_size += (FT_Long)( ( len + 3 ) & ~3U );
|
|
774
|
+ ttf_reserved += (FT_Long)( ( len + 3 ) & ~3U );
|
764
|
775
|
}
|
|
776
|
+ ttf_reserved += 1;
|
765
|
777
|
|
766
|
778
|
status = OTHER_TABLES;
|
767
|
779
|
|
768
|
780
|
FT_TRACE2(( "\n" ));
|
769
|
|
- FT_TRACE2(( " allocating %ld bytes\n", face->ttf_size + 1 ));
|
|
781
|
+ FT_TRACE2(( " allocating %ld bytes\n", ttf_reserved ));
|
770
|
782
|
FT_TRACE2(( "\n" ));
|
771
|
783
|
|
772
|
|
- /* To handle bad fonts we don't use `FT_QREALLOC` here: */
|
773
|
|
- /* chances are high that due to incorrect values in the */
|
774
|
|
- /* table directory the computation of `ttf_size` would be */
|
775
|
|
- /* incorrect otherwise, causing run-time errors because of */
|
776
|
|
- /* accessing uninitialized memory. */
|
777
|
|
- if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
|
778
|
|
- face->ttf_size + 1 ) )
|
|
784
|
+ if ( FT_QREALLOC( face->ttf_data, ttf_reserved_prev,
|
|
785
|
+ ttf_reserved ) )
|
779
|
786
|
goto Fail;
|
780
|
787
|
}
|
781
|
788
|
/* fall through */
|
782
|
789
|
|
783
|
790
|
case OTHER_TABLES:
|
784
|
791
|
/* all other tables are just copied */
|
785
|
|
- if ( count >= face->ttf_size )
|
|
792
|
+ if ( ttf_count >= ttf_reserved )
|
786
|
793
|
{
|
787
|
794
|
FT_ERROR(( "t42_parse_sfnts: too much binary data\n" ));
|
788
|
795
|
error = FT_THROW( Invalid_File_Format );
|
789
|
796
|
goto Fail;
|
790
|
797
|
}
|
791
|
|
- face->ttf_data[count++] = string_buf[n];
|
|
798
|
+ face->ttf_data[ttf_count++] = string_buf[n];
|
792
|
799
|
}
|
793
|
800
|
}
|
794
|
801
|
|
... |
... |
@@ -802,6 +809,11 @@ |
802
|
809
|
parser->root.error = error;
|
803
|
810
|
|
804
|
811
|
Exit:
|
|
812
|
+ if ( parser->root.error )
|
|
813
|
+ {
|
|
814
|
+ FT_FREE( face->ttf_data );
|
|
815
|
+ face->ttf_size = 0;
|
|
816
|
+ }
|
805
|
817
|
if ( allocated )
|
806
|
818
|
FT_FREE( string_buf );
|
807
|
819
|
}
|