diff options
Diffstat (limited to 'modules/woff2/src')
30 files changed, 510 insertions, 679 deletions
diff --git a/modules/woff2/src/buffer.h b/modules/woff2/src/buffer.h index 588ac0d33..7240e5181 100644 --- a/modules/woff2/src/buffer.h +++ b/modules/woff2/src/buffer.h @@ -1,19 +1,11 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// The parts of ots.h & opentype-sanitiser.h that we need, taken from the -// https://code.google.com/p/ots/ project. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* The parts of ots.h & opentype-sanitiser.h that we need, taken from the + https://code.google.com/p/ots/ project. */ #ifndef WOFF2_BUFFER_H_ #define WOFF2_BUFFER_H_ @@ -65,8 +57,8 @@ inline bool Failure(const char *f, int l, const char *fn) { // ----------------------------------------------------------------------------- class Buffer { public: - Buffer(const uint8_t *buffer, size_t len) - : buffer_(buffer), + Buffer(const uint8_t *data, size_t len) + : buffer_(data), length_(len), offset_(0) { } @@ -74,7 +66,7 @@ class Buffer { return Read(NULL, n_bytes); } - bool Read(uint8_t *buffer, size_t n_bytes) { + bool Read(uint8_t *data, size_t n_bytes) { if (n_bytes > 1024 * 1024 * 1024) { return FONT_COMPRESSION_FAILURE(); } @@ -82,8 +74,8 @@ class Buffer { (offset_ > length_ - n_bytes)) { return FONT_COMPRESSION_FAILURE(); } - if (buffer) { - std::memcpy(buffer, buffer_ + offset_, n_bytes); + if (data) { + std::memcpy(data, buffer_ + offset_, n_bytes); } offset_ += n_bytes; return true; diff --git a/modules/woff2/src/convert_woff2ttf_fuzzer.cc b/modules/woff2/src/convert_woff2ttf_fuzzer.cc new file mode 100644 index 000000000..2d977a3ef --- /dev/null +++ b/modules/woff2/src/convert_woff2ttf_fuzzer.cc @@ -0,0 +1,13 @@ +#include <stddef.h> +#include <stdint.h> + +#include <woff2/decode.h> + +// Entry point for LibFuzzer. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + std::string buf; + woff2::WOFF2StringOut out(&buf); + out.SetMaxSize(30 * 1024 * 1024); + woff2::ConvertWOFF2ToTTF(data, size, &out); + return 0; +} diff --git a/modules/woff2/src/convert_woff2ttf_fuzzer_new_entry.cc b/modules/woff2/src/convert_woff2ttf_fuzzer_new_entry.cc new file mode 100644 index 000000000..5ad93364b --- /dev/null +++ b/modules/woff2/src/convert_woff2ttf_fuzzer_new_entry.cc @@ -0,0 +1,12 @@ +#include <string> +#include <woff2/decode.h> + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t data_size) { + // Decode using newer entry pattern. + // Same pattern as woff2_decompress. + std::string output(std::min(woff2::ComputeWOFF2FinalSize(data, data_size), + woff2::kDefaultMaxSize), 0); + woff2::WOFF2StringOut out(&output); + woff2::ConvertWOFF2ToTTF(data, data_size, &out); + return 0; +} diff --git a/modules/woff2/src/file.h b/modules/woff2/src/file.h index 7afcb315f..61318776b 100644 --- a/modules/woff2/src/file.h +++ b/modules/woff2/src/file.h @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// File IO helpers. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* File IO helpers. */ #ifndef WOFF2_FILE_H_ #define WOFF2_FILE_H_ diff --git a/modules/woff2/src/font.cc b/modules/woff2/src/font.cc index 060673005..a45153e9c 100644 --- a/modules/woff2/src/font.cc +++ b/modules/woff2/src/font.cc @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Font management utilities +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Font management utilities */ #include "./font.h" @@ -105,6 +97,12 @@ bool ReadTrueTypeFont(Buffer* file, const uint8_t* data, size_t len, last_offset = i.first + i.second; } + // Sanity check key tables + const Font::Table* head_table = font->FindTable(kHeadTableTag); + if (head_table != NULL && head_table->length < 52) { + return FONT_COMPRESSION_FAILURE(); + } + return true; } @@ -125,6 +123,9 @@ bool ReadCollectionFont(Buffer* file, const uint8_t* data, size_t len, (*all_tables)[table.offset] = font->FindTable(table.tag); } else { table.reuse_of = (*all_tables)[table.offset]; + if (table.tag != table.reuse_of->tag) { + return FONT_COMPRESSION_FAILURE(); + } } } @@ -325,8 +326,11 @@ int NumGlyphs(const Font& font) { return 0; } int index_fmt = IndexFormat(font); - int num_glyphs = (loca_table->length / (index_fmt == 0 ? 2 : 4)) - 1; - return num_glyphs; + int loca_record_size = (index_fmt == 0 ? 2 : 4); + if (loca_table->length < loca_record_size) { + return 0; + } + return (loca_table->length / loca_record_size) - 1; } int IndexFormat(const Font& font) { diff --git a/modules/woff2/src/font.h b/modules/woff2/src/font.h index 93806e6b5..7b8ddddc5 100644 --- a/modules/woff2/src/font.h +++ b/modules/woff2/src/font.h @@ -1,19 +1,11 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Data model for a font file in sfnt format, reading and writing functions and -// accessors for the glyph data. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Data model for a font file in sfnt format, reading and writing functions and + accessors for the glyph data. */ #ifndef WOFF2_FONT_H_ #define WOFF2_FONT_H_ diff --git a/modules/woff2/src/glyph.cc b/modules/woff2/src/glyph.cc index 1dadafcb7..057174de2 100644 --- a/modules/woff2/src/glyph.cc +++ b/modules/woff2/src/glyph.cc @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Glyph manipulation +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Glyph manipulation */ #include "./glyph.h" @@ -118,25 +110,27 @@ bool ReadGlyph(const uint8_t* data, size_t len, Glyph* glyph) { // Read the run-length coded flags. std::vector<std::vector<uint8_t> > flags(num_contours); - uint8_t flag = 0; - uint8_t flag_repeat = 0; - for (int i = 0; i < num_contours; ++i) { - flags[i].resize(glyph->contours[i].size()); - for (size_t j = 0; j < glyph->contours[i].size(); ++j) { - if (flag_repeat == 0) { - if (!buffer.ReadU8(&flag)) { - return FONT_COMPRESSION_FAILURE(); - } - if (flag & kFLAG_REPEAT) { - if (!buffer.ReadU8(&flag_repeat)) { + { + uint8_t flag = 0; + uint8_t flag_repeat = 0; + for (int i = 0; i < num_contours; ++i) { + flags[i].resize(glyph->contours[i].size()); + for (size_t j = 0; j < glyph->contours[i].size(); ++j) { + if (flag_repeat == 0) { + if (!buffer.ReadU8(&flag)) { return FONT_COMPRESSION_FAILURE(); } + if (flag & kFLAG_REPEAT) { + if (!buffer.ReadU8(&flag_repeat)) { + return FONT_COMPRESSION_FAILURE(); + } + } + } else { + flag_repeat--; } - } else { - flag_repeat--; + flags[i][j] = flag; + glyph->contours[i][j].on_curve = flag & kFLAG_ONCURVE; } - flags[i][j] = flag; - glyph->contours[i][j].on_curve = flag & kFLAG_ONCURVE; } } diff --git a/modules/woff2/src/glyph.h b/modules/woff2/src/glyph.h index 0ee755c2f..f24056f4c 100644 --- a/modules/woff2/src/glyph.h +++ b/modules/woff2/src/glyph.h @@ -1,19 +1,11 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Data model and I/O for glyph data within sfnt format files for the purpose of -// performing the preprocessing step of the WOFF 2.0 conversion. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Data model and I/O for glyph data within sfnt format files for the purpose of + performing the preprocessing step of the WOFF 2.0 conversion. */ #ifndef WOFF2_GLYPH_H_ #define WOFF2_GLYPH_H_ diff --git a/modules/woff2/src/normalize.cc b/modules/woff2/src/normalize.cc index b538b91a8..6685e0875 100644 --- a/modules/woff2/src/normalize.cc +++ b/modules/woff2/src/normalize.cc @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Glyph normalization +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Glyph normalization */ #include "./normalize.h" @@ -52,7 +44,7 @@ bool WriteNormalizedLoca(int index_fmt, int num_glyphs, Font* font) { loca_table->buffer.resize(Round4(num_glyphs + 1) * glyph_sz); loca_table->length = (num_glyphs + 1) * glyph_sz; - uint8_t* glyf_dst = &glyf_table->buffer[0]; + uint8_t* glyf_dst = num_glyphs ? &glyf_table->buffer[0] : NULL; uint8_t* loca_dst = &loca_table->buffer[0]; uint32_t glyf_offset = 0; size_t loca_offset = 0; @@ -78,16 +70,13 @@ bool WriteNormalizedLoca(int index_fmt, int num_glyphs, Font* font) { } glyf_offset += glyf_dst_size; } - if (glyf_offset == 0) { - return false; - } StoreLoca(index_fmt, glyf_offset, &loca_offset, loca_dst); glyf_table->buffer.resize(glyf_offset); - glyf_table->data = &glyf_table->buffer[0]; + glyf_table->data = glyf_offset ? &glyf_table->buffer[0] : NULL; glyf_table->length = glyf_offset; - loca_table->data = &loca_table->buffer[0]; + loca_table->data = loca_offset ? &loca_table->buffer[0] : NULL; return true; } @@ -107,7 +96,10 @@ bool MakeEditableBuffer(Font* font, int tableTag) { int sz = Round4(table->length); table->buffer.resize(sz); uint8_t* buf = &table->buffer[0]; - memcpy(buf, table->data, sz); + memcpy(buf, table->data, table->length); + if (PREDICT_FALSE(sz > table->length)) { + memset(buf + table->length, 0, sz - table->length); + } table->data = buf; return true; } diff --git a/modules/woff2/src/normalize.h b/modules/woff2/src/normalize.h index e0153488e..c6fee74db 100644 --- a/modules/woff2/src/normalize.h +++ b/modules/woff2/src/normalize.h @@ -1,20 +1,12 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Functions for normalizing fonts. Since the WOFF 2.0 decoder creates font -// files in normalized form, the WOFF 2.0 conversion is guaranteed to be -// lossless (in a bitwise sense) only for normalized font files. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions for normalizing fonts. Since the WOFF 2.0 decoder creates font + files in normalized form, the WOFF 2.0 conversion is guaranteed to be + lossless (in a bitwise sense) only for normalized font files. */ #ifndef WOFF2_NORMALIZE_H_ #define WOFF2_NORMALIZE_H_ diff --git a/modules/woff2/src/port.h b/modules/woff2/src/port.h index bac47a93a..8b60fee8b 100644 --- a/modules/woff2/src/port.h +++ b/modules/woff2/src/port.h @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Helper function for bit twiddling and macros for branch prediction. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Helper function for bit twiddling and macros for branch prediction. */ #ifndef WOFF2_PORT_H_ #define WOFF2_PORT_H_ @@ -60,4 +52,15 @@ inline int Log2Floor(uint32 n) { #define PREDICT_TRUE(x) (x) #endif +#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \ + (defined(M_ARM) && (M_ARM == 7)) || \ + defined(__aarch64__) || defined(__ARM64_ARCH_8__) || defined(__i386) || \ + defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define WOFF_LITTLE_ENDIAN +#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define WOFF_BIG_ENDIAN +#endif /* endianness */ +#endif /* CPU whitelist */ + #endif // WOFF2_PORT_H_ diff --git a/modules/woff2/src/round.h b/modules/woff2/src/round.h index abb81f823..e5b2cb122 100644 --- a/modules/woff2/src/round.h +++ b/modules/woff2/src/round.h @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Helper for rounding +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Helper for rounding */ #ifndef WOFF2_ROUND_H_ #define WOFF2_ROUND_H_ diff --git a/modules/woff2/src/store_bytes.h b/modules/woff2/src/store_bytes.h index e026cd33a..fff3c62f8 100644 --- a/modules/woff2/src/store_bytes.h +++ b/modules/woff2/src/store_bytes.h @@ -1,19 +1,11 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Helper functions for storing integer values into byte streams. -// No bounds checking is performed, that is the responsibility of the caller. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Helper functions for storing integer values into byte streams. + No bounds checking is performed, that is the responsibility of the caller. */ #ifndef WOFF2_STORE_BYTES_H_ #define WOFF2_STORE_BYTES_H_ @@ -22,6 +14,8 @@ #include <stddef.h> #include <string.h> +#include "./port.h" + namespace woff2 { inline size_t StoreU32(uint8_t* dst, size_t offset, uint32_t x) { @@ -33,12 +27,11 @@ inline size_t StoreU32(uint8_t* dst, size_t offset, uint32_t x) { } inline size_t Store16(uint8_t* dst, size_t offset, int x) { -#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) - uint16_t v = ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8); - memcpy(dst + offset, &v, 2); -#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - uint16_t v = static_cast<uint16_t>(x); - memcpy(dst + offset, &v, 2); +#if defined(WOFF_LITTLE_ENDIAN) + *reinterpret_cast<uint16_t*>(dst + offset) = + ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8); +#elif defined(WOFF_BIG_ENDIAN) + *reinterpret_cast<uint16_t*>(dst + offset) = static_cast<uint16_t>(x); #else dst[offset] = x >> 8; dst[offset + 1] = x; @@ -54,14 +47,12 @@ inline void StoreU32(uint32_t val, size_t* offset, uint8_t* dst) { } inline void Store16(int val, size_t* offset, uint8_t* dst) { -#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) - uint16_t v = ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8); - memcpy(dst + *offset, &v, 2); +#if defined(WOFF_LITTLE_ENDIAN) + *reinterpret_cast<uint16_t*>(dst + *offset) = ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8); *offset += 2; -#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - uint16_t v = static_cast<uint16_t>(val); - memcpy(dst + *offset, &v, 2); +#elif defined(WOFF_BIG_ENDIAN) + *reinterpret_cast<uint16_t*>(dst + *offset) = static_cast<uint16_t>(val); *offset += 2; #else dst[(*offset)++] = val >> 8; diff --git a/modules/woff2/src/table_tags.cc b/modules/woff2/src/table_tags.cc index 0071e00b0..dca3ec8d2 100644 --- a/modules/woff2/src/table_tags.cc +++ b/modules/woff2/src/table_tags.cc @@ -1,18 +1,10 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Font table tags +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Font table tags */ #include "./table_tags.h" diff --git a/modules/woff2/src/table_tags.h b/modules/woff2/src/table_tags.h index daa5d9215..42dc0ae1c 100644 --- a/modules/woff2/src/table_tags.h +++ b/modules/woff2/src/table_tags.h @@ -1,18 +1,10 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Font table tags +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Font table tags */ #ifndef WOFF2_TABLE_TAGS_H_ #define WOFF2_TABLE_TAGS_H_ diff --git a/modules/woff2/src/transform.cc b/modules/woff2/src/transform.cc index 2ad8b163c..999bef374 100644 --- a/modules/woff2/src/transform.cc +++ b/modules/woff2/src/transform.cc @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Library for preprocessing fonts as part of the WOFF 2.0 conversion. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Library for preprocessing fonts as part of the WOFF 2.0 conversion. */ #include "./transform.h" diff --git a/modules/woff2/src/transform.h b/modules/woff2/src/transform.h index e9d1b0d3d..a4583d16c 100644 --- a/modules/woff2/src/transform.h +++ b/modules/woff2/src/transform.h @@ -1,18 +1,10 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Library for preprocessing fonts as part of the WOFF 2.0 conversion. +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Library for preprocessing fonts as part of the WOFF 2.0 conversion. */ #ifndef WOFF2_TRANSFORM_H_ #define WOFF2_TRANSFORM_H_ diff --git a/modules/woff2/src/variable_length.cc b/modules/woff2/src/variable_length.cc index 944a17f2e..4f348d5e5 100644 --- a/modules/woff2/src/variable_length.cc +++ b/modules/woff2/src/variable_length.cc @@ -1,18 +1,10 @@ -// Copyright 2015 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Helper functions for woff2 variable length types: 255UInt16 and UIntBase128 +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Helper functions for woff2 variable length types: 255UInt16 and UIntBase128 */ #include "./variable_length.h" @@ -49,8 +41,8 @@ void Write255UShort(std::vector<uint8_t>* out, int value) { void Store255UShort(int val, size_t* offset, uint8_t* dst) { std::vector<uint8_t> packed; Write255UShort(&packed, val); - for (uint8_t val : packed) { - dst[(*offset)++] = val; + for (uint8_t packed_byte : packed) { + dst[(*offset)++] = packed_byte; } } diff --git a/modules/woff2/src/variable_length.h b/modules/woff2/src/variable_length.h index 2816ae23a..208010653 100644 --- a/modules/woff2/src/variable_length.h +++ b/modules/woff2/src/variable_length.h @@ -1,18 +1,10 @@ -// Copyright 2015 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Helper functions for woff2 variable length types: 255UInt16 and UIntBase128 +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Helper functions for woff2 variable length types: 255UInt16 and UIntBase128 */ #ifndef WOFF2_VARIABLE_LENGTH_H_ #define WOFF2_VARIABLE_LENGTH_H_ diff --git a/modules/woff2/src/woff2_common.cc b/modules/woff2/src/woff2_common.cc index 9dc7cbd5c..fe0a3beda 100644 --- a/modules/woff2/src/woff2_common.cc +++ b/modules/woff2/src/woff2_common.cc @@ -1,23 +1,17 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Helpers common across multiple parts of woff2 +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Helpers common across multiple parts of woff2 */ #include <algorithm> #include "./woff2_common.h" +#include "./port.h" + namespace woff2 { @@ -25,13 +19,12 @@ uint32_t ComputeULongSum(const uint8_t* buf, size_t size) { uint32_t checksum = 0; size_t aligned_size = size & ~3; for (size_t i = 0; i < aligned_size; i += 4) { - uint32_t v; - memcpy(&v, buf + i, 4); -#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) +#if defined(WOFF_LITTLE_ENDIAN) + uint32_t v = *reinterpret_cast<const uint32_t*>(buf + i); checksum += (((v & 0xFF) << 24) | ((v & 0xFF00) << 8) | ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24)); -#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - checksum += v; +#elif defined(WOFF_BIG_ENDIAN) + checksum += *reinterpret_cast<const uint32_t*>(buf + i); #else checksum += (buf[i] << 24) | (buf[i + 1] << 16) | (buf[i + 2] << 8) | buf[i + 3]; diff --git a/modules/woff2/src/woff2_common.h b/modules/woff2/src/woff2_common.h index a8c45af80..51fd4a7bf 100644 --- a/modules/woff2/src/woff2_common.h +++ b/modules/woff2/src/woff2_common.h @@ -1,18 +1,10 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Common definition for WOFF2 encoding/decoding +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Common definition for WOFF2 encoding/decoding */ #ifndef WOFF2_WOFF2_COMMON_H_ #define WOFF2_WOFF2_COMMON_H_ diff --git a/modules/woff2/src/woff2_compress.cc b/modules/woff2/src/woff2_compress.cc index e5cf710f7..80e310866 100644 --- a/modules/woff2/src/woff2_compress.cc +++ b/modules/woff2/src/woff2_compress.cc @@ -1,23 +1,15 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// A commandline tool for compressing ttf format files to woff2. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* A commandline tool for compressing ttf format files to woff2. */ #include <string> #include "file.h" -#include "./woff2_enc.h" +#include <woff2/encode.h> int main(int argc, char **argv) { diff --git a/modules/woff2/src/woff2_dec.cc b/modules/woff2/src/woff2_dec.cc index 97b869fe6..8186c8e5d 100644 --- a/modules/woff2/src/woff2_dec.cc +++ b/modules/woff2/src/woff2_dec.cc @@ -1,20 +1,12 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Library for converting WOFF2 format font files to their TTF versions. - -#include "./woff2_dec.h" +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Library for converting WOFF2 format font files to their TTF versions. */ + +#include <woff2/decode.h> #include <stdlib.h> #include <algorithm> @@ -27,16 +19,7 @@ #include <memory> #include <utility> -#include "mozilla/UniquePtr.h" -namespace std -{ - using mozilla::DefaultDelete; - using mozilla::UniquePtr; - #define default_delete DefaultDelete - #define unique_ptr UniquePtr -} - -#include "./decode.h" +#include <brotli/decode.h> #include "./buffer.h" #include "./port.h" #include "./round.h" @@ -420,6 +403,14 @@ bool ReconstructGlyf(const uint8_t* data, Table* glyf_table, return FONT_COMPRESSION_FAILURE(); } + // https://dev.w3.org/webfonts/WOFF2/spec/#conform-mustRejectLoca + // dst_length here is origLength in the spec + uint32_t expected_loca_dst_length = (info->index_format ? 4 : 2) + * (static_cast<uint32_t>(info->num_glyphs) + 1); + if (PREDICT_FALSE(loca_table->dst_length != expected_loca_dst_length)) { + return FONT_COMPRESSION_FAILURE(); + } + unsigned int offset = (2 + kNumSubStreams) * 4; if (PREDICT_FALSE(offset > glyf_table->transform_length)) { return FONT_COMPRESSION_FAILURE(); @@ -601,6 +592,14 @@ bool ReconstructGlyf(const uint8_t* data, Table* glyf_table, instruction_size, glyph_buf.get(), glyph_buf_size, &glyph_size))) { return FONT_COMPRESSION_FAILURE(); } + } else { + // n_contours == 0; empty glyph. Must NOT have a bbox. + if (PREDICT_FALSE(have_bbox)) { +#ifdef FONT_COMPRESSION_BIN + fprintf(stderr, "Empty glyph has a bbox\n"); +#endif + return FONT_COMPRESSION_FAILURE(); + } } loca_values[i] = out->Size() - glyf_start; @@ -678,6 +677,14 @@ bool ReconstructTransformedHmtx(const uint8_t* transformed_buf, bool has_proportional_lsbs = (hmtx_flags & 1) == 0; bool has_monospace_lsbs = (hmtx_flags & 2) == 0; + // Bits 2-7 are reserved and MUST be zero. + if ((hmtx_flags & 0xFC) != 0) { +#ifdef FONT_COMPRESSION_BIN + fprintf(stderr, "Illegal hmtx flags; bits 2-7 must be 0\n"); +#endif + return FONT_COMPRESSION_FAILURE(); + } + // you say you transformed but there is little evidence of it if (has_proportional_lsbs && has_monospace_lsbs) { return FONT_COMPRESSION_FAILURE(); @@ -751,9 +758,10 @@ bool ReconstructTransformedHmtx(const uint8_t* transformed_buf, bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size, const uint8_t* src_buf, size_t src_size) { size_t uncompressed_size = dst_size; - int ok = BrotliDecompressBuffer(src_size, src_buf, - &uncompressed_size, dst_buf); - if (PREDICT_FALSE(!ok || uncompressed_size != dst_size)) { + BrotliDecoderResult result = BrotliDecoderDecompress( + src_size, src_buf, &uncompressed_size, dst_buf); + if (PREDICT_FALSE(result != BROTLI_DECODER_RESULT_SUCCESS || + uncompressed_size != dst_size)) { return FONT_COMPRESSION_FAILURE(); } return true; @@ -884,11 +892,26 @@ bool ReconstructFont(uint8_t* transformed_buf, std::vector<Table*> tables = Tables(hdr, font_index); // 'glyf' without 'loca' doesn't make sense - if (PREDICT_FALSE(static_cast<bool>(FindTable(&tables, kGlyfTableTag)) != - static_cast<bool>(FindTable(&tables, kLocaTableTag)))) { + const Table* glyf_table = FindTable(&tables, kGlyfTableTag); + const Table* loca_table = FindTable(&tables, kLocaTableTag); + if (PREDICT_FALSE(static_cast<bool>(glyf_table) != + static_cast<bool>(loca_table))) { +#ifdef FONT_COMPRESSION_BIN + fprintf(stderr, "Cannot have just one of glyf/loca\n"); +#endif return FONT_COMPRESSION_FAILURE(); } + if (glyf_table != NULL) { + if (PREDICT_FALSE((glyf_table->flags & kWoff2FlagsTransform) + != (loca_table->flags & kWoff2FlagsTransform))) { +#ifdef FONT_COMPRESSION_BIN + fprintf(stderr, "Cannot transform just one of glyf/loca\n"); +#endif + return FONT_COMPRESSION_FAILURE(); + } + } + uint32_t font_checksum = metadata->header_checksum; if (hdr->header_version) { font_checksum = hdr->ttc_fonts[font_index].header_checksum; @@ -907,7 +930,7 @@ bool ReconstructFont(uint8_t* transformed_buf, // TODO(user) a collection with optimized hmtx that reused glyf/loca // would fail. We don't optimize hmtx for collections yet. - if (PREDICT_FALSE(static_cast<uint64_t>(table.src_offset + table.src_length) + if (PREDICT_FALSE(static_cast<uint64_t>(table.src_offset) + table.src_length > transformed_buf_size)) { return FONT_COMPRESSION_FAILURE(); } @@ -1108,8 +1131,9 @@ bool ReadWOFF2Header(const uint8_t* data, size_t length, WOFF2Header* hdr) { ttc_font.table_indices.resize(num_tables); - const Table* glyf_table = NULL; - const Table* loca_table = NULL; + + unsigned int glyf_idx = 0; + unsigned int loca_idx = 0; for (uint32_t j = 0; j < num_tables; j++) { unsigned int table_idx; @@ -1121,19 +1145,23 @@ bool ReadWOFF2Header(const uint8_t* data, size_t length, WOFF2Header* hdr) { const Table& table = hdr->tables[table_idx]; if (table.tag == kLocaTableTag) { - loca_table = &table; + loca_idx = table_idx; } if (table.tag == kGlyfTableTag) { - glyf_table = &table; + glyf_idx = table_idx; } } - if (PREDICT_FALSE((glyf_table == NULL) != (loca_table == NULL))) { + // if we have both glyf and loca make sure they are consecutive + // if we have just one we'll reject the font elsewhere + if (glyf_idx > 0 || loca_idx > 0) { + if (PREDICT_FALSE(glyf_idx > loca_idx || loca_idx - glyf_idx != 1)) { #ifdef FONT_COMPRESSION_BIN - fprintf(stderr, "Cannot have just one of glyf/loca\n"); + fprintf(stderr, "TTC font %d has non-consecutive glyf/loca\n", i); #endif - return FONT_COMPRESSION_FAILURE(); + return FONT_COMPRESSION_FAILURE(); + } } } } @@ -1307,6 +1335,9 @@ bool ConvertWOFF2ToTTF(const uint8_t* data, size_t length, const uint8_t* src_buf = data + hdr.compressed_offset; std::vector<uint8_t> uncompressed_buf(hdr.uncompressed_size); + if (PREDICT_FALSE(hdr.uncompressed_size < 1)) { + return FONT_COMPRESSION_FAILURE(); + } if (PREDICT_FALSE(!Woff2Uncompress(&uncompressed_buf[0], hdr.uncompressed_size, src_buf, hdr.compressed_length))) { diff --git a/modules/woff2/src/woff2_dec.h b/modules/woff2/src/woff2_dec.h deleted file mode 100644 index b889812fb..000000000 --- a/modules/woff2/src/woff2_dec.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Library for converting WOFF2 format font files to their TTF versions. - -#ifndef WOFF2_WOFF2_DEC_H_ -#define WOFF2_WOFF2_DEC_H_ - -#include <stddef.h> -#include <inttypes.h> -#include "./woff2_out.h" - -namespace woff2 { - -// Compute the size of the final uncompressed font, or 0 on error. -size_t ComputeWOFF2FinalSize(const uint8_t *data, size_t length); - -// Decompresses the font into the target buffer. The result_length should -// be the same as determined by ComputeFinalSize(). Returns true on successful -// decompression. -// DEPRECATED; please prefer the version that takes a WOFF2Out* -bool ConvertWOFF2ToTTF(uint8_t *result, size_t result_length, - const uint8_t *data, size_t length); - -// Decompresses the font into out. Returns true on success. -// Works even if WOFF2Header totalSfntSize is wrong. -// Please prefer this API. -bool ConvertWOFF2ToTTF(const uint8_t *data, size_t length, - WOFF2Out* out); - -} // namespace woff2 - -#endif // WOFF2_WOFF2_DEC_H_ diff --git a/modules/woff2/src/woff2_decompress.cc b/modules/woff2/src/woff2_decompress.cc index f29c797cb..de088b9ec 100644 --- a/modules/woff2/src/woff2_decompress.cc +++ b/modules/woff2/src/woff2_decompress.cc @@ -1,24 +1,16 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// A very simple commandline tool for decompressing woff2 format files to true -// type font files. +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* A very simple commandline tool for decompressing woff2 format files to true + type font files. */ #include <string> #include "./file.h" -#include "./woff2_dec.h" +#include <woff2/decode.h> int main(int argc, char **argv) { @@ -32,6 +24,7 @@ int main(int argc, char **argv) { string filename(argv[1]); string outfilename = filename.substr(0, filename.find_last_of(".")) + ".ttf"; + // Note: update woff2_dec_fuzzer_new_entry.cc if this pattern changes. string input = woff2::GetFileContent(filename); const uint8_t* raw_input = reinterpret_cast<const uint8_t*>(input.data()); string output(std::min(woff2::ComputeWOFF2FinalSize(raw_input, input.size()), diff --git a/modules/woff2/src/woff2_enc.cc b/modules/woff2/src/woff2_enc.cc index d100ad51b..ec00878bc 100644 --- a/modules/woff2/src/woff2_enc.cc +++ b/modules/woff2/src/woff2_enc.cc @@ -1,20 +1,12 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Library for converting TTF format font files to their WOFF2 versions. - -#include "./woff2_enc.h" +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Library for converting TTF format font files to their WOFF2 versions. */ + +#include <woff2/encode.h> #include <stdlib.h> #include <complex> @@ -23,7 +15,7 @@ #include <string> #include <vector> -#include "./compressor.h" +#include <brotli/encode.h> #include "./buffer.h" #include "./font.h" #include "./normalize.h" @@ -34,7 +26,6 @@ #include "./variable_length.h" #include "./woff2_common.h" - namespace woff2 { namespace { @@ -47,16 +38,11 @@ using std::vector; const size_t kWoff2HeaderSize = 48; const size_t kWoff2EntrySize = 20; - -bool Compress(const uint8_t* data, const size_t len, - uint8_t* result, uint32_t* result_len, - brotli::BrotliParams::Mode mode, int quality) { +bool Compress(const uint8_t* data, const size_t len, uint8_t* result, + uint32_t* result_len, BrotliEncoderMode mode, int quality) { size_t compressed_len = *result_len; - brotli::BrotliParams params; - params.mode = mode; - params.quality = quality; - if (brotli::BrotliCompressBuffer(params, len, data, &compressed_len, result) - == 0) { + if (BrotliEncoderCompress(quality, BROTLI_DEFAULT_WINDOW, mode, len, data, + &compressed_len, result) == 0) { return false; } *result_len = compressed_len; @@ -67,14 +53,14 @@ bool Woff2Compress(const uint8_t* data, const size_t len, uint8_t* result, uint32_t* result_len, int quality) { return Compress(data, len, result, result_len, - brotli::BrotliParams::MODE_FONT, quality); + BROTLI_MODE_FONT, quality); } bool TextCompress(const uint8_t* data, const size_t len, uint8_t* result, uint32_t* result_len, int quality) { return Compress(data, len, result, result_len, - brotli::BrotliParams::MODE_TEXT, quality); + BROTLI_MODE_TEXT, quality); } int KnownTableIndex(uint32_t tag) { @@ -111,7 +97,8 @@ size_t TableEntrySize(const Table& table) { size_t ComputeWoff2Length(const FontCollection& font_collection, const std::vector<Table>& tables, - std::map<uint32_t, uint16_t> index_by_offset, + std::map<std::pair<uint32_t, uint32_t>, uint16_t> + index_by_tag_offset, size_t compressed_data_length, size_t extended_metadata_length) { size_t size = kWoff2HeaderSize; @@ -134,7 +121,8 @@ size_t ComputeWoff2Length(const FontCollection& font_collection, // no collection entry for xform table if (table.tag & 0x80808080) continue; - uint16_t table_index = index_by_offset[table.offset]; + std::pair<uint32_t, uint32_t> tag_offset(table.tag, table.offset); + uint16_t table_index = index_by_tag_offset[tag_offset]; size += Size255UShort(table_index); // 255UInt16 index entry } } @@ -326,7 +314,7 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, } std::vector<Table> tables; - std::map<uint32_t, uint16_t> index_by_offset; + std::map<std::pair<uint32_t, uint32_t>, uint16_t> index_by_tag_offset; for (const auto& font : font_collection.fonts) { @@ -336,8 +324,9 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, continue; } - if (index_by_offset.find(src_table.offset) == index_by_offset.end()) { - index_by_offset[src_table.offset] = tables.size(); + std::pair<uint32_t, uint32_t> tag_offset(src_table.tag, src_table.offset); + if (index_by_tag_offset.find(tag_offset) == index_by_tag_offset.end()) { + index_by_tag_offset[tag_offset] = tables.size(); } else { return false; } @@ -362,7 +351,8 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, } size_t woff2_length = ComputeWoff2Length(font_collection, tables, - index_by_offset, total_compressed_length, compressed_metadata_buf_length); + index_by_tag_offset, total_compressed_length, + compressed_metadata_buf_length); if (woff2_length > *result_length) { #ifdef FONT_COMPRESSION_BIN fprintf(stderr, "Result allocation was too small (%zd vs %zd bytes).\n", @@ -435,14 +425,15 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, table.IsReused() ? table.reuse_of->offset : table.offset; uint32_t table_length = table.IsReused() ? table.reuse_of->length : table.length; - if (index_by_offset.find(table_offset) == index_by_offset.end()) { + std::pair<uint32_t, uint32_t> tag_offset(table.tag, table_offset); + if (index_by_tag_offset.find(tag_offset) == index_by_tag_offset.end()) { #ifdef FONT_COMPRESSION_BIN - fprintf(stderr, "Missing table index for offset 0x%08x\n", +fprintf(stderr, "Missing table index for offset 0x%08x\n", table_offset); #endif return FONT_COMPRESSION_FAILURE(); } - uint16_t index = index_by_offset[table_offset]; + uint16_t index = index_by_tag_offset[tag_offset]; Store255UShort(index, &offset, result); } diff --git a/modules/woff2/src/woff2_enc.h b/modules/woff2/src/woff2_enc.h deleted file mode 100644 index 3ac8c3ab1..000000000 --- a/modules/woff2/src/woff2_enc.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Library for converting WOFF2 format font files to their TTF versions. - -#ifndef WOFF2_WOFF2_ENC_H_ -#define WOFF2_WOFF2_ENC_H_ - -#include <stddef.h> -#include <inttypes.h> -#include <string> - -using std::string; - - -namespace woff2 { - -struct WOFF2Params { - WOFF2Params() : extended_metadata(""), brotli_quality(11), - allow_transforms(true) {} - - string extended_metadata; - int brotli_quality; - bool allow_transforms; -}; - -// Returns an upper bound on the size of the compressed file. -size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length); -size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length, - const string& extended_metadata); - -// Compresses the font into the target buffer. *result_length should be at least -// the value returned by MaxWOFF2CompressedSize(), upon return, it is set to the -// actual compressed size. Returns true on successful compression. -bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, - uint8_t *result, size_t *result_length); -bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, - uint8_t *result, size_t *result_length, - const WOFF2Params& params); - -} // namespace woff2 - -#endif // WOFF2_WOFF2_ENC_H_ diff --git a/modules/woff2/src/woff2_info.cc b/modules/woff2/src/woff2_info.cc new file mode 100644 index 000000000..2b51adcb6 --- /dev/null +++ b/modules/woff2/src/woff2_info.cc @@ -0,0 +1,144 @@ +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* A commandline tool for dumping info about a woff2 file. */ + +#include <string> + +#include "file.h" +#include "./woff2_common.h" +#include "./buffer.h" +#include "./font.h" +#include "./table_tags.h" +#include "./variable_length.h" + +std::string PrintTag(int tag) { + if (tag & 0x80808080) { + return std::string("_xfm"); // print _xfm for xform tables (else garbage) + } + char printable[] = { + static_cast<char>((tag >> 24) & 0xFF), + static_cast<char>((tag >> 16) & 0xFF), + static_cast<char>((tag >> 8) & 0xFF), + static_cast<char>(tag & 0xFF) + }; + return std::string(printable, 4); +} + +int main(int argc, char **argv) { + using std::string; + + if (argc != 2) { + fprintf(stderr, "One argument, the input filename, must be provided.\n"); + return 1; + } + + string filename(argv[1]); + string outfilename = filename.substr(0, filename.find_last_of(".")) + ".woff2"; + fprintf(stdout, "Processing %s => %s\n", + filename.c_str(), outfilename.c_str()); + string input = woff2::GetFileContent(filename); + + woff2::Buffer file(reinterpret_cast<const uint8_t*>(input.data()), + input.size()); + + printf("WOFF2Header\n"); + uint32_t signature, flavor, length, totalSfntSize, totalCompressedSize; + uint32_t metaOffset, metaLength, metaOrigLength, privOffset, privLength; + uint16_t num_tables, reserved, major, minor; + if (!file.ReadU32(&signature)) return 1; + if (!file.ReadU32(&flavor)) return 1; + if (!file.ReadU32(&length)) return 1; + if (!file.ReadU16(&num_tables)) return 1; + if (!file.ReadU16(&reserved)) return 1; + if (!file.ReadU32(&totalSfntSize)) return 1; + if (!file.ReadU32(&totalCompressedSize)) return 1; + if (!file.ReadU16(&major)) return 1; + if (!file.ReadU16(&minor)) return 1; + if (!file.ReadU32(&metaOffset)) return 1; + if (!file.ReadU32(&metaLength)) return 1; + if (!file.ReadU32(&metaOrigLength)) return 1; + if (!file.ReadU32(&privOffset)) return 1; + if (!file.ReadU32(&privLength)) return 1; + + if (signature != 0x774F4632) { + printf("Invalid signature: %08x\n", signature); + return 1; + } + printf("signature 0x%08x\n", signature); + printf("flavor 0x%08x\n", flavor); + printf("length %d\n", length); + printf("numTables %d\n", num_tables); + printf("reserved %d\n", reserved); + printf("totalSfntSize %d\n", totalSfntSize); + printf("totalCompressedSize %d\n", totalCompressedSize); + printf("majorVersion %d\n", major); + printf("minorVersion %d\n", minor); + printf("metaOffset %d\n", metaOffset); + printf("metaLength %d\n", metaLength); + printf("metaOrigLength %d\n", metaOrigLength); + printf("privOffset %d\n", privOffset); + printf("privLength %d\n", privLength); + + std::vector<uint32_t> table_tags; + printf("TableDirectory starts at +%zu\n", file.offset()); + printf("Entry offset flags tag origLength txLength\n"); + for (auto i = 0; i < num_tables; i++) { + size_t offset = file.offset(); + uint8_t flags; + uint32_t tag, origLength, transformLength; + if (!file.ReadU8(&flags)) return 1; + if ((flags & 0x3f) == 0x3f) { + if (!file.ReadU32(&tag)) return 1; + } else { + tag = woff2::kKnownTags[flags & 0x3f]; + } + table_tags.push_back(tag); + if (!ReadBase128(&file, &origLength)) return 1; + + printf("%5d %6zu 0x%02x %s %10d", i, offset, flags, + PrintTag(tag).c_str(), origLength); + + uint8_t xform_version = (flags >> 6) & 0x3; + if (tag == woff2::kGlyfTableTag || tag == woff2::kLocaTableTag) { + if (xform_version == 0) { + if (!ReadBase128(&file, &transformLength)) return 1; + printf(" %8d", transformLength); + } + } else if (xform_version > 0) { + if (!ReadBase128(&file, &transformLength)) return 1; + printf(" %8d", transformLength); + } + printf("\n"); + } + + // Collection header + if (flavor == woff2::kTtcFontFlavor) { + uint32_t version, numFonts; + if (!file.ReadU32(&version)) return 1; + if (!woff2::Read255UShort(&file, &numFonts)) return 1; + printf("CollectionHeader 0x%08x %d fonts\n", version, numFonts); + + for (auto i = 0; i < numFonts; i++) { + uint32_t numTables, flavor; + if (!woff2::Read255UShort(&file, &numTables)) return 1; + if (!file.ReadU32(&flavor)) return 1; + printf("CollectionFontEntry %d flavor 0x%08x %d tables\n", i, flavor, + numTables); + for (auto j = 0; j < numTables; j++) { + uint32_t table_idx; + if (!woff2::Read255UShort(&file, &table_idx)) return 1; + if (table_idx >= table_tags.size()) return 1; + printf(" %d %s (idx %d)\n", j, + PrintTag(table_tags[table_idx]).c_str(), table_idx); + } + } + } + + printf("TableDirectory ends at +%zu\n", file.offset()); + + return 0; +} diff --git a/modules/woff2/src/woff2_out.cc b/modules/woff2/src/woff2_out.cc index 888230644..8ab32681f 100644 --- a/modules/woff2/src/woff2_out.cc +++ b/modules/woff2/src/woff2_out.cc @@ -1,20 +1,14 @@ -// Copyright 2014 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Output buffer for WOFF2 decompression. +/* Copyright 2014 Google Inc. All Rights Reserved. -#include "./woff2_out.h" + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Output buffer for WOFF2 decompression. */ + +#include <woff2/output.h> + +using std::string; namespace woff2 { diff --git a/modules/woff2/src/woff2_out.h b/modules/woff2/src/woff2_out.h deleted file mode 100644 index c956afa0e..000000000 --- a/modules/woff2/src/woff2_out.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2016 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Output buffer for WOFF2 decompression. - -// Copyright 2016 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Output buffer for WOFF2 decompression. - -#ifndef WOFF2_WOFF2_OUT_H_ -#define WOFF2_WOFF2_OUT_H_ - -#include <algorithm> -#include <cstring> -#include <memory> -#include <string> -#include "./port.h" - -namespace woff2 { - -// Suggested max size for output. -const size_t kDefaultMaxSize = 30 * 1024 * 1024; - -using std::string; - - -/** - * Output interface for the woff2 decoding. - * - * Writes to arbitrary offsets are supported to facilitate updating offset - * table and checksums after tables are ready. Reading the current size is - * supported so a 'loca' table can be built up while writing glyphs. - * - * By default limits size to kDefaultMaxSize. - */ -class WOFF2Out { - public: - virtual ~WOFF2Out(void) {} - - // Append n bytes of data from buf. - // Return true if all written, false otherwise. - virtual bool Write(const void *buf, size_t n) = 0; - - // Write n bytes of data from buf at offset. - // Return true if all written, false otherwise. - virtual bool Write(const void *buf, size_t offset, size_t n) = 0; - - virtual size_t Size() = 0; -}; - -/** - * Expanding memory block for woff2 out. By default limited to kDefaultMaxSize. - */ -class WOFF2StringOut : public WOFF2Out { - public: - // Create a writer that writes its data to buf. - // buf->size() will grow to at most max_size - // buf may be sized (e.g. using EstimateWOFF2FinalSize) or empty. - explicit WOFF2StringOut(string* buf); - - bool Write(const void *buf, size_t n) override; - bool Write(const void *buf, size_t offset, size_t n) override; - size_t Size() override { return offset_; } - size_t MaxSize() { return max_size_; } - void SetMaxSize(size_t max_size); - private: - string* buf_; - size_t max_size_; - size_t offset_; -}; - -/** - * Fixed memory block for woff2 out. - */ -class WOFF2MemoryOut : public WOFF2Out { - public: - // Create a writer that writes its data to buf. - WOFF2MemoryOut(uint8_t* buf, size_t buf_size); - - bool Write(const void *buf, size_t n) override; - bool Write(const void *buf, size_t offset, size_t n) override; - size_t Size() override { return offset_; } - private: - uint8_t* buf_; - size_t buf_size_; - size_t offset_; -}; - -} // namespace woff2 - -#endif // WOFF2_WOFF2_OUT_H_ |