1 | /**************************************************************************** |
2 | * |
3 | * gxvopbd.c |
4 | * |
5 | * TrueTypeGX/AAT opbd table validation (body). |
6 | * |
7 | * Copyright (C) 2004-2023 by |
8 | * suzuki toshiya, Masatake YAMATO, Red Hat K.K., |
9 | * David Turner, Robert Wilhelm, and Werner Lemberg. |
10 | * |
11 | * This file is part of the FreeType project, and may only be used, |
12 | * modified, and distributed under the terms of the FreeType project |
13 | * license, LICENSE.TXT. By continuing to use, modify, or distribute |
14 | * this file you indicate that you have read the license and |
15 | * understand and accept it fully. |
16 | * |
17 | */ |
18 | |
19 | /**************************************************************************** |
20 | * |
21 | * gxvalid is derived from both gxlayout module and otvalid module. |
22 | * Development of gxlayout is supported by the Information-technology |
23 | * Promotion Agency(IPA), Japan. |
24 | * |
25 | */ |
26 | |
27 | |
28 | #include "gxvalid.h" |
29 | #include "gxvcommn.h" |
30 | |
31 | |
32 | /************************************************************************** |
33 | * |
34 | * The macro FT_COMPONENT is used in trace mode. It is an implicit |
35 | * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
36 | * messages during execution. |
37 | */ |
38 | #undef FT_COMPONENT |
39 | #define FT_COMPONENT gxvopbd |
40 | |
41 | |
42 | /*************************************************************************/ |
43 | /*************************************************************************/ |
44 | /***** *****/ |
45 | /***** Data and Types *****/ |
46 | /***** *****/ |
47 | /*************************************************************************/ |
48 | /*************************************************************************/ |
49 | |
50 | typedef struct GXV_opbd_DataRec_ |
51 | { |
52 | FT_UShort format; |
53 | FT_UShort valueOffset_min; |
54 | |
55 | } GXV_opbd_DataRec, *GXV_opbd_Data; |
56 | |
57 | |
58 | #define GXV_OPBD_DATA( FIELD ) GXV_TABLE_DATA( opbd, FIELD ) |
59 | |
60 | |
61 | /*************************************************************************/ |
62 | /*************************************************************************/ |
63 | /***** *****/ |
64 | /***** UTILITY FUNCTIONS *****/ |
65 | /***** *****/ |
66 | /*************************************************************************/ |
67 | /*************************************************************************/ |
68 | |
69 | static void |
70 | gxv_opbd_LookupValue_validate( FT_UShort glyph, |
71 | GXV_LookupValueCPtr value_p, |
72 | GXV_Validator gxvalid ) |
73 | { |
74 | /* offset in LookupTable is measured from the head of opbd table */ |
75 | FT_Bytes p = gxvalid->root->base + value_p->u; |
76 | FT_Bytes limit = gxvalid->root->limit; |
77 | FT_Short delta_value; |
78 | int i; |
79 | |
80 | |
81 | if ( value_p->u < GXV_OPBD_DATA( valueOffset_min ) ) |
82 | GXV_OPBD_DATA( valueOffset_min ) = value_p->u; |
83 | |
84 | for ( i = 0; i < 4; i++ ) |
85 | { |
86 | GXV_LIMIT_CHECK( 2 ); |
87 | delta_value = FT_NEXT_SHORT( p ); |
88 | |
89 | if ( GXV_OPBD_DATA( format ) ) /* format 1, value is ctrl pt. */ |
90 | { |
91 | if ( delta_value == -1 ) |
92 | continue; |
93 | |
94 | gxv_ctlPoint_validate( glyph, (FT_UShort)delta_value, gxvalid ); |
95 | } |
96 | else /* format 0, value is distance */ |
97 | continue; |
98 | } |
99 | } |
100 | |
101 | |
102 | /* |
103 | opbd ---------------------+ |
104 | | |
105 | +===============+ | |
106 | | lookup header | | |
107 | +===============+ | |
108 | | BinSrchHeader | | |
109 | +===============+ | |
110 | | lastGlyph[0] | | |
111 | +---------------+ | |
112 | | firstGlyph[0] | | head of opbd sfnt table |
113 | +---------------+ | + |
114 | | offset[0] | -> | offset [byte] |
115 | +===============+ | + |
116 | | lastGlyph[1] | | (glyphID - firstGlyph) * 4 * sizeof(FT_Short) [byte] |
117 | +---------------+ | |
118 | | firstGlyph[1] | | |
119 | +---------------+ | |
120 | | offset[1] | | |
121 | +===============+ | |
122 | | |
123 | .... | |
124 | | |
125 | 48bit value array | |
126 | +===============+ | |
127 | | value | <-------+ |
128 | | | |
129 | | | |
130 | | | |
131 | +---------------+ |
132 | .... */ |
133 | |
134 | static GXV_LookupValueDesc |
135 | gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, |
136 | GXV_LookupValueCPtr base_value_p, |
137 | FT_Bytes lookuptbl_limit, |
138 | GXV_Validator gxvalid ) |
139 | { |
140 | GXV_LookupValueDesc value; |
141 | |
142 | FT_UNUSED( lookuptbl_limit ); |
143 | FT_UNUSED( gxvalid ); |
144 | |
145 | /* XXX: check range? */ |
146 | value.u = (FT_UShort)( base_value_p->u + |
147 | relative_gindex * 4 * sizeof ( FT_Short ) ); |
148 | |
149 | return value; |
150 | } |
151 | |
152 | |
153 | /*************************************************************************/ |
154 | /*************************************************************************/ |
155 | /***** *****/ |
156 | /***** opbd TABLE *****/ |
157 | /***** *****/ |
158 | /*************************************************************************/ |
159 | /*************************************************************************/ |
160 | |
161 | FT_LOCAL_DEF( void ) |
162 | gxv_opbd_validate( FT_Bytes table, |
163 | FT_Face face, |
164 | FT_Validator ftvalid ) |
165 | { |
166 | GXV_ValidatorRec gxvalidrec; |
167 | GXV_Validator gxvalid = &gxvalidrec; |
168 | GXV_opbd_DataRec opbdrec; |
169 | GXV_opbd_Data opbd = &opbdrec; |
170 | FT_Bytes p = table; |
171 | FT_Bytes limit = 0; |
172 | |
173 | FT_ULong version; |
174 | |
175 | |
176 | gxvalid->root = ftvalid; |
177 | gxvalid->table_data = opbd; |
178 | gxvalid->face = face; |
179 | |
180 | FT_TRACE3(( "validating `opbd' table\n" )); |
181 | GXV_INIT; |
182 | GXV_OPBD_DATA( valueOffset_min ) = 0xFFFFU; |
183 | |
184 | |
185 | GXV_LIMIT_CHECK( 4 + 2 ); |
186 | version = FT_NEXT_ULONG( p ); |
187 | GXV_OPBD_DATA( format ) = FT_NEXT_USHORT( p ); |
188 | |
189 | |
190 | /* only 0x00010000 is defined (1996) */ |
191 | GXV_TRACE(( "(version=0x%08lx)\n" , version )); |
192 | if ( 0x00010000UL != version ) |
193 | FT_INVALID_FORMAT; |
194 | |
195 | /* only values 0 and 1 are defined (1996) */ |
196 | GXV_TRACE(( "(format=0x%04x)\n" , GXV_OPBD_DATA( format ) )); |
197 | if ( 0x0001 < GXV_OPBD_DATA( format ) ) |
198 | FT_INVALID_FORMAT; |
199 | |
200 | gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; |
201 | gxvalid->lookupval_func = gxv_opbd_LookupValue_validate; |
202 | gxvalid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; |
203 | |
204 | gxv_LookupTable_validate( p, limit, gxvalid ); |
205 | p += gxvalid->subtable_length; |
206 | |
207 | if ( p > table + GXV_OPBD_DATA( valueOffset_min ) ) |
208 | { |
209 | GXV_TRACE(( |
210 | "found overlap between LookupTable and opbd_value array\n" )); |
211 | FT_INVALID_OFFSET; |
212 | } |
213 | |
214 | FT_TRACE4(( "\n" )); |
215 | } |
216 | |
217 | |
218 | /* END */ |
219 | |