Werner Lemberg pushed to branch wl/opentype-1.9 at FreeType / FreeType
Commits:
-
d31bafcb
by Werner Lemberg at 2021-11-14T11:02:54+01:00
-
93e6b3e8
by Werner Lemberg at 2021-11-16T20:13:58+00:00
-
e4f7673e
by Werner Lemberg at 2021-11-16T20:13:58+00:00
7 changed files:
- src/gxvalid/gxvcommn.h
- src/gxvalid/gxvmod.c
- src/smooth/ftgrays.c
- src/truetype/ttgxvar.c
- src/truetype/ttgxvar.h
- src/type1/t1gload.c
- src/type1/t1load.c
Changes:
... | ... | @@ -61,8 +61,11 @@ FT_BEGIN_HEADER |
61 | 61 |
|
62 | 62 |
#undef GXV_LOAD_UNUSED_VARS /* debug purpose */
|
63 | 63 |
|
64 |
-#define IS_PARANOID_VALIDATION ( gxvalid->root->level >= FT_VALIDATE_PARANOID )
|
|
65 |
-#define GXV_SET_ERR_IF_PARANOID( err ) { if ( IS_PARANOID_VALIDATION ) ( err ); }
|
|
64 |
+#define IS_PARANOID_VALIDATION \
|
|
65 |
+ ( gxvalid->root->level >= FT_VALIDATE_PARANOID )
|
|
66 |
+#define GXV_SET_ERR_IF_PARANOID( err ) \
|
|
67 |
+ do { if ( IS_PARANOID_VALIDATION ) ( err ); } while ( 0 )
|
|
68 |
+ |
|
66 | 69 |
|
67 | 70 |
/*************************************************************************/
|
68 | 71 |
/*************************************************************************/
|
... | ... | @@ -76,27 +76,33 @@ |
76 | 76 |
FT_Byte* volatile _sfnt = NULL; \
|
77 | 77 |
FT_ULong len_ ## _sfnt = 0
|
78 | 78 |
|
79 |
-#define GXV_TABLE_LOAD( _sfnt ) \
|
|
80 |
- if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \
|
|
81 |
- ( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \
|
|
82 |
- { \
|
|
83 |
- error = gxv_load_table( face, TTAG_ ## _sfnt, \
|
|
84 |
- &_sfnt, &len_ ## _sfnt ); \
|
|
85 |
- if ( error ) \
|
|
86 |
- goto Exit; \
|
|
87 |
- }
|
|
88 |
- |
|
89 |
-#define GXV_TABLE_VALIDATE( _sfnt ) \
|
|
90 |
- if ( _sfnt ) \
|
|
91 |
- { \
|
|
92 |
- ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
|
|
93 |
- FT_VALIDATE_DEFAULT ); \
|
|
94 |
- if ( ft_setjmp( valid.jump_buffer ) == 0 ) \
|
|
95 |
- gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \
|
|
96 |
- error = valid.error; \
|
|
97 |
- if ( error ) \
|
|
98 |
- goto Exit; \
|
|
99 |
- }
|
|
79 |
+#define GXV_TABLE_LOAD( _sfnt ) \
|
|
80 |
+ do \
|
|
81 |
+ { \
|
|
82 |
+ if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \
|
|
83 |
+ ( gx_flags & FT_VALIDATE_ ## _sfnt ) ) \
|
|
84 |
+ { \
|
|
85 |
+ error = gxv_load_table( face, TTAG_ ## _sfnt, \
|
|
86 |
+ &_sfnt, &len_ ## _sfnt ); \
|
|
87 |
+ if ( error ) \
|
|
88 |
+ goto Exit; \
|
|
89 |
+ } \
|
|
90 |
+ } while ( 0 )
|
|
91 |
+ |
|
92 |
+#define GXV_TABLE_VALIDATE( _sfnt ) \
|
|
93 |
+ do \
|
|
94 |
+ { \
|
|
95 |
+ if ( _sfnt ) \
|
|
96 |
+ { \
|
|
97 |
+ ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
|
|
98 |
+ FT_VALIDATE_DEFAULT ); \
|
|
99 |
+ if ( ft_setjmp( valid.jump_buffer ) == 0 ) \
|
|
100 |
+ gxv_ ## _sfnt ## _validate( _sfnt, face, &valid ); \
|
|
101 |
+ error = valid.error; \
|
|
102 |
+ if ( error ) \
|
|
103 |
+ goto Exit; \
|
|
104 |
+ } \
|
|
105 |
+ } while ( 0 )
|
|
100 | 106 |
|
101 | 107 |
#define GXV_TABLE_SET( _sfnt ) \
|
102 | 108 |
if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) \
|
... | ... | @@ -1986,8 +1986,8 @@ typedef ptrdiff_t FT_PtrDist; |
1986 | 1986 |
ras.ycells[w] = ras.cell_null;
|
1987 | 1987 |
|
1988 | 1988 |
/* memory management: skip ycells */
|
1989 |
- n = ( width * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
|
|
1990 |
- sizeof ( TCell );
|
|
1989 |
+ n = ( (size_t)width * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
|
|
1990 |
+ sizeof ( TCell );
|
|
1991 | 1991 |
|
1992 | 1992 |
ras.cell_free = buffer + n;
|
1993 | 1993 |
ras.cell = ras.cell_null;
|
... | ... | @@ -457,7 +457,8 @@ |
457 | 457 |
FT_UShort format;
|
458 | 458 |
FT_ULong region_offset;
|
459 | 459 |
FT_UInt i, j, k;
|
460 |
- FT_UInt shortDeltaCount;
|
|
460 |
+ FT_UInt wordDeltaCount;
|
|
461 |
+ FT_Bool long_words;
|
|
461 | 462 |
|
462 | 463 |
GX_Blend blend = face->blend;
|
463 | 464 |
GX_ItemVarData varData;
|
... | ... | @@ -572,15 +573,18 @@ |
572 | 573 |
goto Exit;
|
573 | 574 |
|
574 | 575 |
if ( FT_READ_USHORT( varData->itemCount ) ||
|
575 |
- FT_READ_USHORT( shortDeltaCount ) ||
|
|
576 |
+ FT_READ_USHORT( wordDeltaCount ) ||
|
|
576 | 577 |
FT_READ_USHORT( varData->regionIdxCount ) )
|
577 | 578 |
goto Exit;
|
578 | 579 |
|
580 |
+ long_words = !!( wordDeltaCount & 0x8000 );
|
|
581 |
+ wordDeltaCount &= 0x7FFF;
|
|
582 |
+ |
|
579 | 583 |
/* check some data consistency */
|
580 |
- if ( shortDeltaCount > varData->regionIdxCount )
|
|
584 |
+ if ( wordDeltaCount > varData->regionIdxCount )
|
|
581 | 585 |
{
|
582 | 586 |
FT_TRACE2(( "bad short count %d or region count %d\n",
|
583 |
- shortDeltaCount,
|
|
587 |
+ wordDeltaCount,
|
|
584 | 588 |
varData->regionIdxCount ));
|
585 | 589 |
error = FT_THROW( Invalid_Table );
|
586 | 590 |
goto Exit;
|
... | ... | @@ -616,39 +620,52 @@ |
616 | 620 |
|
617 | 621 |
/* Parse delta set. */
|
618 | 622 |
/* */
|
619 |
- /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes */
|
|
620 |
- /* each; on output, deltas are expanded to `regionIdxCount' shorts */
|
|
621 |
- /* each. */
|
|
623 |
+ /* On input, deltas are (wordDeltaCount + regionIdxCount) bytes */
|
|
624 |
+ /* each if `long_words` isn't set, and twice as much otherwise. */
|
|
625 |
+ /* */
|
|
626 |
+ /* On output, deltas are expanded to `regionIdxCount` shorts each. */
|
|
622 | 627 |
if ( FT_NEW_ARRAY( varData->deltaSet,
|
623 | 628 |
varData->regionIdxCount * varData->itemCount ) )
|
624 | 629 |
goto Exit;
|
625 | 630 |
|
626 |
- /* the delta set is stored as a 2-dimensional array of shorts; */
|
|
627 |
- /* sign-extend signed bytes to signed shorts */
|
|
628 |
- for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
|
|
631 |
+ /* the delta set is stored as a 2-dimensional array of shorts */
|
|
632 |
+ if ( long_words )
|
|
633 |
+ {
|
|
634 |
+ /* new in OpenType 1.9, currently for 'COLR' table only; */
|
|
635 |
+ /* the deltas are interpreted as 16.16 fixed-point scaling values */
|
|
636 |
+ |
|
637 |
+ /* not supported yet */
|
|
638 |
+ |
|
639 |
+ error = FT_THROW( Invalid_Table );
|
|
640 |
+ goto Exit;
|
|
641 |
+ }
|
|
642 |
+ else
|
|
629 | 643 |
{
|
630 |
- for ( k = 0; k < shortDeltaCount; k++, j++ )
|
|
644 |
+ for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
|
|
631 | 645 |
{
|
632 |
- /* read the short deltas */
|
|
633 |
- FT_Short delta;
|
|
646 |
+ for ( k = 0; k < wordDeltaCount; k++, j++ )
|
|
647 |
+ {
|
|
648 |
+ /* read the short deltas */
|
|
649 |
+ FT_Short delta;
|
|
634 | 650 |
|
635 | 651 |
|
636 |
- if ( FT_READ_SHORT( delta ) )
|
|
637 |
- goto Exit;
|
|
652 |
+ if ( FT_READ_SHORT( delta ) )
|
|
653 |
+ goto Exit;
|
|
638 | 654 |
|
639 |
- varData->deltaSet[j] = delta;
|
|
640 |
- }
|
|
655 |
+ varData->deltaSet[j] = delta;
|
|
656 |
+ }
|
|
641 | 657 |
|
642 |
- for ( ; k < varData->regionIdxCount; k++, j++ )
|
|
643 |
- {
|
|
644 |
- /* read the (signed) byte deltas */
|
|
645 |
- FT_Char delta;
|
|
658 |
+ for ( ; k < varData->regionIdxCount; k++, j++ )
|
|
659 |
+ {
|
|
660 |
+ /* read the (signed) byte deltas */
|
|
661 |
+ FT_Char delta;
|
|
646 | 662 |
|
647 | 663 |
|
648 |
- if ( FT_READ_CHAR( delta ) )
|
|
649 |
- goto Exit;
|
|
664 |
+ if ( FT_READ_CHAR( delta ) )
|
|
665 |
+ goto Exit;
|
|
650 | 666 |
|
651 |
- varData->deltaSet[j] = delta;
|
|
667 |
+ varData->deltaSet[j] = delta;
|
|
668 |
+ }
|
|
652 | 669 |
}
|
653 | 670 |
}
|
654 | 671 |
}
|
... | ... | @@ -664,37 +681,66 @@ |
664 | 681 |
ft_var_load_delta_set_index_mapping( TT_Face face,
|
665 | 682 |
FT_ULong offset,
|
666 | 683 |
GX_DeltaSetIdxMap map,
|
667 |
- GX_ItemVarStore itemStore )
|
|
684 |
+ GX_ItemVarStore itemStore,
|
|
685 |
+ FT_ULong table_len )
|
|
668 | 686 |
{
|
669 | 687 |
FT_Stream stream = FT_FACE_STREAM( face );
|
670 | 688 |
FT_Memory memory = stream->memory;
|
671 | 689 |
|
672 |
- FT_Error error;
|
|
690 |
+ FT_Error error;
|
|
673 | 691 |
|
674 |
- FT_UShort format;
|
|
675 |
- FT_UInt entrySize;
|
|
676 |
- FT_UInt innerBitCount;
|
|
677 |
- FT_UInt innerIndexMask;
|
|
678 |
- FT_UInt i, j;
|
|
692 |
+ FT_Byte format;
|
|
693 |
+ FT_Byte entryFormat;
|
|
694 |
+ FT_UInt entrySize;
|
|
695 |
+ FT_UInt innerBitCount;
|
|
696 |
+ FT_UInt innerIndexMask;
|
|
697 |
+ FT_ULong i;
|
|
698 |
+ FT_UInt j;
|
|
679 | 699 |
|
680 | 700 |
|
681 |
- if ( FT_STREAM_SEEK( offset ) ||
|
|
682 |
- FT_READ_USHORT( format ) ||
|
|
683 |
- FT_READ_USHORT( map->mapCount ) )
|
|
701 |
+ if ( FT_STREAM_SEEK( offset ) ||
|
|
702 |
+ FT_READ_BYTE( format ) ||
|
|
703 |
+ FT_READ_BYTE( entryFormat ) )
|
|
684 | 704 |
goto Exit;
|
685 | 705 |
|
686 |
- if ( format & 0xFFC0 )
|
|
706 |
+ if ( format == 0 )
|
|
707 |
+ {
|
|
708 |
+ if ( FT_READ_USHORT( map->mapCount ) )
|
|
709 |
+ goto Exit;
|
|
710 |
+ }
|
|
711 |
+ else if ( format == 1 ) /* new in OpenType 1.9 */
|
|
712 |
+ {
|
|
713 |
+ if ( FT_READ_ULONG( map->mapCount ) )
|
|
714 |
+ goto Exit;
|
|
715 |
+ }
|
|
716 |
+ else
|
|
687 | 717 |
{
|
688 | 718 |
FT_TRACE2(( "bad map format %d\n", format ));
|
689 | 719 |
error = FT_THROW( Invalid_Table );
|
690 | 720 |
goto Exit;
|
691 | 721 |
}
|
692 | 722 |
|
723 |
+ if ( entryFormat & 0xC0 )
|
|
724 |
+ {
|
|
725 |
+ FT_TRACE2(( "bad entry format %d\n", format ));
|
|
726 |
+ error = FT_THROW( Invalid_Table );
|
|
727 |
+ goto Exit;
|
|
728 |
+ }
|
|
729 |
+ |
|
693 | 730 |
/* bytes per entry: 1, 2, 3, or 4 */
|
694 |
- entrySize = ( ( format & 0x0030 ) >> 4 ) + 1;
|
|
695 |
- innerBitCount = ( format & 0x000F ) + 1;
|
|
731 |
+ entrySize = ( ( entryFormat & 0x30 ) >> 4 ) + 1;
|
|
732 |
+ innerBitCount = ( entryFormat & 0x0F ) + 1;
|
|
696 | 733 |
innerIndexMask = ( 1 << innerBitCount ) - 1;
|
697 | 734 |
|
735 |
+ /* rough sanity check */
|
|
736 |
+ if ( map->mapCount * entrySize > table_len )
|
|
737 |
+ {
|
|
738 |
+ FT_TRACE1(( "ft_var_load_delta_set_index_mapping:"
|
|
739 |
+ " invalid number of delta-set index mappings\n" ));
|
|
740 |
+ error = FT_THROW( Invalid_Table );
|
|
741 |
+ goto Exit;
|
|
742 |
+ }
|
|
743 |
+ |
|
698 | 744 |
if ( FT_NEW_ARRAY( map->innerIndex, map->mapCount ) )
|
699 | 745 |
goto Exit;
|
700 | 746 |
|
... | ... | @@ -723,7 +769,7 @@ |
723 | 769 |
|
724 | 770 |
if ( outerIndex >= itemStore->dataCount )
|
725 | 771 |
{
|
726 |
- FT_TRACE2(( "outerIndex[%d] == %d out of range\n",
|
|
772 |
+ FT_TRACE2(( "outerIndex[%ld] == %d out of range\n",
|
|
727 | 773 |
i,
|
728 | 774 |
outerIndex ));
|
729 | 775 |
error = FT_THROW( Invalid_Table );
|
... | ... | @@ -736,7 +782,7 @@ |
736 | 782 |
|
737 | 783 |
if ( innerIndex >= itemStore->varData[outerIndex].itemCount )
|
738 | 784 |
{
|
739 |
- FT_TRACE2(( "innerIndex[%d] == %d out of range\n",
|
|
785 |
+ FT_TRACE2(( "innerIndex[%ld] == %d out of range\n",
|
|
740 | 786 |
i,
|
741 | 787 |
innerIndex ));
|
742 | 788 |
error = FT_THROW( Invalid_Table );
|
... | ... | @@ -861,7 +907,8 @@ |
861 | 907 |
face,
|
862 | 908 |
table_offset + widthMap_offset,
|
863 | 909 |
&table->widthMap,
|
864 |
- &table->itemStore );
|
|
910 |
+ &table->itemStore,
|
|
911 |
+ table_len );
|
|
865 | 912 |
if ( error )
|
866 | 913 |
goto Exit;
|
867 | 914 |
}
|
... | ... | @@ -106,9 +106,9 @@ FT_BEGIN_HEADER |
106 | 106 |
|
107 | 107 |
typedef struct GX_DeltaSetIdxMapRec_
|
108 | 108 |
{
|
109 |
- FT_UInt mapCount;
|
|
110 |
- FT_UInt* outerIndex; /* indices to item var data */
|
|
111 |
- FT_UInt* innerIndex; /* indices to delta set */
|
|
109 |
+ FT_ULong mapCount;
|
|
110 |
+ FT_UInt* outerIndex; /* indices to item var data */
|
|
111 |
+ FT_UInt* innerIndex; /* indices to delta set */
|
|
112 | 112 |
|
113 | 113 |
} GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
|
114 | 114 |
|
... | ... | @@ -79,7 +79,7 @@ |
79 | 79 |
/* For ordinary fonts get the character data stored in the face record. */
|
80 | 80 |
{
|
81 | 81 |
char_string->pointer = type1->charstrings[glyph_index];
|
82 |
- char_string->length = (FT_Int)type1->charstrings_len[glyph_index];
|
|
82 |
+ char_string->length = type1->charstrings_len[glyph_index];
|
|
83 | 83 |
}
|
84 | 84 |
|
85 | 85 |
if ( !error )
|
... | ... | @@ -1346,7 +1346,7 @@ |
1346 | 1346 |
|
1347 | 1347 |
static int
|
1348 | 1348 |
read_binary_data( T1_Parser parser,
|
1349 |
- FT_Long* size,
|
|
1349 |
+ FT_ULong* size,
|
|
1350 | 1350 |
FT_Byte** base,
|
1351 | 1351 |
FT_Bool incremental )
|
1352 | 1352 |
{
|
... | ... | @@ -1378,7 +1378,7 @@ |
1378 | 1378 |
if ( s >= 0 && s < limit - *base )
|
1379 | 1379 |
{
|
1380 | 1380 |
parser->root.cursor += s + 1;
|
1381 |
- *size = s;
|
|
1381 |
+ *size = (FT_ULong)s;
|
|
1382 | 1382 |
return !parser->root.error;
|
1383 | 1383 |
}
|
1384 | 1384 |
}
|
... | ... | @@ -1803,7 +1803,7 @@ |
1803 | 1803 |
for ( count = 0; ; count++ )
|
1804 | 1804 |
{
|
1805 | 1805 |
FT_Long idx;
|
1806 |
- FT_Long size;
|
|
1806 |
+ FT_ULong size;
|
|
1807 | 1807 |
FT_Byte* base;
|
1808 | 1808 |
|
1809 | 1809 |
|
... | ... | @@ -1861,7 +1861,7 @@ |
1861 | 1861 |
/* some fonts define empty subr records -- this is not totally */
|
1862 | 1862 |
/* compliant to the specification (which says they should at */
|
1863 | 1863 |
/* least contain a `return'), but we support them anyway */
|
1864 |
- if ( size < face->type1.private_dict.lenIV )
|
|
1864 |
+ if ( size < (FT_ULong)face->type1.private_dict.lenIV )
|
|
1865 | 1865 |
{
|
1866 | 1866 |
error = FT_THROW( Invalid_File_Format );
|
1867 | 1867 |
goto Fail;
|
... | ... | @@ -1872,7 +1872,7 @@ |
1872 | 1872 |
goto Fail;
|
1873 | 1873 |
FT_MEM_COPY( temp, base, size );
|
1874 | 1874 |
psaux->t1_decrypt( temp, size, 4330 );
|
1875 |
- size -= face->type1.private_dict.lenIV;
|
|
1875 |
+ size -= (FT_ULong)face->type1.private_dict.lenIV;
|
|
1876 | 1876 |
error = T1_Add_Table( table, (FT_Int)idx,
|
1877 | 1877 |
temp + face->type1.private_dict.lenIV, size );
|
1878 | 1878 |
FT_FREE( temp );
|
... | ... | @@ -1977,7 +1977,7 @@ |
1977 | 1977 |
|
1978 | 1978 |
for (;;)
|
1979 | 1979 |
{
|
1980 |
- FT_Long size;
|
|
1980 |
+ FT_ULong size;
|
|
1981 | 1981 |
FT_Byte* base;
|
1982 | 1982 |
|
1983 | 1983 |
|
... | ... | @@ -2071,7 +2071,7 @@ |
2071 | 2071 |
FT_Byte* temp = NULL;
|
2072 | 2072 |
|
2073 | 2073 |
|
2074 |
- if ( size <= face->type1.private_dict.lenIV )
|
|
2074 |
+ if ( size <= (FT_ULong)face->type1.private_dict.lenIV )
|
|
2075 | 2075 |
{
|
2076 | 2076 |
error = FT_THROW( Invalid_File_Format );
|
2077 | 2077 |
goto Fail;
|
... | ... | @@ -2082,7 +2082,7 @@ |
2082 | 2082 |
goto Fail;
|
2083 | 2083 |
FT_MEM_COPY( temp, base, size );
|
2084 | 2084 |
psaux->t1_decrypt( temp, size, 4330 );
|
2085 |
- size -= face->type1.private_dict.lenIV;
|
|
2085 |
+ size -= (FT_ULong)face->type1.private_dict.lenIV;
|
|
2086 | 2086 |
error = T1_Add_Table( code_table, n,
|
2087 | 2087 |
temp + face->type1.private_dict.lenIV, size );
|
2088 | 2088 |
FT_FREE( temp );
|
... | ... | @@ -2334,7 +2334,7 @@ |
2334 | 2334 |
else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' &&
|
2335 | 2335 |
have_integer )
|
2336 | 2336 |
{
|
2337 |
- FT_Long s;
|
|
2337 |
+ FT_ULong s;
|
|
2338 | 2338 |
FT_Byte* b;
|
2339 | 2339 |
|
2340 | 2340 |
|
... | ... | @@ -2347,7 +2347,7 @@ |
2347 | 2347 |
else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' &&
|
2348 | 2348 |
have_integer )
|
2349 | 2349 |
{
|
2350 |
- FT_Long s;
|
|
2350 |
+ FT_ULong s;
|
|
2351 | 2351 |
FT_Byte* b;
|
2352 | 2352 |
|
2353 | 2353 |
|