Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: third_party/freetype/src/sfnt/ttload.c

Issue 1413673003: Update bundled freetype to 2.6.1 (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: DEPS for corpus Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/freetype/src/sfnt/ttload.h ('k') | third_party/freetype/src/sfnt/ttmtx.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /***************************************************************************/ 1 /***************************************************************************/
2 /* */ 2 /* */
3 /* ttload.c */ 3 /* ttload.c */
4 /* */ 4 /* */
5 /* Load the basic TrueType tables, i.e., tables that can be either in */ 5 /* Load the basic TrueType tables, i.e., tables that can be either in */
6 /* TTF or OTF fonts (body). */ 6 /* TTF or OTF fonts (body). */
7 /* */ 7 /* */
8 /* Copyright 1996-2010, 2012-2014 by */ 8 /* Copyright 1996-2015 by */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* */ 10 /* */
11 /* This file is part of the FreeType project, and may only be used, */ 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 */ 12 /* modified, and distributed under the terms of the FreeType project */
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
14 /* this file you indicate that you have read the license and */ 14 /* this file you indicate that you have read the license and */
15 /* understand and accept it fully. */ 15 /* understand and accept it fully. */
16 /* */ 16 /* */
17 /***************************************************************************/ 17 /***************************************************************************/
18 18
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 else 144 else
145 error = FT_THROW( Table_Missing ); 145 error = FT_THROW( Table_Missing );
146 146
147 Exit: 147 Exit:
148 return error; 148 return error;
149 } 149 }
150 150
151 151
152 /* Here, we */ 152 /* Here, we */
153 /* */ 153 /* */
154 /* - check that `num_tables' is valid (and adjust it if necessary) */ 154 /* - check that `num_tables' is valid (and adjust it if necessary); */
155 /* also return the number of valid table entries */
155 /* */ 156 /* */
156 /* - look for a `head' table, check its size, and parse it to check */ 157 /* - look for a `head' table, check its size, and parse it to check */
157 /* whether its `magic' field is correctly set */ 158 /* whether its `magic' field is correctly set */
158 /* */ 159 /* */
159 /* - errors (except errors returned by stream handling) */ 160 /* - errors (except errors returned by stream handling) */
160 /* */ 161 /* */
161 /* SFNT_Err_Unknown_File_Format: */ 162 /* SFNT_Err_Unknown_File_Format: */
162 /* no table is defined in directory, it is not sfnt-wrapped */ 163 /* no table is defined in directory, it is not sfnt-wrapped */
163 /* data */ 164 /* data */
164 /* SFNT_Err_Table_Missing: */ 165 /* SFNT_Err_Table_Missing: */
165 /* table directory is valid, but essential tables */ 166 /* table directory is valid, but essential tables */
166 /* (head/bhed/SING) are missing */ 167 /* (head/bhed/SING) are missing */
167 /* */ 168 /* */
168 static FT_Error 169 static FT_Error
169 check_table_dir( SFNT_Header sfnt, 170 check_table_dir( SFNT_Header sfnt,
170 FT_Stream stream ) 171 FT_Stream stream,
172 FT_UShort* valid )
171 { 173 {
172 FT_Error error; 174 FT_Error error;
173 FT_UShort nn, valid_entries = 0; 175 FT_UShort nn, valid_entries = 0;
174 FT_UInt has_head = 0, has_sing = 0, has_meta = 0; 176 FT_UInt has_head = 0, has_sing = 0, has_meta = 0;
175 FT_ULong offset = sfnt->offset + 12; 177 FT_ULong offset = sfnt->offset + 12;
176 178
177 static const FT_Frame_Field table_dir_entry_fields[] = 179 static const FT_Frame_Field table_dir_entry_fields[] =
178 { 180 {
179 #undef FT_STRUCTURE 181 #undef FT_STRUCTURE
180 #define FT_STRUCTURE TT_TableRec 182 #define FT_STRUCTURE TT_TableRec
(...skipping 20 matching lines...) Expand all
201 nn--; 203 nn--;
202 FT_TRACE2(( "check_table_dir:" 204 FT_TRACE2(( "check_table_dir:"
203 " can read only %d table%s in font (instead of %d)\n", 205 " can read only %d table%s in font (instead of %d)\n",
204 nn, nn == 1 ? "" : "s", sfnt->num_tables )); 206 nn, nn == 1 ? "" : "s", sfnt->num_tables ));
205 sfnt->num_tables = nn; 207 sfnt->num_tables = nn;
206 break; 208 break;
207 } 209 }
208 210
209 /* we ignore invalid tables */ 211 /* we ignore invalid tables */
210 212
211 /* table.Offset + table.Length > stream->size ? */ 213 if ( table.Offset > stream->size )
212 if ( table.Length > stream->size ||
213 table.Offset > stream->size - table.Length )
214 { 214 {
215 FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); 215 FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
216 continue; 216 continue;
217 } 217 }
218 else if ( table.Length > stream->size - table.Offset )
219 {
220 /* Some tables have such a simple structure that clipping its */
221 /* contents is harmless. This also makes FreeType less sensitive */
222 /* to invalid table lengths (which programs like Acroread seem to */
223 /* ignore in general). */
224
225 if ( table.Tag == TTAG_hmtx ||
226 table.Tag == TTAG_vmtx )
227 valid_entries++;
228 else
229 {
230 FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
231 continue;
232 }
233 }
218 else 234 else
219 valid_entries++; 235 valid_entries++;
220 236
221 if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed ) 237 if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
222 { 238 {
223 FT_UInt32 magic; 239 FT_UInt32 magic;
224 240
225 241
226 #ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 242 #ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
227 if ( table.Tag == TTAG_head ) 243 if ( table.Tag == TTAG_head )
(...skipping 27 matching lines...) Expand all
255 271
256 if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) ) 272 if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
257 goto Exit; 273 goto Exit;
258 } 274 }
259 else if ( table.Tag == TTAG_SING ) 275 else if ( table.Tag == TTAG_SING )
260 has_sing = 1; 276 has_sing = 1;
261 else if ( table.Tag == TTAG_META ) 277 else if ( table.Tag == TTAG_META )
262 has_meta = 1; 278 has_meta = 1;
263 } 279 }
264 280
265 sfnt->num_tables = valid_entries; 281 *valid = valid_entries;
266 282
267 if ( sfnt->num_tables == 0 ) 283 if ( !valid_entries )
268 { 284 {
269 FT_TRACE2(( "check_table_dir: no tables found\n" )); 285 FT_TRACE2(( "check_table_dir: no valid tables found\n" ));
270 error = FT_THROW( Unknown_File_Format ); 286 error = FT_THROW( Unknown_File_Format );
271 goto Exit; 287 goto Exit;
272 } 288 }
273 289
274 /* if `sing' and `meta' tables are present, there is no `head' table */ 290 /* if `sing' and `meta' tables are present, there is no `head' table */
275 if ( has_head || ( has_sing && has_meta ) ) 291 if ( has_head || ( has_sing && has_meta ) )
276 { 292 {
277 error = FT_Err_Ok; 293 error = FT_Err_Ok;
278 goto Exit; 294 goto Exit;
279 } 295 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 /* <Note> */ 331 /* <Note> */
316 /* The stream cursor must be at the beginning of the font directory. */ 332 /* The stream cursor must be at the beginning of the font directory. */
317 /* */ 333 /* */
318 FT_LOCAL_DEF( FT_Error ) 334 FT_LOCAL_DEF( FT_Error )
319 tt_face_load_font_dir( TT_Face face, 335 tt_face_load_font_dir( TT_Face face,
320 FT_Stream stream ) 336 FT_Stream stream )
321 { 337 {
322 SFNT_HeaderRec sfnt; 338 SFNT_HeaderRec sfnt;
323 FT_Error error; 339 FT_Error error;
324 FT_Memory memory = stream->memory; 340 FT_Memory memory = stream->memory;
325 TT_TableRec* entry; 341 FT_UShort nn, valid_entries;
326 FT_Int nn;
327 342
328 static const FT_Frame_Field offset_table_fields[] = 343 static const FT_Frame_Field offset_table_fields[] =
329 { 344 {
330 #undef FT_STRUCTURE 345 #undef FT_STRUCTURE
331 #define FT_STRUCTURE SFNT_HeaderRec 346 #define FT_STRUCTURE SFNT_HeaderRec
332 347
333 FT_FRAME_START( 8 ), 348 FT_FRAME_START( 8 ),
334 FT_FRAME_USHORT( num_tables ), 349 FT_FRAME_USHORT( num_tables ),
335 FT_FRAME_USHORT( search_range ), 350 FT_FRAME_USHORT( search_range ),
336 FT_FRAME_USHORT( entry_selector ), 351 FT_FRAME_USHORT( entry_selector ),
(...skipping 20 matching lines...) Expand all
357 #endif 372 #endif
358 373
359 /* load the table directory */ 374 /* load the table directory */
360 375
361 FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables )); 376 FT_TRACE2(( "-- Number of tables: %10u\n", sfnt.num_tables ));
362 FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag )); 377 FT_TRACE2(( "-- Format version: 0x%08lx\n", sfnt.format_tag ));
363 378
364 if ( sfnt.format_tag != TTAG_OTTO ) 379 if ( sfnt.format_tag != TTAG_OTTO )
365 { 380 {
366 /* check first */ 381 /* check first */
367 error = check_table_dir( &sfnt, stream ); 382 error = check_table_dir( &sfnt, stream, &valid_entries );
368 if ( error ) 383 if ( error )
369 { 384 {
370 FT_TRACE2(( "tt_face_load_font_dir:" 385 FT_TRACE2(( "tt_face_load_font_dir:"
371 " invalid table directory for TrueType\n" )); 386 " invalid table directory for TrueType\n" ));
372
373 goto Exit; 387 goto Exit;
374 } 388 }
375 } 389 }
390 else
391 valid_entries = sfnt.num_tables;
376 392
377 face->num_tables = sfnt.num_tables; 393 face->num_tables = valid_entries;
378 face->format_tag = sfnt.format_tag; 394 face->format_tag = sfnt.format_tag;
379 395
380 if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) 396 if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
381 goto Exit; 397 goto Exit;
382 398
383 if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || 399 if ( FT_STREAM_SEEK( sfnt.offset + 12 ) ||
384 FT_FRAME_ENTER( face->num_tables * 16L ) ) 400 FT_FRAME_ENTER( sfnt.num_tables * 16L ) )
385 goto Exit; 401 goto Exit;
386 402
387 entry = face->dir_tables;
388
389 FT_TRACE2(( "\n" 403 FT_TRACE2(( "\n"
390 " tag offset length checksum\n" 404 " tag offset length checksum\n"
391 " ----------------------------------\n" )); 405 " ----------------------------------\n" ));
392 406
407 valid_entries = 0;
393 for ( nn = 0; nn < sfnt.num_tables; nn++ ) 408 for ( nn = 0; nn < sfnt.num_tables; nn++ )
394 { 409 {
395 entry->Tag = FT_GET_TAG4(); 410 TT_TableRec entry;
396 entry->CheckSum = FT_GET_ULONG(); 411 FT_UShort i;
397 entry->Offset = FT_GET_ULONG(); 412 FT_Bool duplicate;
398 entry->Length = FT_GET_ULONG();
399 413
400 /* ignore invalid tables */
401 414
402 /* entry->Offset + entry->Length > stream->size ? */ 415 entry.Tag = FT_GET_TAG4();
403 if ( entry->Length > stream->size || 416 entry.CheckSum = FT_GET_ULONG();
404 entry->Offset > stream->size - entry->Length ) 417 entry.Offset = FT_GET_ULONG();
418 entry.Length = FT_GET_ULONG();
419
420 /* ignore invalid tables that can't be sanitized */
421
422 if ( entry.Offset > stream->size )
405 continue; 423 continue;
424 else if ( entry.Length > stream->size - entry.Offset )
425 {
426 if ( entry.Tag == TTAG_hmtx ||
427 entry.Tag == TTAG_vmtx )
428 {
429 #ifdef FT_DEBUG_LEVEL_TRACE
430 FT_ULong old_length = entry.Length;
431 #endif
432
433
434 /* make metrics table length a multiple of 4 */
435 entry.Length = ( stream->size - entry.Offset ) & ~3U;
436
437 FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx"
438 " (sanitized; original length %08lx)",
439 (FT_Char)( entry.Tag >> 24 ),
440 (FT_Char)( entry.Tag >> 16 ),
441 (FT_Char)( entry.Tag >> 8 ),
442 (FT_Char)( entry.Tag ),
443 entry.Offset,
444 entry.Length,
445 entry.CheckSum,
446 old_length ));
447 }
448 else
449 continue;
450 }
451 #ifdef FT_DEBUG_LEVEL_TRACE
452 else
453 FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx",
454 (FT_Char)( entry.Tag >> 24 ),
455 (FT_Char)( entry.Tag >> 16 ),
456 (FT_Char)( entry.Tag >> 8 ),
457 (FT_Char)( entry.Tag ),
458 entry.Offset,
459 entry.Length,
460 entry.CheckSum ));
461 #endif
462
463 /* ignore duplicate tables – the first one wins */
464 duplicate = 0;
465 for ( i = 0; i < valid_entries; i++ )
466 {
467 if ( face->dir_tables[i].Tag == entry.Tag )
468 {
469 duplicate = 1;
470 break;
471 }
472 }
473 if ( duplicate )
474 {
475 FT_TRACE2(( " (duplicate, ignored)\n" ));
476 continue;
477 }
406 else 478 else
407 { 479 {
408 FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", 480 FT_TRACE2(( "\n" ));
409 (FT_Char)( entry->Tag >> 24 ), 481
410 (FT_Char)( entry->Tag >> 16 ), 482 /* we finally have a valid entry */
411 (FT_Char)( entry->Tag >> 8 ), 483 face->dir_tables[valid_entries++] = entry;
412 (FT_Char)( entry->Tag ),
413 entry->Offset,
414 entry->Length,
415 entry->CheckSum ));
416 entry++;
417 } 484 }
418 } 485 }
419 486
487 /* final adjustment to number of tables */
488 face->num_tables = valid_entries;
489
420 FT_FRAME_EXIT(); 490 FT_FRAME_EXIT();
421 491
422 FT_TRACE2(( "table directory loaded\n\n" )); 492 FT_TRACE2(( "table directory loaded\n\n" ));
423 493
424 Exit: 494 Exit:
425 return error; 495 return error;
426 } 496 }
427 497
428 498
429 /*************************************************************************/ 499 /*************************************************************************/
(...skipping 854 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 } 1354 }
1285 1355
1286 FT_FRAME_EXIT(); 1356 FT_FRAME_EXIT();
1287 1357
1288 Exit: 1358 Exit:
1289 return error; 1359 return error;
1290 } 1360 }
1291 1361
1292 1362
1293 /* END */ 1363 /* END */
OLDNEW
« no previous file with comments | « third_party/freetype/src/sfnt/ttload.h ('k') | third_party/freetype/src/sfnt/ttmtx.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698