OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "cmap.h" | 5 #include "cmap.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 18 matching lines...) Expand all Loading... |
29 }; | 29 }; |
30 | 30 |
31 struct Subtable314Range { | 31 struct Subtable314Range { |
32 uint16_t start_range; | 32 uint16_t start_range; |
33 uint16_t end_range; | 33 uint16_t end_range; |
34 int16_t id_delta; | 34 int16_t id_delta; |
35 uint16_t id_range_offset; | 35 uint16_t id_range_offset; |
36 uint32_t id_range_offset_offset; | 36 uint32_t id_range_offset_offset; |
37 }; | 37 }; |
38 | 38 |
39 // The maximum number of groups in format 12, 13 or 14 subtables. | |
40 // Note: 0xFFFF is the maximum number of glyphs in a single font file. | |
41 const unsigned kMaxCMAPGroups = 0xFFFF; | |
42 | |
43 // Glyph array size for the Mac Roman (format 0) table. | 39 // Glyph array size for the Mac Roman (format 0) table. |
44 const size_t kFormat0ArraySize = 256; | 40 const size_t kFormat0ArraySize = 256; |
45 | 41 |
46 // The upper limit of the Unicode code point. | 42 // The upper limit of the Unicode code point. |
47 const uint32_t kUnicodeUpperLimit = 0x10FFFF; | 43 const uint32_t kUnicodeUpperLimit = 0x10FFFF; |
48 | 44 |
49 // The maximum number of UVS records (See below). | 45 // The maximum number of UVS records (See below). |
50 const uint32_t kMaxCMAPSelectorRecords = 259; | 46 const uint32_t kMaxCMAPSelectorRecords = 259; |
51 // The range of UVSes are: | 47 // The range of UVSes are: |
52 // 0x180B-0x180D (3 code points) | 48 // 0x180B-0x180D (3 code points) |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 return OTS_FAILURE_MSG("can't read format 12 subtable language"); | 275 return OTS_FAILURE_MSG("can't read format 12 subtable language"); |
280 } | 276 } |
281 if (language) { | 277 if (language) { |
282 return OTS_FAILURE_MSG("format 12 subtable language should be zero (%d)", la
nguage); | 278 return OTS_FAILURE_MSG("format 12 subtable language should be zero (%d)", la
nguage); |
283 } | 279 } |
284 | 280 |
285 uint32_t num_groups = 0; | 281 uint32_t num_groups = 0; |
286 if (!subtable.ReadU32(&num_groups)) { | 282 if (!subtable.ReadU32(&num_groups)) { |
287 return OTS_FAILURE_MSG("can't read number of format 12 subtable groups"); | 283 return OTS_FAILURE_MSG("can't read number of format 12 subtable groups"); |
288 } | 284 } |
289 if (num_groups == 0 || num_groups > kMaxCMAPGroups) { | 285 if (num_groups == 0 || subtable.remaining() < num_groups * 12) { |
290 return OTS_FAILURE_MSG("Bad format 12 subtable group count %d", num_groups); | 286 return OTS_FAILURE_MSG("Bad format 12 subtable group count %d", num_groups); |
291 } | 287 } |
292 | 288 |
293 std::vector<ots::OpenTypeCMAPSubtableRange> &groups | 289 std::vector<ots::OpenTypeCMAPSubtableRange> &groups |
294 = font->cmap->subtable_3_10_12; | 290 = font->cmap->subtable_3_10_12; |
295 groups.resize(num_groups); | 291 groups.resize(num_groups); |
296 | 292 |
297 for (unsigned i = 0; i < num_groups; ++i) { | 293 for (unsigned i = 0; i < num_groups; ++i) { |
298 if (!subtable.ReadU32(&groups[i].start_range) || | 294 if (!subtable.ReadU32(&groups[i].start_range) || |
299 !subtable.ReadU32(&groups[i].end_range) || | 295 !subtable.ReadU32(&groups[i].end_range) || |
300 !subtable.ReadU32(&groups[i].start_glyph_id)) { | 296 !subtable.ReadU32(&groups[i].start_glyph_id)) { |
301 return OTS_FAILURE_MSG("can't read format 12 subtable group"); | 297 return OTS_FAILURE_MSG("can't read format 12 subtable group"); |
302 } | 298 } |
303 | 299 |
304 if (groups[i].start_range > kUnicodeUpperLimit || | 300 if (groups[i].start_range > kUnicodeUpperLimit || |
305 groups[i].end_range > kUnicodeUpperLimit || | 301 groups[i].end_range > kUnicodeUpperLimit || |
306 groups[i].start_glyph_id > 0xFFFF) { | 302 groups[i].start_glyph_id > 0xFFFF) { |
307 return OTS_FAILURE_MSG("bad format 12 subtable group (startCharCode=0x%4X,
endCharCode=0x%4X, startGlyphID=%d)", | 303 return OTS_FAILURE_MSG("bad format 12 subtable group (startCharCode=0x%4X,
endCharCode=0x%4X, startGlyphID=%d)", |
308 groups[i].start_range, groups[i].end_range, groups[
i].start_glyph_id); | 304 groups[i].start_range, groups[i].end_range, groups[
i].start_glyph_id); |
309 } | 305 } |
310 | 306 |
311 // [0xD800, 0xDFFF] are surrogate code points. | |
312 if (groups[i].start_range >= 0xD800 && | |
313 groups[i].start_range <= 0xDFFF) { | |
314 return OTS_FAILURE_MSG("format 12 subtable out of range group startCharCod
e (0x%4X)", groups[i].start_range); | |
315 } | |
316 if (groups[i].end_range >= 0xD800 && | |
317 groups[i].end_range <= 0xDFFF) { | |
318 return OTS_FAILURE_MSG("format 12 subtable out of range group endCharCode
(0x%4X)", groups[i].end_range); | |
319 } | |
320 if (groups[i].start_range < 0xD800 && | |
321 groups[i].end_range > 0xDFFF) { | |
322 return OTS_FAILURE_MSG("bad format 12 subtable group startCharCode (0x%4X)
or endCharCode (0x%4X)", | |
323 groups[i].start_range, groups[i].end_range); | |
324 } | |
325 | |
326 // We assert that the glyph value is within range. Because of the range | 307 // We assert that the glyph value is within range. Because of the range |
327 // limits, above, we don't need to worry about overflow. | 308 // limits, above, we don't need to worry about overflow. |
328 if (groups[i].end_range < groups[i].start_range) { | 309 if (groups[i].end_range < groups[i].start_range) { |
329 return OTS_FAILURE_MSG("format 12 subtable group endCharCode before startC
harCode (0x%4X < 0x%4X)", | 310 return OTS_FAILURE_MSG("format 12 subtable group endCharCode before startC
harCode (0x%4X < 0x%4X)", |
330 groups[i].end_range, groups[i].start_range); | 311 groups[i].end_range, groups[i].start_range); |
331 } | 312 } |
332 if ((groups[i].end_range - groups[i].start_range) + | 313 if ((groups[i].end_range - groups[i].start_range) + |
333 groups[i].start_glyph_id > num_glyphs) { | 314 groups[i].start_glyph_id > num_glyphs) { |
334 return OTS_FAILURE_MSG("bad format 12 subtable group startGlyphID (%d)", g
roups[i].start_glyph_id); | 315 return OTS_FAILURE_MSG("bad format 12 subtable group startGlyphID (%d)", g
roups[i].start_glyph_id); |
335 } | 316 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 return OTS_FAILURE_MSG("Cmap subtable language should be zero but is %d", la
nguage); | 349 return OTS_FAILURE_MSG("Cmap subtable language should be zero but is %d", la
nguage); |
369 } | 350 } |
370 | 351 |
371 uint32_t num_groups = 0; | 352 uint32_t num_groups = 0; |
372 if (!subtable.ReadU32(&num_groups)) { | 353 if (!subtable.ReadU32(&num_groups)) { |
373 return OTS_FAILURE_MSG("Can't read number of groups in a cmap subtable"); | 354 return OTS_FAILURE_MSG("Can't read number of groups in a cmap subtable"); |
374 } | 355 } |
375 | 356 |
376 // We limit the number of groups in the same way as in 3.10.12 tables. See | 357 // We limit the number of groups in the same way as in 3.10.12 tables. See |
377 // the comment there in | 358 // the comment there in |
378 if (num_groups == 0 || num_groups > kMaxCMAPGroups) { | 359 if (num_groups == 0 || subtable.remaining() < num_groups * 12) { |
379 return OTS_FAILURE_MSG("Bad format 13 subtable group count %d", num_groups); | 360 return OTS_FAILURE_MSG("Bad format 13 subtable group count %d", num_groups); |
380 } | 361 } |
381 | 362 |
382 std::vector<ots::OpenTypeCMAPSubtableRange> &groups | 363 std::vector<ots::OpenTypeCMAPSubtableRange> &groups |
383 = font->cmap->subtable_3_10_13; | 364 = font->cmap->subtable_3_10_13; |
384 groups.resize(num_groups); | 365 groups.resize(num_groups); |
385 | 366 |
386 for (unsigned i = 0; i < num_groups; ++i) { | 367 for (unsigned i = 0; i < num_groups; ++i) { |
387 if (!subtable.ReadU32(&groups[i].start_range) || | 368 if (!subtable.ReadU32(&groups[i].start_range) || |
388 !subtable.ReadU32(&groups[i].end_range) || | 369 !subtable.ReadU32(&groups[i].end_range) || |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 } | 457 } |
477 | 458 |
478 for (unsigned i = 0; i < num_records; ++i) { | 459 for (unsigned i = 0; i < num_records; ++i) { |
479 // Checks default UVS table | 460 // Checks default UVS table |
480 if (records[i].default_offset) { | 461 if (records[i].default_offset) { |
481 subtable.set_offset(records[i].default_offset); | 462 subtable.set_offset(records[i].default_offset); |
482 uint32_t num_ranges = 0; | 463 uint32_t num_ranges = 0; |
483 if (!subtable.ReadU32(&num_ranges)) { | 464 if (!subtable.ReadU32(&num_ranges)) { |
484 return OTS_FAILURE_MSG("Can't read number of ranges in record %d", i); | 465 return OTS_FAILURE_MSG("Can't read number of ranges in record %d", i); |
485 } | 466 } |
486 if (num_ranges == 0 || num_ranges > kMaxCMAPGroups) { | 467 if (num_ranges == 0 || subtable.remaining() < num_ranges * 4) { |
487 return OTS_FAILURE_MSG("Bad number of ranges (%d) in record %d", num_ran
ges, i); | 468 return OTS_FAILURE_MSG("Bad number of ranges (%d) in record %d", num_ran
ges, i); |
488 } | 469 } |
489 | 470 |
490 uint32_t last_unicode_value = 0; | 471 uint32_t last_unicode_value = 0; |
491 std::vector<ots::OpenTypeCMAPSubtableVSRange>& ranges | 472 std::vector<ots::OpenTypeCMAPSubtableVSRange>& ranges |
492 = records[i].ranges; | 473 = records[i].ranges; |
493 ranges.resize(num_ranges); | 474 ranges.resize(num_ranges); |
494 | 475 |
495 for (unsigned j = 0; j < num_ranges; ++j) { | 476 for (unsigned j = 0; j < num_ranges; ++j) { |
496 if (!subtable.ReadU24(&ranges[j].unicode_value) || | 477 if (!subtable.ReadU24(&ranges[j].unicode_value) || |
(...skipping 13 matching lines...) Expand all Loading... |
510 } | 491 } |
511 } | 492 } |
512 | 493 |
513 // Checks non default UVS table | 494 // Checks non default UVS table |
514 if (records[i].non_default_offset) { | 495 if (records[i].non_default_offset) { |
515 subtable.set_offset(records[i].non_default_offset); | 496 subtable.set_offset(records[i].non_default_offset); |
516 uint32_t num_mappings = 0; | 497 uint32_t num_mappings = 0; |
517 if (!subtable.ReadU32(&num_mappings)) { | 498 if (!subtable.ReadU32(&num_mappings)) { |
518 return OTS_FAILURE_MSG("Can't read number of mappings in variation selec
tor record %d", i); | 499 return OTS_FAILURE_MSG("Can't read number of mappings in variation selec
tor record %d", i); |
519 } | 500 } |
520 if (num_mappings == 0) { | 501 if (num_mappings == 0 || subtable.remaining() < num_mappings * 5) { |
521 return OTS_FAILURE_MSG("Bad number of mappings (%d) in variation selecto
r record %d", num_mappings, i); | 502 return OTS_FAILURE_MSG("Bad number of mappings (%d) in variation selecto
r record %d", num_mappings, i); |
522 } | 503 } |
523 | 504 |
524 uint32_t last_unicode_value = 0; | 505 uint32_t last_unicode_value = 0; |
525 std::vector<ots::OpenTypeCMAPSubtableVSMapping>& mappings | 506 std::vector<ots::OpenTypeCMAPSubtableVSMapping>& mappings |
526 = records[i].mappings; | 507 = records[i].mappings; |
527 mappings.resize(num_mappings); | 508 mappings.resize(num_mappings); |
528 | 509 |
529 for (unsigned j = 0; j < num_mappings; ++j) { | 510 for (unsigned j = 0; j < num_mappings; ++j) { |
530 if (!subtable.ReadU24(&mappings[j].unicode_value) || | 511 if (!subtable.ReadU24(&mappings[j].unicode_value) || |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 font->cmap_reused = true; | 1078 font->cmap_reused = true; |
1098 } | 1079 } |
1099 | 1080 |
1100 void ots_cmap_free(Font *font) { | 1081 void ots_cmap_free(Font *font) { |
1101 delete font->cmap; | 1082 delete font->cmap; |
1102 } | 1083 } |
1103 | 1084 |
1104 } // namespace ots | 1085 } // namespace ots |
1105 | 1086 |
1106 #undef TABLE_NAME | 1087 #undef TABLE_NAME |
OLD | NEW |