... |
... |
@@ -114,7 +114,7 @@ |
114
|
114
|
FT_TRACE3(( "version: %d\n", svg->version ));
|
115
|
115
|
FT_TRACE3(( "number of entries: %d\n", svg->num_entries ));
|
116
|
116
|
|
117
|
|
- if ( offsetToSVGDocumentList +
|
|
117
|
+ if ( offsetToSVGDocumentList + 2U +
|
118
|
118
|
svg->num_entries * SVG_DOCUMENT_RECORD_SIZE > table_size )
|
119
|
119
|
goto InvalidTable;
|
120
|
120
|
|
... |
... |
@@ -196,7 +196,7 @@ |
196
|
196
|
|
197
|
197
|
|
198
|
198
|
static FT_Error
|
199
|
|
- find_doc( FT_Byte* stream,
|
|
199
|
+ find_doc( FT_Byte* document_records,
|
200
|
200
|
FT_UShort num_entries,
|
201
|
201
|
FT_UInt glyph_index,
|
202
|
202
|
FT_ULong *doc_offset,
|
... |
... |
@@ -225,8 +225,8 @@ |
225
|
225
|
return error;
|
226
|
226
|
}
|
227
|
227
|
|
228
|
|
- start_doc = extract_svg_doc( stream + start_index * 12 );
|
229
|
|
- end_doc = extract_svg_doc( stream + end_index * 12 );
|
|
228
|
+ start_doc = extract_svg_doc( document_records + start_index * 12 );
|
|
229
|
+ end_doc = extract_svg_doc( document_records + end_index * 12 );
|
230
|
230
|
|
231
|
231
|
if ( ( compare_svg_doc( start_doc, glyph_index ) == -1 ) ||
|
232
|
232
|
( compare_svg_doc( end_doc, glyph_index ) == 1 ) )
|
... |
... |
@@ -238,18 +238,18 @@ |
238
|
238
|
while ( start_index <= end_index )
|
239
|
239
|
{
|
240
|
240
|
i = ( start_index + end_index ) / 2;
|
241
|
|
- mid_doc = extract_svg_doc( stream + i * 12 );
|
|
241
|
+ mid_doc = extract_svg_doc( document_records + i * 12 );
|
242
|
242
|
comp_res = compare_svg_doc( mid_doc, glyph_index );
|
243
|
243
|
|
244
|
244
|
if ( comp_res == 1 )
|
245
|
245
|
{
|
246
|
246
|
start_index = i + 1;
|
247
|
|
- start_doc = extract_svg_doc( stream + start_index * 4 );
|
|
247
|
+ start_doc = extract_svg_doc( document_records + start_index * 4 );
|
248
|
248
|
}
|
249
|
249
|
else if ( comp_res == -1 )
|
250
|
250
|
{
|
251
|
251
|
end_index = i - 1;
|
252
|
|
- end_doc = extract_svg_doc( stream + end_index * 4 );
|
|
252
|
+ end_doc = extract_svg_doc( document_records + end_index * 4 );
|
253
|
253
|
}
|
254
|
254
|
else
|
255
|
255
|
{
|
... |
... |
@@ -283,38 +283,47 @@ |
283
|
283
|
tt_face_load_svg_doc( FT_GlyphSlot glyph,
|
284
|
284
|
FT_UInt glyph_index )
|
285
|
285
|
{
|
286
|
|
- FT_Byte* doc_list; /* pointer to the SVG doc list */
|
287
|
|
- FT_UShort num_entries; /* total number of entries in doc list */
|
288
|
|
- FT_ULong doc_offset;
|
289
|
|
- FT_ULong doc_length;
|
290
|
|
-
|
291
|
|
- FT_UShort start_glyph_id;
|
292
|
|
- FT_UShort end_glyph_id;
|
293
|
|
-
|
294
|
286
|
FT_Error error = FT_Err_Ok;
|
295
|
287
|
TT_Face face = (TT_Face)glyph->face;
|
296
|
288
|
FT_Memory memory = face->root.memory;
|
297
|
289
|
Svg* svg = (Svg*)face->svg;
|
298
|
290
|
|
|
291
|
+ FT_Byte* doc_list;
|
|
292
|
+ FT_ULong doc_limit;
|
|
293
|
+
|
|
294
|
+ FT_Byte* doc;
|
|
295
|
+ FT_ULong doc_offset;
|
|
296
|
+ FT_ULong doc_length;
|
|
297
|
+ FT_UShort doc_start_glyph_id;
|
|
298
|
+ FT_UShort doc_end_glyph_id;
|
|
299
|
+
|
299
|
300
|
FT_SVG_Document svg_document = (FT_SVG_Document)glyph->other;
|
300
|
301
|
|
301
|
302
|
|
302
|
303
|
FT_ASSERT( !( svg == NULL ) );
|
303
|
304
|
|
304
|
|
- doc_list = svg->svg_doc_list;
|
305
|
|
- num_entries = FT_NEXT_USHORT( doc_list );
|
|
305
|
+ doc_list = svg->svg_doc_list;
|
306
|
306
|
|
307
|
|
- error = find_doc( doc_list, num_entries, glyph_index,
|
308
|
|
- &doc_offset, &doc_length,
|
309
|
|
- &start_glyph_id, &end_glyph_id );
|
|
307
|
+ error = find_doc( doc_list + 2, svg->num_entries, glyph_index,
|
|
308
|
+ &doc_offset, &doc_length,
|
|
309
|
+ &doc_start_glyph_id, &doc_end_glyph_id );
|
310
|
310
|
if ( error != FT_Err_Ok )
|
311
|
311
|
goto Exit;
|
312
|
312
|
|
313
|
|
- doc_list = svg->svg_doc_list; /* reset, so we can use it again */
|
314
|
|
- doc_list = (FT_Byte*)( doc_list + doc_offset );
|
|
313
|
+ doc_limit = svg->table_size - ( doc_list - (FT_Byte*)svg->table );
|
|
314
|
+ if ( doc_offset > doc_limit ||
|
|
315
|
+ doc_length > doc_limit - doc_offset )
|
|
316
|
+ {
|
|
317
|
+ error = FT_THROW( Invalid_Table );
|
|
318
|
+ goto Exit;
|
|
319
|
+ }
|
|
320
|
+
|
|
321
|
+ doc = doc_list + doc_offset;
|
315
|
322
|
|
316
|
|
- if ( ( doc_list[0] == 0x1F ) && ( doc_list[1] == 0x8B )
|
317
|
|
- && ( doc_list[2] == 0x08 ) )
|
|
323
|
+ if ( doc_length > 6 &&
|
|
324
|
+ doc[0] == 0x1F &&
|
|
325
|
+ doc[1] == 0x8B &&
|
|
326
|
+ doc[2] == 0x08 )
|
318
|
327
|
{
|
319
|
328
|
#ifdef FT_CONFIG_OPTION_USE_ZLIB
|
320
|
329
|
|
... |
... |
@@ -331,10 +340,10 @@ |
331
|
340
|
* little-endian format.
|
332
|
341
|
*/
|
333
|
342
|
FT_TRACE4(( "SVG document is GZIP compressed\n" ));
|
334
|
|
- uncomp_size = (FT_ULong)doc_list[doc_length - 1] << 24 |
|
335
|
|
- (FT_ULong)doc_list[doc_length - 2] << 16 |
|
336
|
|
- (FT_ULong)doc_list[doc_length - 3] << 8 |
|
337
|
|
- (FT_ULong)doc_list[doc_length - 4];
|
|
343
|
+ uncomp_size = (FT_ULong)doc[doc_length - 1] << 24 |
|
|
344
|
+ (FT_ULong)doc[doc_length - 2] << 16 |
|
|
345
|
+ (FT_ULong)doc[doc_length - 3] << 8 |
|
|
346
|
+ (FT_ULong)doc[doc_length - 4];
|
338
|
347
|
|
339
|
348
|
if ( FT_QALLOC( uncomp_buffer, uncomp_size ) )
|
340
|
349
|
goto Exit;
|
... |
... |
@@ -342,7 +351,7 @@ |
342
|
351
|
error = FT_Gzip_Uncompress( memory,
|
343
|
352
|
uncomp_buffer,
|
344
|
353
|
&uncomp_size,
|
345
|
|
- doc_list,
|
|
354
|
+ doc,
|
346
|
355
|
doc_length );
|
347
|
356
|
if ( error )
|
348
|
357
|
{
|
... |
... |
@@ -353,7 +362,7 @@ |
353
|
362
|
|
354
|
363
|
glyph->internal->flags |= FT_GLYPH_OWN_GZIP_SVG;
|
355
|
364
|
|
356
|
|
- doc_list = uncomp_buffer;
|
|
365
|
+ doc = uncomp_buffer;
|
357
|
366
|
doc_length = uncomp_size;
|
358
|
367
|
|
359
|
368
|
#else /* !FT_CONFIG_OPTION_USE_ZLIB */
|
... |
... |
@@ -364,14 +373,14 @@ |
364
|
373
|
#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
|
365
|
374
|
}
|
366
|
375
|
|
367
|
|
- svg_document->svg_document = doc_list;
|
|
376
|
+ svg_document->svg_document = doc;
|
368
|
377
|
svg_document->svg_document_length = doc_length;
|
369
|
378
|
|
370
|
379
|
svg_document->metrics = glyph->face->size->metrics;
|
371
|
380
|
svg_document->units_per_EM = glyph->face->units_per_EM;
|
372
|
381
|
|
373
|
|
- svg_document->start_glyph_id = start_glyph_id;
|
374
|
|
- svg_document->end_glyph_id = end_glyph_id;
|
|
382
|
+ svg_document->start_glyph_id = doc_start_glyph_id;
|
|
383
|
+ svg_document->end_glyph_id = doc_end_glyph_id;
|
375
|
384
|
|
376
|
385
|
svg_document->transform.xx = 0x10000;
|
377
|
386
|
svg_document->transform.xy = 0;
|
... |
... |
@@ -381,10 +390,10 @@ |
381
|
390
|
svg_document->delta.x = 0;
|
382
|
391
|
svg_document->delta.y = 0;
|
383
|
392
|
|
384
|
|
- FT_TRACE5(( "start_glyph_id: %d\n", start_glyph_id ));
|
385
|
|
- FT_TRACE5(( "end_glyph_id: %d\n", end_glyph_id ));
|
|
393
|
+ FT_TRACE5(( "start_glyph_id: %d\n", doc_start_glyph_id ));
|
|
394
|
+ FT_TRACE5(( "end_glyph_id: %d\n", doc_end_glyph_id ));
|
386
|
395
|
FT_TRACE5(( "svg_document:\n" ));
|
387
|
|
- FT_TRACE5(( " %.*s\n", (FT_UInt)doc_length, doc_list ));
|
|
396
|
+ FT_TRACE5(( " %.*s\n", (FT_UInt)doc_length, doc ));
|
388
|
397
|
|
389
|
398
|
glyph->other = svg_document;
|
390
|
399
|
|