Fix TTC detection, based on findings by libFuzzer
This commit is contained in:
+4
-5
@@ -181,15 +181,14 @@ bool ReadFontCollection(const uint8_t* data, size_t len,
|
|||||||
FontCollection* font_collection) {
|
FontCollection* font_collection) {
|
||||||
Buffer file(data, len);
|
Buffer file(data, len);
|
||||||
|
|
||||||
uint32_t flavor;
|
if (!file.ReadU32(&font_collection->flavor)) {
|
||||||
if (!file.ReadU32(&flavor)) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
return FONT_COMPRESSION_FAILURE();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flavor != kTtcFontFlavor) {
|
if (font_collection->flavor != kTtcFontFlavor) {
|
||||||
font_collection->fonts.resize(1);
|
font_collection->fonts.resize(1);
|
||||||
Font& font = font_collection->fonts[0];
|
Font& font = font_collection->fonts[0];
|
||||||
font.flavor = flavor;
|
font.flavor = font_collection->flavor;
|
||||||
return ReadTrueTypeFont(&file, data, len, &font);
|
return ReadTrueTypeFont(&file, data, len, &font);
|
||||||
}
|
}
|
||||||
return ReadTrueTypeCollection(&file, data, len, font_collection);
|
return ReadTrueTypeCollection(&file, data, len, font_collection);
|
||||||
@@ -286,7 +285,7 @@ bool WriteFontCollection(const FontCollection& font_collection, uint8_t* dst,
|
|||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
// It's simpler if this just a simple sfnt
|
// It's simpler if this just a simple sfnt
|
||||||
if (font_collection.fonts.size() == 1) {
|
if (font_collection.flavor != kTtcFontFlavor) {
|
||||||
return WriteFont(font_collection.fonts[0], &offset, dst, dst_size);
|
return WriteFont(font_collection.fonts[0], &offset, dst, dst_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ struct Font {
|
|||||||
|
|
||||||
// Accomodates both singular (OTF, TTF) and collection (TTC) fonts
|
// Accomodates both singular (OTF, TTF) and collection (TTC) fonts
|
||||||
struct FontCollection {
|
struct FontCollection {
|
||||||
|
uint32_t flavor;
|
||||||
uint32_t header_version;
|
uint32_t header_version;
|
||||||
// (offset, first use of table*) pairs
|
// (offset, first use of table*) pairs
|
||||||
std::map<uint32_t, Font::Table*> tables;
|
std::map<uint32_t, Font::Table*> tables;
|
||||||
|
|||||||
+8
-9
@@ -121,7 +121,7 @@ size_t ComputeWoff2Length(const FontCollection& font_collection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for collections only, collection tables
|
// for collections only, collection tables
|
||||||
if (font_collection.fonts.size() > 1) {
|
if (font_collection.flavor == kTtcFontFlavor) {
|
||||||
size += 4; // UInt32 Version of TTC Header
|
size += 4; // UInt32 Version of TTC Header
|
||||||
size += Size255UShort(font_collection.fonts.size()); // 255UInt16 numFonts
|
size += Size255UShort(font_collection.fonts.size()); // 255UInt16 numFonts
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ size_t ComputeUncompressedLength(const Font& font) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t ComputeUncompressedLength(const FontCollection& font_collection) {
|
size_t ComputeUncompressedLength(const FontCollection& font_collection) {
|
||||||
if (font_collection.fonts.size() == 1) {
|
if (font_collection.flavor != kTtcFontFlavor) {
|
||||||
return ComputeUncompressedLength(font_collection.fonts[0]);
|
return ComputeUncompressedLength(font_collection.fonts[0]);
|
||||||
}
|
}
|
||||||
size_t size = CollectionHeaderSize(font_collection.header_version,
|
size_t size = CollectionHeaderSize(font_collection.header_version,
|
||||||
@@ -372,13 +372,12 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
|
|||||||
}
|
}
|
||||||
*result_length = woff2_length;
|
*result_length = woff2_length;
|
||||||
|
|
||||||
const Font& first_font = font_collection.fonts[0];
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
// start of woff2 header (http://www.w3.org/TR/WOFF2/#woff20Header)
|
// start of woff2 header (http://www.w3.org/TR/WOFF2/#woff20Header)
|
||||||
StoreU32(kWoff2Signature, &offset, result);
|
StoreU32(kWoff2Signature, &offset, result);
|
||||||
if (font_collection.fonts.size() == 1) {
|
if (font_collection.flavor != kTtcFontFlavor) {
|
||||||
StoreU32(first_font.flavor, &offset, result);
|
StoreU32(font_collection.fonts[0].flavor, &offset, result);
|
||||||
} else {
|
} else {
|
||||||
StoreU32(kTtcFontFlavor, &offset, result);
|
StoreU32(kTtcFontFlavor, &offset, result);
|
||||||
}
|
}
|
||||||
@@ -389,9 +388,9 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
|
|||||||
StoreU32(ComputeUncompressedLength(font_collection), &offset, result);
|
StoreU32(ComputeUncompressedLength(font_collection), &offset, result);
|
||||||
StoreU32(total_compressed_length, &offset, result); // totalCompressedSize
|
StoreU32(total_compressed_length, &offset, result); // totalCompressedSize
|
||||||
|
|
||||||
// TODO(user): is always taking this from the first tables head OK?
|
// Let's just all be v1.0
|
||||||
// font revision
|
Store16(1, &offset, result); // majorVersion
|
||||||
StoreBytes(first_font.FindTable(kHeadTableTag)->data + 4, 4, &offset, result);
|
Store16(0, &offset, result); // minorVersion
|
||||||
if (compressed_metadata_buf_length > 0) {
|
if (compressed_metadata_buf_length > 0) {
|
||||||
StoreU32(woff2_length - compressed_metadata_buf_length,
|
StoreU32(woff2_length - compressed_metadata_buf_length,
|
||||||
&offset, result); // metaOffset
|
&offset, result); // metaOffset
|
||||||
@@ -413,7 +412,7 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for collections only, collection table directory
|
// for collections only, collection table directory
|
||||||
if (font_collection.fonts.size() > 1) {
|
if (font_collection.flavor == kTtcFontFlavor) {
|
||||||
StoreU32(font_collection.header_version, &offset, result);
|
StoreU32(font_collection.header_version, &offset, result);
|
||||||
Store255UShort(font_collection.fonts.size(), &offset, result);
|
Store255UShort(font_collection.fonts.size(), &offset, result);
|
||||||
for (const Font& font : font_collection.fonts) {
|
for (const Font& font : font_collection.fonts) {
|
||||||
|
|||||||
Reference in New Issue
Block a user