Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cff.h"
      6 
      7 #include <cstring>
      8 #include <utility>  // std::pair
      9 #include <vector>
     10 
     11 #include "cff_type2_charstring.h"
     12 
     13 // CFF - PostScript font program (Compact Font Format) table
     14 // http://www.microsoft.com/typography/otspec/cff.htm
     15 // http://www.microsoft.com/typography/otspec/cffspec.htm
     16 
     17 namespace {
     18 
     19 enum DICT_OPERAND_TYPE {
     20   DICT_OPERAND_INTEGER,
     21   DICT_OPERAND_REAL,
     22   DICT_OPERATOR,
     23 };
     24 
     25 enum DICT_DATA_TYPE {
     26   DICT_DATA_TOPLEVEL,
     27   DICT_DATA_FDARRAY,
     28 };
     29 
     30 enum FONT_FORMAT {
     31   FORMAT_UNKNOWN,
     32   FORMAT_CID_KEYED,
     33   FORMAT_OTHER,  // Including synthetic fonts
     34 };
     35 
     36 // see Appendix. A
     37 const size_t kNStdString = 390;
     38 
     39 bool ReadOffset(ots::Buffer *table, uint8_t off_size, uint32_t *offset) {
     40   if (off_size > 4) {
     41     return OTS_FAILURE();
     42   }
     43 
     44   uint32_t tmp32 = 0;
     45   for (unsigned i = 0; i < off_size; ++i) {
     46     uint8_t tmp8 = 0;
     47     if (!table->ReadU8(&tmp8)) {
     48       return OTS_FAILURE();
     49     }
     50     tmp32 <<= 8;
     51     tmp32 += tmp8;
     52   }
     53   *offset = tmp32;
     54   return true;
     55 }
     56 
     57 bool ParseIndex(ots::Buffer *table, ots::CFFIndex *index) {
     58   index->off_size = 0;
     59   index->offsets.clear();
     60 
     61   if (!table->ReadU16(&(index->count))) {
     62     return OTS_FAILURE();
     63   }
     64   if (index->count == 0) {
     65     // An empty INDEX.
     66     index->offset_to_next = table->offset();
     67     return true;
     68   }
     69 
     70   if (!table->ReadU8(&(index->off_size))) {
     71     return OTS_FAILURE();
     72   }
     73   if ((index->off_size == 0) ||
     74       (index->off_size > 4)) {
     75     return OTS_FAILURE();
     76   }
     77 
     78   const size_t array_size = (index->count + 1) * index->off_size;
     79   // less than ((64k + 1) * 4), thus does not overflow.
     80   const size_t object_data_offset = table->offset() + array_size;
     81   // does not overflow too, since offset() <= 1GB.
     82 
     83   if (object_data_offset >= table->length()) {
     84     return OTS_FAILURE();
     85   }
     86 
     87   for (unsigned i = 0; i <= index->count; ++i) {  // '<=' is not a typo.
     88     uint32_t rel_offset = 0;
     89     if (!ReadOffset(table, index->off_size, &rel_offset)) {
     90       return OTS_FAILURE();
     91     }
     92     if (rel_offset < 1) {
     93       return OTS_FAILURE();
     94     }
     95     if (i == 0 && rel_offset != 1) {
     96       return OTS_FAILURE();
     97     }
     98 
     99     if (rel_offset > table->length()) {
    100       return OTS_FAILURE();
    101     }
    102 
    103     // does not underflow.
    104     if (object_data_offset > table->length() - (rel_offset - 1)) {
    105       return OTS_FAILURE();
    106     }
    107 
    108     index->offsets.push_back(
    109         object_data_offset + (rel_offset - 1));  // less than length(), 1GB.
    110   }
    111 
    112   for (unsigned i = 1; i < index->offsets.size(); ++i) {
    113     // We allow consecutive identical offsets here for zero-length strings.
    114     // See http://crbug.com/69341 for more details.
    115     if (index->offsets[i] < index->offsets[i - 1]) {
    116       return OTS_FAILURE();
    117     }
    118   }
    119 
    120   index->offset_to_next = index->offsets.back();
    121   return true;
    122 }
    123 
    124 bool ParseNameData(
    125     ots::Buffer *table, const ots::CFFIndex &index, std::string* out_name) {
    126   uint8_t name[256] = {0};
    127   if (index.offsets.size() == 0) {  // just in case.
    128     return OTS_FAILURE();
    129   }
    130   for (unsigned i = 1; i < index.offsets.size(); ++i) {
    131     const size_t length = index.offsets[i] - index.offsets[i - 1];
    132     // font names should be no longer than 127 characters.
    133     if (length > 127) {
    134       return OTS_FAILURE();
    135     }
    136 
    137     table->set_offset(index.offsets[i - 1]);
    138     if (!table->Read(name, length)) {
    139       return OTS_FAILURE();
    140     }
    141 
    142     for (size_t j = 0; j < length; ++j) {
    143       // setting the first byte to NUL is allowed.
    144       if (j == 0 && name[j] == 0) continue;
    145       // non-ASCII characters are not recommended (except the first character).
    146       if (name[j] < 33 || name[j] > 126) {
    147         return OTS_FAILURE();
    148       }
    149       // [, ], ... are not allowed.
    150       if (std::strchr("[](){}<>/% ", name[j])) {
    151         return OTS_FAILURE();
    152       }
    153     }
    154   }
    155 
    156   *out_name = reinterpret_cast<char *>(name);
    157   return true;
    158 }
    159 
    160 bool CheckOffset(const std::pair<uint32_t, DICT_OPERAND_TYPE>& operand,
    161                  size_t table_length) {
    162   if (operand.second != DICT_OPERAND_INTEGER) {
    163     return OTS_FAILURE();
    164   }
    165   if (operand.first >= table_length) {
    166     return OTS_FAILURE();
    167   }
    168   return true;
    169 }
    170 
    171 bool CheckSid(const std::pair<uint32_t, DICT_OPERAND_TYPE>& operand,
    172               size_t sid_max) {
    173   if (operand.second != DICT_OPERAND_INTEGER) {
    174     return OTS_FAILURE();
    175   }
    176   if (operand.first > sid_max) {
    177     return OTS_FAILURE();
    178   }
    179   return true;
    180 }
    181 
    182 bool ParseDictDataBcd(
    183     ots::Buffer *table,
    184     std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
    185   bool read_decimal_point = false;
    186   bool read_e = false;
    187 
    188   uint8_t nibble = 0;
    189   size_t count = 0;
    190   while (true) {
    191     if (!table->ReadU8(&nibble)) {
    192       return OTS_FAILURE();
    193     }
    194     if ((nibble & 0xf0) == 0xf0) {
    195       if ((nibble & 0xf) == 0xf) {
    196         // TODO(yusukes): would be better to store actual double value,
    197         // rather than the dummy integer.
    198         operands->push_back(std::make_pair(static_cast<uint32_t>(0),
    199                                            DICT_OPERAND_REAL));
    200         return true;
    201       }
    202       return OTS_FAILURE();
    203     }
    204     if ((nibble & 0x0f) == 0x0f) {
    205       operands->push_back(std::make_pair(static_cast<uint32_t>(0),
    206                                          DICT_OPERAND_REAL));
    207       return true;
    208     }
    209 
    210     // check number format
    211     uint8_t nibbles[2];
    212     nibbles[0] = (nibble & 0xf0) >> 8;
    213     nibbles[1] = (nibble & 0x0f);
    214     for (unsigned i = 0; i < 2; ++i) {
    215       if (nibbles[i] == 0xd) {  // reserved number
    216         return OTS_FAILURE();
    217       }
    218       if ((nibbles[i] == 0xe) &&  // minus
    219           ((count > 0) || (i > 0))) {
    220         return OTS_FAILURE();  // minus sign should be the first character.
    221       }
    222       if (nibbles[i] == 0xa) {  // decimal point
    223         if (!read_decimal_point) {
    224           read_decimal_point = true;
    225         } else {
    226           return OTS_FAILURE();  // two or more points.
    227         }
    228       }
    229       if ((nibbles[i] == 0xb) ||  // E+
    230           (nibbles[i] == 0xc)) {  // E-
    231         if (!read_e) {
    232           read_e = true;
    233         } else {
    234           return OTS_FAILURE();  // two or more E's.
    235         }
    236       }
    237     }
    238     ++count;
    239   }
    240 }
    241 
    242 bool ParseDictDataEscapedOperator(
    243     ots::Buffer *table,
    244     std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
    245   uint8_t op = 0;
    246   if (!table->ReadU8(&op)) {
    247     return OTS_FAILURE();
    248   }
    249 
    250   if ((op <= 14) ||
    251       (op >= 17 && op <= 23) ||
    252       (op >= 30 && op <= 38)) {
    253     operands->push_back(std::make_pair((12U << 8) + op, DICT_OPERATOR));
    254     return true;
    255   }
    256 
    257   // reserved area.
    258   return OTS_FAILURE();
    259 }
    260 
    261 bool ParseDictDataNumber(
    262     ots::Buffer *table, uint8_t b0,
    263     std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
    264   uint8_t b1 = 0;
    265   uint8_t b2 = 0;
    266   uint8_t b3 = 0;
    267   uint8_t b4 = 0;
    268 
    269   switch (b0) {
    270     case 28:  // shortint
    271       if (!table->ReadU8(&b1) ||
    272           !table->ReadU8(&b2)) {
    273         return OTS_FAILURE();
    274       }
    275       operands->push_back(std::make_pair(
    276           static_cast<uint32_t>((b1 << 8) + b2), DICT_OPERAND_INTEGER));
    277       return true;
    278 
    279     case 29:  // longint
    280       if (!table->ReadU8(&b1) ||
    281           !table->ReadU8(&b2) ||
    282           !table->ReadU8(&b3) ||
    283           !table->ReadU8(&b4)) {
    284         return OTS_FAILURE();
    285       }
    286       operands->push_back(std::make_pair(
    287           static_cast<uint32_t>((b1 << 24) + (b2 << 16) + (b3 << 8) + b4),
    288           DICT_OPERAND_INTEGER));
    289       return true;
    290 
    291     case 30:  // binary coded decimal
    292       return ParseDictDataBcd(table, operands);
    293 
    294     default:
    295       break;
    296   }
    297 
    298   uint32_t result;
    299   if (b0 >=32 && b0 <=246) {
    300     result = b0 - 139;
    301   } else if (b0 >=247 && b0 <= 250) {
    302     if (!table->ReadU8(&b1)) {
    303       return OTS_FAILURE();
    304     }
    305     result = (b0 - 247) * 256 + b1 + 108;
    306   } else if (b0 >= 251 && b0 <= 254) {
    307     if (!table->ReadU8(&b1)) {
    308       return OTS_FAILURE();
    309     }
    310     result = -(b0 - 251) * 256 + b1 - 108;
    311   } else {
    312     return OTS_FAILURE();
    313   }
    314 
    315   operands->push_back(std::make_pair(result, DICT_OPERAND_INTEGER));
    316   return true;
    317 }
    318 
    319 bool ParseDictDataReadNext(
    320     ots::Buffer *table,
    321     std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
    322   uint8_t op = 0;
    323   if (!table->ReadU8(&op)) {
    324     return OTS_FAILURE();
    325   }
    326   if (op <= 21) {
    327     if (op == 12) {
    328       return ParseDictDataEscapedOperator(table, operands);
    329     }
    330     operands->push_back(std::make_pair(
    331         static_cast<uint32_t>(op), DICT_OPERATOR));
    332     return true;
    333   } else if (op <= 27 || op == 31 || op == 255) {
    334     // reserved area.
    335     return OTS_FAILURE();
    336   }
    337 
    338   return ParseDictDataNumber(table, op, operands);
    339 }
    340 
    341 bool ParsePrivateDictData(
    342     const uint8_t *data,
    343     size_t table_length, size_t offset, size_t dict_length,
    344     DICT_DATA_TYPE type, ots::OpenTypeCFF *out_cff) {
    345   ots::Buffer table(data + offset, dict_length);
    346   std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands;
    347 
    348   // Since a Private DICT for FDArray might not have a Local Subr (e.g. Hiragino
    349   // Kaku Gothic Std W8), we create an empty Local Subr here to match the size
    350   // of FDArray the size of |local_subrs_per_font|.
    351   if (type == DICT_DATA_FDARRAY) {
    352     out_cff->local_subrs_per_font.push_back(new ots::CFFIndex);
    353   }
    354 
    355   while (table.offset() < dict_length) {
    356     if (!ParseDictDataReadNext(&table, &operands)) {
    357       return OTS_FAILURE();
    358     }
    359     if (operands.empty()) {
    360       return OTS_FAILURE();
    361     }
    362     if (operands.size() > 48) {
    363       // An operator may be preceded by up to a maximum of 48 operands.
    364       return OTS_FAILURE();
    365     }
    366     if (operands.back().second != DICT_OPERATOR) {
    367       continue;
    368     }
    369 
    370     // got operator
    371     const uint32_t op = operands.back().first;
    372     operands.pop_back();
    373 
    374     switch (op) {
    375       // array
    376       case 6:  // BlueValues
    377       case 7:  // OtherBlues
    378       case 8:  // FamilyBlues
    379       case 9:  // FamilyOtherBlues
    380       case (12U << 8) + 12:  // StemSnapH (delta)
    381       case (12U << 8) + 13:  // StemSnapV (delta)
    382         if (operands.empty()) {
    383           return OTS_FAILURE();
    384         }
    385         break;
    386 
    387       // number
    388       case 10:  // StdHW
    389       case 11:  // StdVW
    390       case 20:  // defaultWidthX
    391       case 21:  // nominalWidthX
    392       case (12U << 8) + 9:   // BlueScale
    393       case (12U << 8) + 10:  // BlueShift
    394       case (12U << 8) + 11:  // BlueFuzz
    395       case (12U << 8) + 17:  // LanguageGroup
    396       case (12U << 8) + 18:  // ExpansionFactor
    397       case (12U << 8) + 19:  // initialRandomSeed
    398         if (operands.size() != 1) {
    399           return OTS_FAILURE();
    400         }
    401         break;
    402 
    403       // Local Subrs INDEX, offset(self)
    404       case 19: {
    405         if (operands.size() != 1) {
    406           return OTS_FAILURE();
    407         }
    408         if (operands.back().second != DICT_OPERAND_INTEGER) {
    409           return OTS_FAILURE();
    410         }
    411         if (operands.back().first >= 1024 * 1024 * 1024) {
    412           return OTS_FAILURE();
    413         }
    414         if (operands.back().first + offset >= table_length) {
    415           return OTS_FAILURE();
    416         }
    417         // parse "16. Local Subrs INDEX"
    418         ots::Buffer table(data, table_length);
    419         table.set_offset(operands.back().first + offset);
    420         ots::CFFIndex *local_subrs_index = NULL;
    421         if (type == DICT_DATA_FDARRAY) {
    422           if (out_cff->local_subrs_per_font.empty()) {
    423             return OTS_FAILURE();  // not reached.
    424           }
    425           local_subrs_index = out_cff->local_subrs_per_font.back();
    426         } else { // type == DICT_DATA_TOPLEVEL
    427           if (out_cff->local_subrs) {
    428             return OTS_FAILURE();  // two or more local_subrs?
    429           }
    430           local_subrs_index = new ots::CFFIndex;
    431           out_cff->local_subrs = local_subrs_index;
    432         }
    433         if (!ParseIndex(&table, local_subrs_index)) {
    434           return OTS_FAILURE();
    435         }
    436         break;
    437       }
    438 
    439       // boolean
    440       case (12U << 8) + 14:  // ForceBold
    441         if (operands.size() != 1) {
    442           return OTS_FAILURE();
    443         }
    444         if (operands.back().second != DICT_OPERAND_INTEGER) {
    445           return OTS_FAILURE();
    446         }
    447         if (operands.back().first >= 2) {
    448           return OTS_FAILURE();
    449         }
    450         break;
    451 
    452       default:
    453         return OTS_FAILURE();
    454     }
    455     operands.clear();
    456   }
    457 
    458   return true;
    459 }
    460 
    461 bool ParseDictData(const uint8_t *data, size_t table_length,
    462                    const ots::CFFIndex &index, size_t sid_max,
    463                    DICT_DATA_TYPE type, ots::OpenTypeCFF *out_cff) {
    464   for (unsigned i = 1; i < index.offsets.size(); ++i) {
    465     if (type == DICT_DATA_TOPLEVEL) {
    466       out_cff->char_strings_array.push_back(new ots::CFFIndex);
    467     }
    468     size_t dict_length = index.offsets[i] - index.offsets[i - 1];
    469     ots::Buffer table(data + index.offsets[i - 1], dict_length);
    470 
    471     std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands;
    472 
    473     FONT_FORMAT font_format = FORMAT_UNKNOWN;
    474     bool have_ros = false;
    475     size_t glyphs = 0;
    476     size_t charset_offset = 0;
    477 
    478     while (table.offset() < dict_length) {
    479       if (!ParseDictDataReadNext(&table, &operands)) {
    480         return OTS_FAILURE();
    481       }
    482       if (operands.empty()) {
    483         return OTS_FAILURE();
    484       }
    485       if (operands.size() > 48) {
    486         // An operator may be preceded by up to a maximum of 48 operands.
    487         return OTS_FAILURE();
    488       }
    489       if (operands.back().second != DICT_OPERATOR) continue;
    490 
    491       // got operator
    492       const uint32_t op = operands.back().first;
    493       operands.pop_back();
    494 
    495       switch (op) {
    496         // SID
    497         case 0:   // version
    498         case 1:   // Notice
    499         case 2:   // Copyright
    500         case 3:   // FullName
    501         case 4:   // FamilyName
    502         case (12U << 8) + 0:   // Copyright
    503         case (12U << 8) + 21:  // PostScript
    504         case (12U << 8) + 22:  // BaseFontName
    505         case (12U << 8) + 38:  // FontName
    506           if (operands.size() != 1) {
    507             return OTS_FAILURE();
    508           }
    509           if (!CheckSid(operands.back(), sid_max)) {
    510             return OTS_FAILURE();
    511           }
    512           break;
    513 
    514         // array
    515         case 5:   // FontBBox
    516         case 14:  // XUID
    517         case (12U << 8) + 7:   // FontMatrix
    518         case (12U << 8) + 23:  // BaseFontBlend (delta)
    519           if (operands.empty()) {
    520             return OTS_FAILURE();
    521           }
    522           break;
    523 
    524         // number
    525         case 13:  // UniqueID
    526         case (12U << 8) + 2:   // ItalicAngle
    527         case (12U << 8) + 3:   // UnderlinePosition
    528         case (12U << 8) + 4:   // UnderlineThickness
    529         case (12U << 8) + 5:   // PaintType
    530         case (12U << 8) + 8:   // StrokeWidth
    531         case (12U << 8) + 20:  // SyntheticBase
    532           if (operands.size() != 1) {
    533             return OTS_FAILURE();
    534           }
    535           break;
    536         case (12U << 8) + 31:  // CIDFontVersion
    537         case (12U << 8) + 32:  // CIDFontRevision
    538         case (12U << 8) + 33:  // CIDFontType
    539         case (12U << 8) + 34:  // CIDCount
    540         case (12U << 8) + 35:  // UIDBase
    541           if (operands.size() != 1) {
    542             return OTS_FAILURE();
    543           }
    544           if (font_format != FORMAT_CID_KEYED) {
    545             return OTS_FAILURE();
    546           }
    547           break;
    548         case (12U << 8) + 6:   // CharstringType
    549           if (operands.size() != 1) {
    550             return OTS_FAILURE();
    551           }
    552           if(operands.back().second != DICT_OPERAND_INTEGER) {
    553             return OTS_FAILURE();
    554           }
    555           if (operands.back().first != 2) {
    556             // We only support the "Type 2 Charstring Format."
    557             // TODO(yusukes): Support Type 1 format? Is that still in use?
    558             return OTS_FAILURE();
    559           }
    560           break;
    561 
    562         // boolean
    563         case (12U << 8) + 1:   // isFixedPitch
    564           if (operands.size() != 1) {
    565             return OTS_FAILURE();
    566           }
    567           if (operands.back().second != DICT_OPERAND_INTEGER) {
    568             return OTS_FAILURE();
    569           }
    570           if (operands.back().first >= 2) {
    571             return OTS_FAILURE();
    572           }
    573           break;
    574 
    575         // offset(0)
    576         case 15:  // charset
    577           if (operands.size() != 1) {
    578             return OTS_FAILURE();
    579           }
    580           if (operands.back().first <= 2) {
    581             // predefined charset, ISOAdobe, Expert or ExpertSubset, is used.
    582             break;
    583           }
    584           if (!CheckOffset(operands.back(), table_length)) {
    585             return OTS_FAILURE();
    586           }
    587           if (charset_offset) {
    588             return OTS_FAILURE();  // multiple charset tables?
    589           }
    590           charset_offset = operands.back().first;
    591           break;
    592 
    593         case 16: {  // Encoding
    594           if (operands.size() != 1) {
    595             return OTS_FAILURE();
    596           }
    597           if (operands.back().first <= 1) {
    598             break;  // predefined encoding, "Standard" or "Expert", is used.
    599           }
    600           if (!CheckOffset(operands.back(), table_length)) {
    601             return OTS_FAILURE();
    602           }
    603 
    604           // parse sub dictionary INDEX.
    605           ots::Buffer table(data, table_length);
    606           table.set_offset(operands.back().first);
    607           uint8_t format = 0;
    608           if (!table.ReadU8(&format)) {
    609             return OTS_FAILURE();
    610           }
    611           if (format & 0x80) {
    612             // supplemental encoding is not supported at the moment.
    613             return OTS_FAILURE();
    614           }
    615           // TODO(yusukes): support & parse supplemental encoding tables.
    616           break;
    617         }
    618 
    619         case 17: {  // CharStrings
    620           if (type != DICT_DATA_TOPLEVEL) {
    621             return OTS_FAILURE();
    622           }
    623           if (operands.size() != 1) {
    624             return OTS_FAILURE();
    625           }
    626           if (!CheckOffset(operands.back(), table_length)) {
    627             return OTS_FAILURE();
    628           }
    629           // parse "14. CharStrings INDEX"
    630           ots::Buffer table(data, table_length);
    631           table.set_offset(operands.back().first);
    632           ots::CFFIndex *charstring_index = out_cff->char_strings_array.back();
    633           if (!ParseIndex(&table, charstring_index)) {
    634             return OTS_FAILURE();
    635           }
    636           if (charstring_index->count < 2) {
    637             return OTS_FAILURE();
    638           }
    639           if (glyphs) {
    640             return OTS_FAILURE();  // multiple charstring tables?
    641           }
    642           glyphs = charstring_index->count;
    643           break;
    644         }
    645 
    646         case (12U << 8) + 36: {  // FDArray
    647           if (type != DICT_DATA_TOPLEVEL) {
    648             return OTS_FAILURE();
    649           }
    650           if (operands.size() != 1) {
    651             return OTS_FAILURE();
    652           }
    653           if (!CheckOffset(operands.back(), table_length)) {
    654             return OTS_FAILURE();
    655           }
    656 
    657           // parse sub dictionary INDEX.
    658           ots::Buffer table(data, table_length);
    659           table.set_offset(operands.back().first);
    660           ots::CFFIndex sub_dict_index;
    661           if (!ParseIndex(&table, &sub_dict_index)) {
    662             return OTS_FAILURE();
    663           }
    664           if (!ParseDictData(data, table_length,
    665                              sub_dict_index, sid_max, DICT_DATA_FDARRAY,
    666                              out_cff)) {
    667             return OTS_FAILURE();
    668           }
    669           if (out_cff->font_dict_length != 0) {
    670             return OTS_FAILURE();  // two or more FDArray found.
    671           }
    672           out_cff->font_dict_length = sub_dict_index.count;
    673           break;
    674         }
    675 
    676         case (12U << 8) + 37: {  // FDSelect
    677           if (type != DICT_DATA_TOPLEVEL) {
    678             return OTS_FAILURE();
    679           }
    680           if (operands.size() != 1) {
    681             return OTS_FAILURE();
    682           }
    683           if (!CheckOffset(operands.back(), table_length)) {
    684             return OTS_FAILURE();
    685           }
    686 
    687           // parse FDSelect data structure
    688           ots::Buffer table(data, table_length);
    689           table.set_offset(operands.back().first);
    690           uint8_t format = 0;
    691           if (!table.ReadU8(&format)) {
    692             return OTS_FAILURE();
    693           }
    694           if (format == 0) {
    695             for (size_t j = 0; j < glyphs; ++j) {
    696               uint8_t fd_index = 0;
    697               if (!table.ReadU8(&fd_index)) {
    698                 return OTS_FAILURE();
    699               }
    700               (out_cff->fd_select)[j] = fd_index;
    701             }
    702           } else if (format == 3) {
    703             uint16_t n_ranges = 0;
    704             if (!table.ReadU16(&n_ranges)) {
    705               return OTS_FAILURE();
    706             }
    707             if (n_ranges == 0) {
    708               return OTS_FAILURE();
    709             }
    710 
    711             uint16_t last_gid = 0;
    712             uint8_t fd_index = 0;
    713             for (unsigned j = 0; j < n_ranges; ++j) {
    714               uint16_t first = 0;  // GID
    715               if (!table.ReadU16(&first)) {
    716                 return OTS_FAILURE();
    717               }
    718 
    719               // Sanity checks.
    720               if ((j == 0) && (first != 0)) {
    721                 return OTS_FAILURE();
    722               }
    723               if ((j != 0) && (last_gid >= first)) {
    724                 return OTS_FAILURE();  // not increasing order.
    725               }
    726 
    727               // Copy the mapping to |out_cff->fd_select|.
    728               if (j != 0) {
    729                 for (uint16_t k = last_gid; k < first; ++k) {
    730                   if (!out_cff->fd_select.insert(
    731                           std::make_pair(k, fd_index)).second) {
    732                     return OTS_FAILURE();
    733                   }
    734                 }
    735               }
    736 
    737               if (!table.ReadU8(&fd_index)) {
    738                 return OTS_FAILURE();
    739               }
    740               last_gid = first;
    741               // TODO(yusukes): check GID?
    742             }
    743             uint16_t sentinel = 0;
    744             if (!table.ReadU16(&sentinel)) {
    745               return OTS_FAILURE();
    746             }
    747             if (last_gid >= sentinel) {
    748               return OTS_FAILURE();
    749             }
    750             for (uint16_t k = last_gid; k < sentinel; ++k) {
    751               if (!out_cff->fd_select.insert(
    752                       std::make_pair(k, fd_index)).second) {
    753                 return OTS_FAILURE();
    754               }
    755             }
    756           } else {
    757             // unknown format
    758             return OTS_FAILURE();
    759           }
    760           break;
    761         }
    762 
    763         // Private DICT (2 * number)
    764         case 18: {
    765           if (operands.size() != 2) {
    766             return OTS_FAILURE();
    767           }
    768           if (operands.back().second != DICT_OPERAND_INTEGER) {
    769             return OTS_FAILURE();
    770           }
    771           const uint32_t private_offset = operands.back().first;
    772           operands.pop_back();
    773           if (operands.back().second != DICT_OPERAND_INTEGER) {
    774             return OTS_FAILURE();
    775           }
    776           const uint32_t private_length = operands.back().first;
    777           if (private_offset > table_length) {
    778             return OTS_FAILURE();
    779           }
    780           if (private_length >= table_length) {
    781             return OTS_FAILURE();
    782           }
    783           if (private_length + private_offset > table_length) {
    784             return OTS_FAILURE();
    785           }
    786           // parse "15. Private DICT Data"
    787           if (!ParsePrivateDictData(data, table_length,
    788                                     private_offset, private_length,
    789                                     type, out_cff)) {
    790             return OTS_FAILURE();
    791           }
    792           break;
    793         }
    794 
    795         // ROS
    796         case (12U << 8) + 30:
    797           if (font_format != FORMAT_UNKNOWN) {
    798             return OTS_FAILURE();
    799           }
    800           font_format = FORMAT_CID_KEYED;
    801           if (operands.size() != 3) {
    802             return OTS_FAILURE();
    803           }
    804           // check SIDs
    805           operands.pop_back();  // ignore the first number.
    806           if (!CheckSid(operands.back(), sid_max)) {
    807             return OTS_FAILURE();
    808           }
    809           operands.pop_back();
    810           if (!CheckSid(operands.back(), sid_max)) {
    811             return OTS_FAILURE();
    812           }
    813           if (have_ros) {
    814             return OTS_FAILURE();  // multiple ROS tables?
    815           }
    816           have_ros = true;
    817           break;
    818 
    819         default:
    820           return OTS_FAILURE();
    821       }
    822       operands.clear();
    823 
    824       if (font_format == FORMAT_UNKNOWN) {
    825         font_format = FORMAT_OTHER;
    826       }
    827     }
    828 
    829     // parse "13. Charsets"
    830     if (charset_offset) {
    831       ots::Buffer table(data, table_length);
    832       table.set_offset(charset_offset);
    833       uint8_t format = 0;
    834       if (!table.ReadU8(&format)) {
    835         return OTS_FAILURE();
    836       }
    837       switch (format) {
    838         case 0:
    839           for (unsigned j = 1 /* .notdef is omitted */; j < glyphs; ++j) {
    840             uint16_t sid = 0;
    841             if (!table.ReadU16(&sid)) {
    842               return OTS_FAILURE();
    843             }
    844             if (!have_ros && (sid > sid_max)) {
    845               return OTS_FAILURE();
    846             }
    847             // TODO(yusukes): check CIDs when have_ros is true.
    848           }
    849           break;
    850 
    851         case 1:
    852         case 2: {
    853           uint32_t total = 1;  // .notdef is omitted.
    854           while (total < glyphs) {
    855             uint16_t sid = 0;
    856             if (!table.ReadU16(&sid)) {
    857               return OTS_FAILURE();
    858             }
    859             if (!have_ros && (sid > sid_max)) {
    860               return OTS_FAILURE();
    861             }
    862             // TODO(yusukes): check CIDs when have_ros is true.
    863 
    864             if (format == 1) {
    865               uint8_t left = 0;
    866               if (!table.ReadU8(&left)) {
    867                 return OTS_FAILURE();
    868               }
    869               total += (left + 1);
    870             } else {
    871               uint16_t left = 0;
    872               if (!table.ReadU16(&left)) {
    873                 return OTS_FAILURE();
    874               }
    875               total += (left + 1);
    876             }
    877           }
    878           break;
    879         }
    880 
    881         default:
    882           return OTS_FAILURE();
    883       }
    884     }
    885   }
    886   return true;
    887 }
    888 
    889 }  // namespace
    890 
    891 namespace ots {
    892 
    893 bool ots_cff_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
    894   Buffer table(data, length);
    895 
    896   file->cff = new OpenTypeCFF;
    897   file->cff->data = data;
    898   file->cff->length = length;
    899   file->cff->font_dict_length = 0;
    900   file->cff->local_subrs = NULL;
    901 
    902   // parse "6. Header" in the Adobe Compact Font Format Specification
    903   uint8_t major = 0;
    904   uint8_t minor = 0;
    905   uint8_t hdr_size = 0;
    906   uint8_t off_size = 0;
    907   if (!table.ReadU8(&major)) {
    908     return OTS_FAILURE();
    909   }
    910   if (!table.ReadU8(&minor)) {
    911     return OTS_FAILURE();
    912   }
    913   if (!table.ReadU8(&hdr_size)) {
    914     return OTS_FAILURE();
    915   }
    916   if (!table.ReadU8(&off_size)) {
    917     return OTS_FAILURE();
    918   }
    919   if ((off_size == 0) || (off_size > 4)) {
    920     return OTS_FAILURE();
    921   }
    922 
    923   if ((major != 1) ||
    924       (minor != 0) ||
    925       (hdr_size != 4)) {
    926     return OTS_FAILURE();
    927   }
    928   if (hdr_size >= length) {
    929     return OTS_FAILURE();
    930   }
    931 
    932   // parse "7. Name INDEX"
    933   table.set_offset(hdr_size);
    934   CFFIndex name_index;
    935   if (!ParseIndex(&table, &name_index)) {
    936     return OTS_FAILURE();
    937   }
    938   if (!ParseNameData(&table, name_index, &(file->cff->name))) {
    939     return OTS_FAILURE();
    940   }
    941 
    942   // parse "8. Top DICT INDEX"
    943   table.set_offset(name_index.offset_to_next);
    944   CFFIndex top_dict_index;
    945   if (!ParseIndex(&table, &top_dict_index)) {
    946     return OTS_FAILURE();
    947   }
    948   if (name_index.count != top_dict_index.count) {
    949     return OTS_FAILURE();
    950   }
    951 
    952   // parse "10. String INDEX"
    953   table.set_offset(top_dict_index.offset_to_next);
    954   CFFIndex string_index;
    955   if (!ParseIndex(&table, &string_index)) {
    956     return OTS_FAILURE();
    957   }
    958   if (string_index.count >= 65000 - kNStdString) {
    959     return OTS_FAILURE();
    960   }
    961 
    962   const size_t sid_max = string_index.count + kNStdString;
    963   // string_index.count == 0 is allowed.
    964 
    965   // parse "9. Top DICT Data"
    966   if (!ParseDictData(data, length, top_dict_index,
    967                      sid_max, DICT_DATA_TOPLEVEL, file->cff)) {
    968     return OTS_FAILURE();
    969   }
    970 
    971   // parse "16. Global Subrs INDEX"
    972   table.set_offset(string_index.offset_to_next);
    973   CFFIndex global_subrs_index;
    974   if (!ParseIndex(&table, &global_subrs_index)) {
    975     return OTS_FAILURE();
    976   }
    977 
    978   // Check if all fd_index in FDSelect are valid.
    979   std::map<uint16_t, uint8_t>::const_iterator iter;
    980   std::map<uint16_t, uint8_t>::const_iterator end = file->cff->fd_select.end();
    981   for (iter = file->cff->fd_select.begin(); iter != end; ++iter) {
    982     if (iter->second >= file->cff->font_dict_length) {
    983       return OTS_FAILURE();
    984     }
    985   }
    986 
    987   // Check if all charstrings (font hinting code for each glyph) are valid.
    988   for (size_t i = 0; i < file->cff->char_strings_array.size(); ++i) {
    989     if (!ValidateType2CharStringIndex(*(file->cff->char_strings_array.at(i)),
    990                                       global_subrs_index,
    991                                       file->cff->fd_select,
    992                                       file->cff->local_subrs_per_font,
    993                                       file->cff->local_subrs,
    994                                       &table)) {
    995       return OTS_FAILURE();
    996     }
    997   }
    998 
    999   return true;
   1000 }
   1001 
   1002 bool ots_cff_should_serialise(OpenTypeFile *file) {
   1003   return file->cff != NULL;
   1004 }
   1005 
   1006 bool ots_cff_serialise(OTSStream *out, OpenTypeFile *file) {
   1007   // TODO(yusukes): would be better to transcode the data,
   1008   //                rather than simple memcpy.
   1009   if (!out->Write(file->cff->data, file->cff->length)) {
   1010     return OTS_FAILURE();
   1011   }
   1012   return true;
   1013 }
   1014 
   1015 void ots_cff_free(OpenTypeFile *file) {
   1016   if (file->cff) {
   1017     for (size_t i = 0; i < file->cff->char_strings_array.size(); ++i) {
   1018       delete (file->cff->char_strings_array)[i];
   1019     }
   1020     for (size_t i = 0; i < file->cff->local_subrs_per_font.size(); ++i) {
   1021       delete (file->cff->local_subrs_per_font)[i];
   1022     }
   1023     delete file->cff->local_subrs;
   1024     delete file->cff;
   1025   }
   1026 }
   1027 
   1028 }  // namespace ots
   1029