OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "layout.h" | 5 #include "layout.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "gdef.h" | 10 #include "gdef.h" |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 OTS_WARNING("bad class value: %u", class_value); | 329 OTS_WARNING("bad class value: %u", class_value); |
330 return OTS_FAILURE(); | 330 return OTS_FAILURE(); |
331 } | 331 } |
332 last_end = end; | 332 last_end = end; |
333 } | 333 } |
334 | 334 |
335 return true; | 335 return true; |
336 } | 336 } |
337 | 337 |
338 bool ParseCoverageFormat1(const uint8_t *data, size_t length, | 338 bool ParseCoverageFormat1(const uint8_t *data, size_t length, |
339 const uint16_t num_glyphs) { | 339 const uint16_t num_glyphs, |
| 340 const uint16_t expected_num_glyphs) { |
340 ots::Buffer subtable(data, length); | 341 ots::Buffer subtable(data, length); |
341 | 342 |
342 // Skip format field. | 343 // Skip format field. |
343 if (!subtable.Skip(2)) { | 344 if (!subtable.Skip(2)) { |
344 return OTS_FAILURE(); | 345 return OTS_FAILURE(); |
345 } | 346 } |
346 | 347 |
347 uint16_t glyph_count = 0; | 348 uint16_t glyph_count = 0; |
348 if (!subtable.ReadU16(&glyph_count)) { | 349 if (!subtable.ReadU16(&glyph_count)) { |
349 return OTS_FAILURE(); | 350 return OTS_FAILURE(); |
350 } | 351 } |
351 if (glyph_count > num_glyphs) { | 352 if (glyph_count > num_glyphs) { |
352 OTS_WARNING("bad glyph count: %u", glyph_count); | 353 OTS_WARNING("bad glyph count: %u", glyph_count); |
353 return OTS_FAILURE(); | 354 return OTS_FAILURE(); |
354 } | 355 } |
355 for (unsigned i = 0; i < glyph_count; ++i) { | 356 for (unsigned i = 0; i < glyph_count; ++i) { |
356 uint16_t glyph = 0; | 357 uint16_t glyph = 0; |
357 if (!subtable.ReadU16(&glyph)) { | 358 if (!subtable.ReadU16(&glyph)) { |
358 return OTS_FAILURE(); | 359 return OTS_FAILURE(); |
359 } | 360 } |
360 if (glyph > num_glyphs) { | 361 if (glyph > num_glyphs) { |
361 OTS_WARNING("bad glyph ID: %u", glyph); | 362 OTS_WARNING("bad glyph ID: %u", glyph); |
362 return OTS_FAILURE(); | 363 return OTS_FAILURE(); |
363 } | 364 } |
364 } | 365 } |
365 | 366 |
| 367 if (expected_num_glyphs && expected_num_glyphs != glyph_count) { |
| 368 OTS_WARNING("unexpected number of glyphs: %u", glyph_count); |
| 369 return OTS_FAILURE(); |
| 370 } |
| 371 |
366 return true; | 372 return true; |
367 } | 373 } |
368 | 374 |
369 bool ParseCoverageFormat2(const uint8_t *data, size_t length, | 375 bool ParseCoverageFormat2(const uint8_t *data, size_t length, |
370 const uint16_t num_glyphs) { | 376 const uint16_t num_glyphs, |
| 377 const uint16_t expected_num_glyphs) { |
371 ots::Buffer subtable(data, length); | 378 ots::Buffer subtable(data, length); |
372 | 379 |
373 // Skip format field. | 380 // Skip format field. |
374 if (!subtable.Skip(2)) { | 381 if (!subtable.Skip(2)) { |
375 return OTS_FAILURE(); | 382 return OTS_FAILURE(); |
376 } | 383 } |
377 | 384 |
378 uint16_t range_count = 0; | 385 uint16_t range_count = 0; |
379 if (!subtable.ReadU16(&range_count)) { | 386 if (!subtable.ReadU16(&range_count)) { |
380 return OTS_FAILURE(); | 387 return OTS_FAILURE(); |
(...skipping 23 matching lines...) Expand all Loading... |
404 return OTS_FAILURE(); | 411 return OTS_FAILURE(); |
405 } | 412 } |
406 if (start_coverage_index != last_start_coverage_index) { | 413 if (start_coverage_index != last_start_coverage_index) { |
407 OTS_WARNING("bad start coverage index."); | 414 OTS_WARNING("bad start coverage index."); |
408 return OTS_FAILURE(); | 415 return OTS_FAILURE(); |
409 } | 416 } |
410 last_end = end; | 417 last_end = end; |
411 last_start_coverage_index += end - start + 1; | 418 last_start_coverage_index += end - start + 1; |
412 } | 419 } |
413 | 420 |
| 421 if (expected_num_glyphs && |
| 422 expected_num_glyphs != last_start_coverage_index) { |
| 423 OTS_WARNING("unexpected number of glyphs: %u", last_start_coverage_index); |
| 424 return OTS_FAILURE(); |
| 425 } |
| 426 |
414 return true; | 427 return true; |
415 } | 428 } |
416 | 429 |
417 // Parsers for Contextual subtables in GSUB/GPOS tables. | 430 // Parsers for Contextual subtables in GSUB/GPOS tables. |
418 | 431 |
419 bool ParseLookupRecord(ots::Buffer *subtable, const uint16_t num_glyphs, | 432 bool ParseLookupRecord(ots::Buffer *subtable, const uint16_t num_glyphs, |
420 const uint16_t num_lookups) { | 433 const uint16_t num_lookups) { |
421 uint16_t sequence_index = 0; | 434 uint16_t sequence_index = 0; |
422 uint16_t lookup_list_index = 0; | 435 uint16_t lookup_list_index = 0; |
423 if (!subtable->ReadU16(&sequence_index) || | 436 if (!subtable->ReadU16(&sequence_index) || |
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 if (format == 1) { | 1341 if (format == 1) { |
1329 return ParseClassDefFormat1(data, length, num_glyphs, num_classes); | 1342 return ParseClassDefFormat1(data, length, num_glyphs, num_classes); |
1330 } else if (format == 2) { | 1343 } else if (format == 2) { |
1331 return ParseClassDefFormat2(data, length, num_glyphs, num_classes); | 1344 return ParseClassDefFormat2(data, length, num_glyphs, num_classes); |
1332 } | 1345 } |
1333 | 1346 |
1334 return OTS_FAILURE(); | 1347 return OTS_FAILURE(); |
1335 } | 1348 } |
1336 | 1349 |
1337 bool ParseCoverageTable(const uint8_t *data, size_t length, | 1350 bool ParseCoverageTable(const uint8_t *data, size_t length, |
1338 const uint16_t num_glyphs) { | 1351 const uint16_t num_glyphs, |
| 1352 const uint16_t expected_num_glyphs) { |
1339 Buffer subtable(data, length); | 1353 Buffer subtable(data, length); |
1340 | 1354 |
1341 uint16_t format = 0; | 1355 uint16_t format = 0; |
1342 if (!subtable.ReadU16(&format)) { | 1356 if (!subtable.ReadU16(&format)) { |
1343 return OTS_FAILURE(); | 1357 return OTS_FAILURE(); |
1344 } | 1358 } |
1345 if (format == 1) { | 1359 if (format == 1) { |
1346 return ParseCoverageFormat1(data, length, num_glyphs); | 1360 return ParseCoverageFormat1(data, length, num_glyphs, expected_num_glyphs); |
1347 } else if (format == 2) { | 1361 } else if (format == 2) { |
1348 return ParseCoverageFormat2(data, length, num_glyphs); | 1362 return ParseCoverageFormat2(data, length, num_glyphs, expected_num_glyphs); |
1349 } | 1363 } |
1350 | 1364 |
1351 return OTS_FAILURE(); | 1365 return OTS_FAILURE(); |
1352 } | 1366 } |
1353 | 1367 |
1354 bool ParseDeviceTable(const uint8_t *data, size_t length) { | 1368 bool ParseDeviceTable(const uint8_t *data, size_t length) { |
1355 Buffer subtable(data, length); | 1369 Buffer subtable(data, length); |
1356 | 1370 |
1357 uint16_t start_size = 0; | 1371 uint16_t start_size = 0; |
1358 uint16_t end_size = 0; | 1372 uint16_t end_size = 0; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 if (!parser->Parse(file, data + offset_extension, length - offset_extension, | 1487 if (!parser->Parse(file, data + offset_extension, length - offset_extension, |
1474 lookup_type)) { | 1488 lookup_type)) { |
1475 return OTS_FAILURE(); | 1489 return OTS_FAILURE(); |
1476 } | 1490 } |
1477 | 1491 |
1478 return true; | 1492 return true; |
1479 } | 1493 } |
1480 | 1494 |
1481 } // namespace ots | 1495 } // namespace ots |
1482 | 1496 |
OLD | NEW |