Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ COMMONOBJ = $(BROTLIOBJ)/common/*.o
OBJS = $(patsubst %, $(SRCDIR)/%, $(OUROBJ))
EXECUTABLES=woff2_compress woff2_decompress woff2_info
EXE_OBJS=$(patsubst %, $(SRCDIR)/%.o, $(EXECUTABLES))
ARCHIVES=convert_woff2ttf_fuzzer convert_woff2ttf_fuzzer_new_entry
ARCHIVES=convert_woff2ttf_fuzzer convert_woff2ttf_fuzzer_new_entry \
convert_ttf2woff2_fuzzer woff2_memory_out_fuzzer \
woff2_glyph_fuzzer woff2_font_fuzzer
ARCHIVE_OBJS=$(patsubst %, $(SRCDIR)/%.o, $(ARCHIVES))

ifeq (,$(wildcard $(BROTLI)/*))
Expand Down
46 changes: 46 additions & 0 deletions src/convert_ttf2woff2_fuzzer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include <string>

#include <woff2/encode.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 1) {
return 0;
}

woff2::WOFF2Params params;
uint8_t first_byte = data[0];
params.allow_transforms = first_byte & 1;
params.brotli_quality = (first_byte >> 1) % 12; // 0-11

size_t metadata_size = 0;
if (size > 2) {
metadata_size = data[1] % (size - 1);
}

if (metadata_size > 0) {
params.extended_metadata.assign(reinterpret_cast<const char*>(data + 2), metadata_size);
}

size_t offset = 2 + metadata_size;
if (offset > size) {
return 0;
}

const uint8_t* font_data = data + offset;
size_t font_size = size - offset;

if (font_size == 0) {
return 0;
}

size_t result_length = woff2::MaxWOFF2CompressedSize(font_data, font_size, params.extended_metadata);
if (result_length > 30 * 1024 * 1024) {
return 0;
}
std::vector<uint8_t> result(result_length);
woff2::ConvertTTFToWOFF2(font_data, font_size, result.data(), &result_length, params);
return 0;
}
45 changes: 45 additions & 0 deletions src/woff2_font_fuzzer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <stddef.h>
#include <stdint.h>
#include <vector>

#include "font.h"
#include "normalize.h"
#include "transform.h"
#include "woff2_common.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 10 || size > 1000000) {
return 0;
}
woff2::FontCollection font_collection;
if (!woff2::ReadFontCollection(data, size, &font_collection)) {
return 0;
}

woff2::NormalizeFontCollection(&font_collection);

for (auto& font : font_collection.fonts) {
woff2::TransformGlyfAndLocaTables(&font);
woff2::TransformHmtxTable(&font);
}

size_t out_size = woff2::FontCollectionFileSize(font_collection);
// Robust size calculation for TTC header
if (font_collection.flavor == woff2::kTtcFontFlavor) {
size_t header_size = 12 + 4 * font_collection.fonts.size();
if (font_collection.header_version == 0x00020000) {
header_size += 12;
}
out_size = std::max(out_size, header_size);
}

if (out_size == 0 || out_size > 30 * 1024 * 1024) {
return 0;
}

// Add some padding to be safe against library bugs
std::vector<uint8_t> out(out_size + 1024);
woff2::WriteFontCollection(font_collection, out.data(), out.size());

return 0;
}
21 changes: 21 additions & 0 deletions src/woff2_glyph_fuzzer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <stddef.h>
#include <stdint.h>
#include <vector>

#include "glyph.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 2 || size > 10000) {
return 0;
}
woff2::Glyph glyph;
if (!woff2::ReadGlyph(data, size, &glyph)) {
return 0;
}

size_t dst_size = size * 2 + 1024; // Provide enough space
std::vector<uint8_t> dst(dst_size);
woff2::StoreGlyph(glyph, dst.data(), &dst_size);

return 0;
}
18 changes: 18 additions & 0 deletions src/woff2_memory_out_fuzzer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stddef.h>
#include <stdint.h>
#include <vector>

#include <woff2/decode.h>
#include <woff2/output.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
size_t final_size = woff2::ComputeWOFF2FinalSize(data, size);
if (final_size == 0 || final_size > 30 * 1024 * 1024) {
return 0;
}

std::vector<uint8_t> result(final_size);
woff2::WOFF2MemoryOut out(result.data(), result.size());
woff2::ConvertWOFF2ToTTF(data, size, &out);
return 0;
}