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

Side by Side Diff: third_party/ots/src/woff2.cc

Issue 1062093002: Update OTS to revision 6d2e08b (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months 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/ots/src/ots.cc ('k') | third_party/ots/test/ot-sanitise.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 // This is the implementation of decompression of the proposed WOFF Ultra 5 // This is the implementation of decompression of the proposed WOFF Ultra
6 // Condensed file format. 6 // Condensed file format.
7 7
8 #include <cassert> 8 #include <cassert>
9 #include <cstdlib> 9 #include <cstdlib>
10 #include <vector> 10 #include <vector>
(...skipping 27 matching lines...) Expand all
38 38
39 const size_t kSfntHeaderSize = 12; 39 const size_t kSfntHeaderSize = 12;
40 const size_t kSfntEntrySize = 16; 40 const size_t kSfntEntrySize = 16;
41 const size_t kCheckSumAdjustmentOffset = 8; 41 const size_t kCheckSumAdjustmentOffset = 8;
42 42
43 const size_t kEndPtsOfContoursOffset = 10; 43 const size_t kEndPtsOfContoursOffset = 10;
44 const size_t kCompositeGlyphBegin = 10; 44 const size_t kCompositeGlyphBegin = 10;
45 45
46 // Note that the byte order is big-endian, not the same as ots.cc 46 // Note that the byte order is big-endian, not the same as ots.cc
47 #define TAG(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d) 47 #define TAG(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d)
48 #define CHR(t) (t >> 24), (t >> 16), (t >> 8), (t >> 0) 48 #define UNTAG(t) (t >> 24), (t >> 16), (t >> 8), (t >> 0)
49 49
50 const unsigned int kWoff2FlagsTransform = 1 << 5; 50 const unsigned int kWoff2FlagsTransform = 1 << 5;
51 51
52 const uint32_t kKnownTags[] = { 52 const uint32_t kKnownTags[] = {
53 TAG('c', 'm', 'a', 'p'), // 0 53 TAG('c', 'm', 'a', 'p'), // 0
54 TAG('h', 'e', 'a', 'd'), // 1 54 TAG('h', 'e', 'a', 'd'), // 1
55 TAG('h', 'h', 'e', 'a'), // 2 55 TAG('h', 'h', 'e', 'a'), // 2
56 TAG('h', 'm', 't', 'x'), // 3 56 TAG('h', 'm', 't', 'x'), // 3
57 TAG('m', 'a', 'x', 'p'), // 4 57 TAG('m', 'a', 'x', 'p'), // 4
58 TAG('n', 'a', 'm', 'e'), // 5 58 TAG('n', 'a', 'm', 'e'), // 5
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 StoreU32(dst, kSfntHeaderSize + i * kSfntEntrySize + 4, checksum); 765 StoreU32(dst, kSfntHeaderSize + i * kSfntEntrySize + 4, checksum);
766 file_checksum += checksum; // The addition is mod 2^32 766 file_checksum += checksum; // The addition is mod 2^32
767 } 767 }
768 file_checksum += ComputeChecksum(dst, 768 file_checksum += ComputeChecksum(dst,
769 kSfntHeaderSize + kSfntEntrySize * n_tables); 769 kSfntHeaderSize + kSfntEntrySize * n_tables);
770 uint32_t checksum_adjustment = 0xb1b0afba - file_checksum; 770 uint32_t checksum_adjustment = 0xb1b0afba - file_checksum;
771 StoreU32(dst, adjustment_offset, checksum_adjustment); 771 StoreU32(dst, adjustment_offset, checksum_adjustment);
772 return true; 772 return true;
773 } 773 }
774 774
775 bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
776 const uint8_t* src_buf, size_t src_size) {
777 size_t uncompressed_size = dst_size;
778 int ok = BrotliDecompressBuffer(src_size, src_buf,
779 &uncompressed_size, dst_buf);
780 if (!ok || uncompressed_size != dst_size) {
781 return OTS_FAILURE();
782 }
783 return true;
784 }
785
786 bool ReadTableDirectory(ots::OpenTypeFile* file, 775 bool ReadTableDirectory(ots::OpenTypeFile* file,
787 ots::Buffer* buffer, std::vector<Table>* tables, 776 ots::Buffer* buffer, std::vector<Table>* tables,
788 size_t num_tables) { 777 size_t num_tables) {
789 for (size_t i = 0; i < num_tables; ++i) { 778 for (size_t i = 0; i < num_tables; ++i) {
790 Table* table = &tables->at(i); 779 Table* table = &tables->at(i);
791 uint8_t flag_byte; 780 uint8_t flag_byte;
792 if (!buffer->ReadU8(&flag_byte)) { 781 if (!buffer->ReadU8(&flag_byte)) {
793 return OTS_FAILURE_MSG("Failed to read the flags of table directory entry %d", i); 782 return OTS_FAILURE_MSG("Failed to read the flags of table directory entry %d", i);
794 } 783 }
795 uint32_t tag; 784 uint32_t tag;
796 if ((flag_byte & 0x3f) == 0x3f) { 785 if ((flag_byte & 0x3f) == 0x3f) {
797 if (!buffer->ReadU32(&tag)) { 786 if (!buffer->ReadU32(&tag)) {
798 return OTS_FAILURE_MSG("Failed to read the tag of table directory entry %d", i); 787 return OTS_FAILURE_MSG("Failed to read the tag of table directory entry %d", i);
799 } 788 }
800 } else { 789 } else {
801 tag = kKnownTags[flag_byte & 0x3f]; 790 tag = kKnownTags[flag_byte & 0x3f];
802 } 791 }
803 // Bits 6 and 7 are reserved and must be 0. 792 // Bits 6 and 7 are reserved and must be 0.
804 if ((flag_byte & 0xc0) != 0) { 793 if ((flag_byte & 0xc0) != 0) {
805 return OTS_FAILURE_MSG("Bits 6 and 7 are not 0 for table directory entry % d", i); 794 return OTS_FAILURE_MSG("Bits 6 and 7 are not 0 for table directory entry % d", i);
806 } 795 }
807 uint32_t flags = 0; 796 uint32_t flags = 0;
808 // Always transform the glyf and loca tables 797 // Always transform the glyf and loca tables
809 if (tag == TAG('g', 'l', 'y', 'f') || 798 if (tag == TAG('g', 'l', 'y', 'f') ||
810 tag == TAG('l', 'o', 'c', 'a')) { 799 tag == TAG('l', 'o', 'c', 'a')) {
811 flags |= kWoff2FlagsTransform; 800 flags |= kWoff2FlagsTransform;
812 } 801 }
813 uint32_t dst_length; 802 uint32_t dst_length;
814 if (!ReadBase128(buffer, &dst_length)) { 803 if (!ReadBase128(buffer, &dst_length)) {
815 return OTS_FAILURE_MSG("Failed to read 'origLength' for table '%c%c%c%c'", CHR(tag)); 804 return OTS_FAILURE_MSG("Failed to read 'origLength' for table '%c%c%c%c'", UNTAG(tag));
816 } 805 }
817 uint32_t transform_length = dst_length; 806 uint32_t transform_length = dst_length;
818 if ((flags & kWoff2FlagsTransform) != 0) { 807 if ((flags & kWoff2FlagsTransform) != 0) {
819 if (!ReadBase128(buffer, &transform_length)) { 808 if (!ReadBase128(buffer, &transform_length)) {
820 return OTS_FAILURE_MSG("Failed to read 'transformLength' for table '%c%c %c%c'", CHR(tag)); 809 return OTS_FAILURE_MSG("Failed to read 'transformLength' for table '%c%c %c%c'", UNTAG(tag));
810 }
811
812 if (tag == TAG('l', 'o', 'c', 'a') && transform_length != 0) {
813 return OTS_FAILURE_MSG("The 'transformLength' of 'loca' table must be ze ro: %d", transform_length);
821 } 814 }
822 } 815 }
823 // Disallow huge numbers (> 1GB) for sanity. 816 // Disallow huge numbers (> 1GB) for sanity.
824 if (transform_length > 1024 * 1024 * 1024 || 817 if (transform_length > 1024 * 1024 * 1024 ||
825 dst_length > 1024 * 1024 * 1024) { 818 dst_length > 1024 * 1024 * 1024) {
826 return OTS_FAILURE_MSG("'origLength' or 'transformLength' > 1GB"); 819 return OTS_FAILURE_MSG("'origLength' or 'transformLength' > 1GB");
827 } 820 }
828 table->tag = tag; 821 table->tag = tag;
829 table->flags = flags; 822 table->flags = flags;
830 table->transform_length = transform_length; 823 table->transform_length = transform_length;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 for (uint16_t i = 0; i < num_tables; ++i) { 1006 for (uint16_t i = 0; i < num_tables; ++i) {
1014 total_size += tables.at(i).transform_length; 1007 total_size += tables.at(i).transform_length;
1015 if (total_size > std::numeric_limits<uint32_t>::max()) { 1008 if (total_size > std::numeric_limits<uint32_t>::max()) {
1016 return OTS_FAILURE(); 1009 return OTS_FAILURE();
1017 } 1010 }
1018 } 1011 }
1019 // Enforce same 30M limit on uncompressed tables as OTS 1012 // Enforce same 30M limit on uncompressed tables as OTS
1020 if (total_size > 30 * 1024 * 1024) { 1013 if (total_size > 30 * 1024 * 1024) {
1021 return OTS_FAILURE(); 1014 return OTS_FAILURE();
1022 } 1015 }
1023 const size_t total_size_size_t = static_cast<size_t>(total_size); 1016 size_t uncompressed_size = static_cast<size_t>(total_size);
1024 uncompressed_buf.resize(total_size_size_t); 1017 uncompressed_buf.resize(uncompressed_size);
1025 const uint8_t* src_buf = data + compressed_offset; 1018 const uint8_t* compressed_buf = data + compressed_offset;
1026 if (!Woff2Uncompress(&uncompressed_buf[0], total_size_size_t, 1019 if (!BrotliDecompressBuffer(compressed_length, compressed_buf,
1027 src_buf, compressed_length)) { 1020 &uncompressed_size, &uncompressed_buf[0])) {
1028 return OTS_FAILURE_MSG("Failed to uncompress font data"); 1021 return OTS_FAILURE_MSG("Failed to uncompress font data");
1029 } 1022 }
1023 if (uncompressed_size != static_cast<size_t>(total_size)) {
1024 return OTS_FAILURE_MSG("Decompressed font data size does not match the sum o f 'origLength' and 'transformLength'");
1025 }
1030 transform_buf = &uncompressed_buf[0]; 1026 transform_buf = &uncompressed_buf[0];
1031 1027
1032 for (uint16_t i = 0; i < num_tables; ++i) { 1028 for (uint16_t i = 0; i < num_tables; ++i) {
1033 const Table* table = &tables.at(i); 1029 const Table* table = &tables.at(i);
1034 uint32_t flags = table->flags; 1030 uint32_t flags = table->flags;
1035 size_t transform_length = table->transform_length; 1031 size_t transform_length = table->transform_length;
1036 1032
1037 if ((flags & kWoff2FlagsTransform) == 0) { 1033 if ((flags & kWoff2FlagsTransform) == 0) {
1038 if (transform_length != table->dst_length) { 1034 if (transform_length != table->dst_length) {
1039 return OTS_FAILURE(); 1035 return OTS_FAILURE();
1040 } 1036 }
1041 if (static_cast<uint64_t>(table->dst_offset) + transform_length > 1037 if (static_cast<uint64_t>(table->dst_offset) + transform_length >
1042 result_length) { 1038 result_length) {
1043 return OTS_FAILURE(); 1039 return OTS_FAILURE();
1044 } 1040 }
1045 std::memcpy(result + table->dst_offset, transform_buf, 1041 std::memcpy(result + table->dst_offset, transform_buf,
1046 transform_length); 1042 transform_length);
1047 } else { 1043 } else {
1048 if (!ReconstructTransformed(file, tables, table->tag, 1044 if (!ReconstructTransformed(file, tables, table->tag,
1049 transform_buf, transform_length, result, result_length)) { 1045 transform_buf, transform_length, result, result_length)) {
1050 return OTS_FAILURE_MSG("Failed to reconstruct '%c%c%c%c' table", CHR(tab le->tag)); 1046 return OTS_FAILURE_MSG("Failed to reconstruct '%c%c%c%c' table", UNTAG(t able->tag));
1051 } 1047 }
1052 } 1048 }
1053 1049
1054 transform_buf += transform_length; 1050 transform_buf += transform_length;
1055 if (transform_buf > &uncompressed_buf[0] + uncompressed_buf.size()) { 1051 if (transform_buf > &uncompressed_buf[0] + uncompressed_buf.size()) {
1056 return OTS_FAILURE(); 1052 return OTS_FAILURE();
1057 } 1053 }
1058 } 1054 }
1059 1055
1060 return FixChecksums(sorted_tables, result); 1056 return FixChecksums(sorted_tables, result);
1061 } 1057 }
1062 1058
1063 } // namespace ots 1059 } // namespace ots
1064 1060
1065 #undef TABLE_NAME 1061 #undef TABLE_NAME
OLDNEW
« no previous file with comments | « third_party/ots/src/ots.cc ('k') | third_party/ots/test/ot-sanitise.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698