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 "ots.h" | 5 #include "ots.h" |
6 | 6 |
7 #include <sys/types.h> | 7 #include <sys/types.h> |
8 #include <zlib.h> | 8 #include <zlib.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 } | 277 } |
278 | 278 |
279 uint32_t reported_total_sfnt_size; | 279 uint32_t reported_total_sfnt_size; |
280 if (!file.ReadU32(&reported_total_sfnt_size)) { | 280 if (!file.ReadU32(&reported_total_sfnt_size)) { |
281 return OTS_FAILURE_MSG_HDR("error reading total sfnt size"); | 281 return OTS_FAILURE_MSG_HDR("error reading total sfnt size"); |
282 } | 282 } |
283 | 283 |
284 // We don't care about these fields of the header: | 284 // We don't care about these fields of the header: |
285 // uint16_t major_version, minor_version | 285 // uint16_t major_version, minor_version |
286 if (!file.Skip(2 * 2)) { | 286 if (!file.Skip(2 * 2)) { |
287 return OTS_FAILURE_MSG_HDR("error skipping WOFF header fields"); | 287 return OTS_FAILURE_MSG_HDR("Failed to read 'majorVersion' or 'minorVersion'"
); |
288 } | 288 } |
289 | 289 |
290 // Checks metadata block size. | 290 // Checks metadata block size. |
291 uint32_t meta_offset; | 291 uint32_t meta_offset; |
292 uint32_t meta_length; | 292 uint32_t meta_length; |
293 uint32_t meta_length_orig; | 293 uint32_t meta_length_orig; |
294 if (!file.ReadU32(&meta_offset) || | 294 if (!file.ReadU32(&meta_offset) || |
295 !file.ReadU32(&meta_length) || | 295 !file.ReadU32(&meta_length) || |
296 !file.ReadU32(&meta_length_orig)) { | 296 !file.ReadU32(&meta_length_orig)) { |
297 return OTS_FAILURE_MSG_HDR("error reading WOFF header fields"); | 297 return OTS_FAILURE_MSG_HDR("Failed to read header metadata block fields"); |
298 } | 298 } |
299 if (meta_offset) { | 299 if (meta_offset) { |
300 if (meta_offset >= length || length - meta_offset < meta_length) { | 300 if (meta_offset >= length || length - meta_offset < meta_length) { |
301 return OTS_FAILURE_MSG_HDR("invalid metadata block location/size"); | 301 return OTS_FAILURE_MSG_HDR("Invalid metadata block offset or length"); |
302 } | 302 } |
303 } | 303 } |
304 | 304 |
305 // Checks private data block size. | 305 // Checks private data block size. |
306 uint32_t priv_offset; | 306 uint32_t priv_offset; |
307 uint32_t priv_length; | 307 uint32_t priv_length; |
308 if (!file.ReadU32(&priv_offset) || | 308 if (!file.ReadU32(&priv_offset) || |
309 !file.ReadU32(&priv_length)) { | 309 !file.ReadU32(&priv_length)) { |
310 return OTS_FAILURE_MSG_HDR("error reading WOFF header fields"); | 310 return OTS_FAILURE_MSG_HDR("Failed to read header private block fields"); |
311 } | 311 } |
312 if (priv_offset) { | 312 if (priv_offset) { |
313 if (priv_offset >= length || length - priv_offset < priv_length) { | 313 if (priv_offset >= length || length - priv_offset < priv_length) { |
314 return OTS_FAILURE_MSG_HDR("invalid private block location/size"); | 314 return OTS_FAILURE_MSG_HDR("Invalid private block offset or length"); |
315 } | 315 } |
316 } | 316 } |
317 | 317 |
318 // Next up is the list of tables. | 318 // Next up is the list of tables. |
319 std::vector<OpenTypeTable> tables; | 319 std::vector<OpenTypeTable> tables; |
320 | 320 |
321 uint32_t first_index = 0; | 321 uint32_t first_index = 0; |
322 uint32_t last_index = 0; | 322 uint32_t last_index = 0; |
323 // Size of sfnt header plus size of table records. | 323 // Size of sfnt header plus size of table records. |
324 uint64_t total_sfnt_size = 12 + 16 * header->num_tables; | 324 uint64_t total_sfnt_size = 12 + 16 * header->num_tables; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 // Blocks must follow immediately after the previous block. | 359 // Blocks must follow immediately after the previous block. |
360 // (Except for padding with a maximum of three null bytes) | 360 // (Except for padding with a maximum of three null bytes) |
361 uint64_t block_end = ots::Round4( | 361 uint64_t block_end = ots::Round4( |
362 static_cast<uint64_t>(tables[last_index].offset) + | 362 static_cast<uint64_t>(tables[last_index].offset) + |
363 static_cast<uint64_t>(tables[last_index].length)); | 363 static_cast<uint64_t>(tables[last_index].length)); |
364 if (block_end > std::numeric_limits<uint32_t>::max()) { | 364 if (block_end > std::numeric_limits<uint32_t>::max()) { |
365 return OTS_FAILURE_MSG_HDR("invalid table location/size"); | 365 return OTS_FAILURE_MSG_HDR("invalid table location/size"); |
366 } | 366 } |
367 if (meta_offset) { | 367 if (meta_offset) { |
368 if (block_end != meta_offset) { | 368 if (block_end != meta_offset) { |
369 return OTS_FAILURE_MSG_HDR("invalid metadata block location"); | 369 return OTS_FAILURE_MSG_HDR("Invalid metadata block offset"); |
370 } | 370 } |
371 block_end = ots::Round4(static_cast<uint64_t>(meta_offset) + | 371 block_end = ots::Round4(static_cast<uint64_t>(meta_offset) + |
372 static_cast<uint64_t>(meta_length)); | 372 static_cast<uint64_t>(meta_length)); |
373 if (block_end > std::numeric_limits<uint32_t>::max()) { | 373 if (block_end > std::numeric_limits<uint32_t>::max()) { |
374 return OTS_FAILURE_MSG_HDR("invalid metadata block size"); | 374 return OTS_FAILURE_MSG_HDR("Invalid metadata block length"); |
375 } | 375 } |
376 } | 376 } |
377 if (priv_offset) { | 377 if (priv_offset) { |
378 if (block_end != priv_offset) { | 378 if (block_end != priv_offset) { |
379 return OTS_FAILURE_MSG_HDR("invalid private block location"); | 379 return OTS_FAILURE_MSG_HDR("Invalid private block offset"); |
380 } | 380 } |
381 block_end = ots::Round4(static_cast<uint64_t>(priv_offset) + | 381 block_end = ots::Round4(static_cast<uint64_t>(priv_offset) + |
382 static_cast<uint64_t>(priv_length)); | 382 static_cast<uint64_t>(priv_length)); |
383 if (block_end > std::numeric_limits<uint32_t>::max()) { | 383 if (block_end > std::numeric_limits<uint32_t>::max()) { |
384 return OTS_FAILURE_MSG_HDR("invalid private block size"); | 384 return OTS_FAILURE_MSG_HDR("Invalid private block length"); |
385 } | 385 } |
386 } | 386 } |
387 if (block_end != ots::Round4(length)) { | 387 if (block_end != ots::Round4(length)) { |
388 return OTS_FAILURE_MSG_HDR("file length mismatch (trailing junk?)"); | 388 return OTS_FAILURE_MSG_HDR("File length mismatch (trailing junk?)"); |
389 } | 389 } |
390 | 390 |
391 return ProcessGeneric(header, woff_tag, output, data, length, tables, file); | 391 return ProcessGeneric(header, woff_tag, output, data, length, tables, file); |
392 } | 392 } |
393 | 393 |
394 bool ProcessWOFF2(ots::OpenTypeFile *header, | 394 bool ProcessWOFF2(ots::OpenTypeFile *header, |
395 ots::OTSStream *output, const uint8_t *data, size_t length) { | 395 ots::OTSStream *output, const uint8_t *data, size_t length) { |
396 size_t decompressed_size = ots::ComputeWOFF2FinalSize(data, length); | 396 size_t decompressed_size = ots::ComputeWOFF2FinalSize(data, length); |
397 if (decompressed_size == 0) { | 397 if (decompressed_size == 0) { |
398 return OTS_FAILURE(); | 398 return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 is set to 0"); |
399 } | 399 } |
400 // decompressed font must be <= 30MB | 400 // decompressed font must be <= 30MB |
401 if (decompressed_size > 30 * 1024 * 1024) { | 401 if (decompressed_size > 30 * 1024 * 1024) { |
402 return OTS_FAILURE(); | 402 return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 font exceeds 30MB"
); |
403 } | 403 } |
404 | 404 |
405 std::vector<uint8_t> decompressed_buffer(decompressed_size); | 405 std::vector<uint8_t> decompressed_buffer(decompressed_size); |
406 if (!ots::ConvertWOFF2ToTTF(header, &decompressed_buffer[0], decompressed_size
, | 406 if (!ots::ConvertWOFF2ToSFNT(header, &decompressed_buffer[0], decompressed_siz
e, |
407 data, length)) { | 407 data, length)) { |
408 return OTS_FAILURE(); | 408 return OTS_FAILURE_MSG_HDR("Failed to convert WOFF 2.0 font to SFNT"); |
409 } | 409 } |
410 return ProcessTTF(header, output, &decompressed_buffer[0], decompressed_size); | 410 return ProcessTTF(header, output, &decompressed_buffer[0], decompressed_size); |
411 } | 411 } |
412 | 412 |
413 ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) { | 413 ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) { |
414 ots::TableAction action = ots::TABLE_ACTION_DEFAULT; | 414 ots::TableAction action = ots::TABLE_ACTION_DEFAULT; |
415 | 415 |
416 action = header->context->GetTableAction(htonl(tag)); | 416 action = header->context->GetTableAction(htonl(tag)); |
417 | 417 |
418 if (action == ots::TABLE_ACTION_DEFAULT) { | 418 if (action == ots::TABLE_ACTION_DEFAULT) { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 if (header->version != Tag("OTTO")) { | 592 if (header->version != Tag("OTTO")) { |
593 return OTS_FAILURE_MSG_HDR("wrong font version for PostScript glyph data")
; | 593 return OTS_FAILURE_MSG_HDR("wrong font version for PostScript glyph data")
; |
594 } | 594 } |
595 if (header->glyf || header->loca) { | 595 if (header->glyf || header->loca) { |
596 // mixing outline formats is not recommended | 596 // mixing outline formats is not recommended |
597 return OTS_FAILURE_MSG_HDR("font contains both PS and TT glyphs"); | 597 return OTS_FAILURE_MSG_HDR("font contains both PS and TT glyphs"); |
598 } | 598 } |
599 } else { | 599 } else { |
600 if (!header->glyf || !header->loca) { | 600 if (!header->glyf || !header->loca) { |
601 // No TrueType glyph found. | 601 // No TrueType glyph found. |
602 // Note: bitmap-only fonts are not supported. | 602 #define PASSTHRU_TABLE(TAG) (table_map.find(Tag(TAG)) != table_map.end() && \ |
603 return OTS_FAILURE_MSG_HDR("neither PS nor TT glyphs present"); | 603 GetTableAction(header, Tag(TAG)) == ots::TABLE_ACTI
ON_PASSTHRU) |
| 604 // We don't sanitise bitmap table, but don't reject bitmap-only fonts if |
| 605 // we keep the tables. |
| 606 if (!PASSTHRU_TABLE("CBDT") || !PASSTHRU_TABLE("CBLC")) { |
| 607 return OTS_FAILURE_MSG_HDR("no supported glyph shapes table(s) present")
; |
| 608 } |
| 609 #undef PASSTHRU_TABLE |
604 } | 610 } |
605 } | 611 } |
606 | 612 |
607 uint16_t num_output_tables = 0; | 613 uint16_t num_output_tables = 0; |
608 for (unsigned i = 0; ; ++i) { | 614 for (unsigned i = 0; ; ++i) { |
609 if (table_parsers[i].parse == NULL) { | 615 if (table_parsers[i].parse == NULL) { |
610 break; | 616 break; |
611 } | 617 } |
612 | 618 |
613 if (table_parsers[i].should_serialise(header)) { | 619 if (table_parsers[i].should_serialise(header)) { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 return OTS_FAILURE_MSG_HDR("error writing output"); | 775 return OTS_FAILURE_MSG_HDR("error writing output"); |
770 } | 776 } |
771 | 777 |
772 return true; | 778 return true; |
773 } | 779 } |
774 | 780 |
775 } // namespace | 781 } // namespace |
776 | 782 |
777 namespace ots { | 783 namespace ots { |
778 | 784 |
779 void EnableWOFF2() { | |
780 } | |
781 | |
782 bool IsValidVersionTag(uint32_t tag) { | 785 bool IsValidVersionTag(uint32_t tag) { |
783 return tag == Tag("\x00\x01\x00\x00") || | 786 return tag == Tag("\x00\x01\x00\x00") || |
784 // OpenType fonts with CFF data have 'OTTO' tag. | 787 // OpenType fonts with CFF data have 'OTTO' tag. |
785 tag == Tag("OTTO") || | 788 tag == Tag("OTTO") || |
786 // Older Mac fonts might have 'true' or 'typ1' tag. | 789 // Older Mac fonts might have 'true' or 'typ1' tag. |
787 tag == Tag("true") || | 790 tag == Tag("true") || |
788 tag == Tag("typ1"); | 791 tag == Tag("typ1"); |
789 } | 792 } |
790 | 793 |
791 bool OTSContext::Process(OTSStream *output, | 794 bool OTSContext::Process(OTSStream *output, |
(...skipping 23 matching lines...) Expand all Loading... |
815 return result; | 818 return result; |
816 } | 819 } |
817 | 820 |
818 // For backward compatibility | 821 // For backward compatibility |
819 bool Process(OTSStream *output, const uint8_t *data, size_t length) { | 822 bool Process(OTSStream *output, const uint8_t *data, size_t length) { |
820 static OTSContext context; | 823 static OTSContext context; |
821 return context.Process(output, data, length); | 824 return context.Process(output, data, length); |
822 } | 825 } |
823 | 826 |
824 } // namespace ots | 827 } // namespace ots |
OLD | NEW |