From 2e09253456d2ca968fb57a690af1be243afaec18 Mon Sep 17 00:00:00 2001 From: Rod Sheeter Date: Mon, 31 Jul 2017 09:16:49 -0700 Subject: [PATCH] Check for non-consecutive glyf/loca. Reject inconsistent xform flags on glyf/loca --- src/woff2_dec.cc | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/woff2_dec.cc b/src/woff2_dec.cc index d07e2ed..0986cfd 100644 --- a/src/woff2_dec.cc +++ b/src/woff2_dec.cc @@ -876,11 +876,26 @@ bool ReconstructFont(uint8_t* transformed_buf, std::vector tables = Tables(hdr, font_index); // 'glyf' without 'loca' doesn't make sense - if (PREDICT_FALSE(static_cast(FindTable(&tables, kGlyfTableTag)) != - static_cast(FindTable(&tables, kLocaTableTag)))) { + const Table* glyf_table = FindTable(&tables, kGlyfTableTag); + const Table* loca_table = FindTable(&tables, kLocaTableTag); + if (PREDICT_FALSE(static_cast(glyf_table) != + static_cast(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; @@ -1100,8 +1115,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; @@ -1113,19 +1129,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(); + } } } }