// Copyright (c) 2012-2017 The OTS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cff.h"

#include <cstring>
#include <utility>
#include <vector>

#include "maxp.h"
#include "cff_type2_charstring.h"

// CFF - PostScript font program (Compact Font Format) table
// http://www.microsoft.com/typography/otspec/cff.htm
// http://www.microsoft.com/typography/otspec/cffspec.htm

#define TABLE_NAME "CFF"

namespace {

enum DICT_OPERAND_TYPE {
  DICT_OPERAND_INTEGER,
  DICT_OPERAND_REAL,
  DICT_OPERATOR,
};

enum DICT_DATA_TYPE {
  DICT_DATA_TOPLEVEL,
  DICT_DATA_FDARRAY,
};

enum FONT_FORMAT {
  FORMAT_UNKNOWN,
  FORMAT_CID_KEYED,
  FORMAT_OTHER,  // Including synthetic fonts
};

// see Appendix. A
const size_t kNStdString = 390;

bool ReadOffset(ots::Buffer *table, uint8_t off_size, uint32_t *offset) {
  if (off_size > 4) {
    return OTS_FAILURE();
  }

  uint32_t tmp32 = 0;
  for (unsigned i = 0; i < off_size; ++i) {
    uint8_t tmp8 = 0;
    if (!table->ReadU8(&tmp8)) {
      return OTS_FAILURE();
    }
    tmp32 <<= 8;
    tmp32 += tmp8;
  }
  *offset = tmp32;
  return true;
}

bool ParseIndex(ots::Buffer *table, ots::CFFIndex *index) {
  index->off_size = 0;
  index->offsets.clear();

  if (!table->ReadU16(&(index->count))) {
    return OTS_FAILURE();
  }
  if (index->count == 0) {
    // An empty INDEX.
    index->offset_to_next = table->offset();
    return true;
  }

  if (!table->ReadU8(&(index->off_size))) {
    return OTS_FAILURE();
  }
  if ((index->off_size == 0) ||
      (index->off_size > 4)) {
    return OTS_FAILURE();
  }

  const size_t array_size = (index->count + 1) * index->off_size;
  // less than ((64k + 1) * 4), thus does not overflow.
  const size_t object_data_offset = table->offset() + array_size;
  // does not overflow too, since offset() <= 1GB.

  if (object_data_offset >= table->length()) {
    return OTS_FAILURE();
  }

  for (unsigned i = 0; i <= index->count; ++i) {  // '<=' is not a typo.
    uint32_t rel_offset = 0;
    if (!ReadOffset(table, index->off_size, &rel_offset)) {
      return OTS_FAILURE();
    }
    if (rel_offset < 1) {
      return OTS_FAILURE();
    }
    if (i == 0 && rel_offset != 1) {
      return OTS_FAILURE();
    }

    if (rel_offset > table->length()) {
      return OTS_FAILURE();
    }

    // does not underflow.
    if (object_data_offset > table->length() - (rel_offset - 1)) {
      return OTS_FAILURE();
    }

    index->offsets.push_back(
        object_data_offset + (rel_offset - 1));  // less than length(), 1GB.
  }

  for (unsigned i = 1; i < index->offsets.size(); ++i) {
    // We allow consecutive identical offsets here for zero-length strings.
    // See http://crbug.com/69341 for more details.
    if (index->offsets[i] < index->offsets[i - 1]) {
      return OTS_FAILURE();
    }
  }

  index->offset_to_next = index->offsets.back();
  return true;
}

bool ParseNameData(
    ots::Buffer *table, const ots::CFFIndex &index, std::string* out_name) {
  uint8_t name[256] = {0};
  if (index.offsets.size() == 0) {  // just in case.
    return OTS_FAILURE();
  }
  for (unsigned i = 1; i < index.offsets.size(); ++i) {
    const size_t length = index.offsets[i] - index.offsets[i - 1];
    // font names should be no longer than 127 characters.
    if (length > 127) {
      return OTS_FAILURE();
    }

    table->set_offset(index.offsets[i - 1]);
    if (!table->Read(name, length)) {
      return OTS_FAILURE();
    }

    for (size_t j = 0; j < length; ++j) {
      // setting the first byte to NUL is allowed.
      if (j == 0 && name[j] == 0) continue;
      // non-ASCII characters are not recommended (except the first character).
      if (name[j] < 33 || name[j] > 126) {
        return OTS_FAILURE();
      }
      // [, ], ... are not allowed.
      if (std::strchr("[](){}<>/% ", name[j])) {
        return OTS_FAILURE();
      }
    }
  }

  *out_name = reinterpret_cast<char *>(name);
  return true;
}

bool CheckOffset(const std::pair<uint32_t, DICT_OPERAND_TYPE>& operand,
                 size_t table_length) {
  if (operand.second != DICT_OPERAND_INTEGER) {
    return OTS_FAILURE();
  }
  if (operand.first >= table_length) {
    return OTS_FAILURE();
  }
  return true;
}

bool CheckSid(const std::pair<uint32_t, DICT_OPERAND_TYPE>& operand,
              size_t sid_max) {
  if (operand.second != DICT_OPERAND_INTEGER) {
    return OTS_FAILURE();
  }
  if (operand.first > sid_max) {
    return OTS_FAILURE();
  }
  return true;
}

bool ParseDictDataBcd(
    ots::Buffer *table,
    std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
  bool read_decimal_point = false;
  bool read_e = false;

  uint8_t nibble = 0;
  size_t count = 0;
  while (true) {
    if (!table->ReadU8(&nibble)) {
      return OTS_FAILURE();
    }
    if ((nibble & 0xf0) == 0xf0) {
      if ((nibble & 0xf) == 0xf) {
        // TODO(yusukes): would be better to store actual double value,
        // rather than the dummy integer.
        operands->push_back(std::make_pair(static_cast<uint32_t>(0),
                                           DICT_OPERAND_REAL));
        return true;
      }
      return OTS_FAILURE();
    }
    if ((nibble & 0x0f) == 0x0f) {
      operands->push_back(std::make_pair(static_cast<uint32_t>(0),
                                         DICT_OPERAND_REAL));
      return true;
    }

    // check number format
    uint8_t nibbles[2];
    nibbles[0] = (nibble & 0xf0) >> 8;
    nibbles[1] = (nibble & 0x0f);
    for (unsigned i = 0; i < 2; ++i) {
      if (nibbles[i] == 0xd) {  // reserved number
        return OTS_FAILURE();
      }
      if ((nibbles[i] == 0xe) &&  // minus
          ((count > 0) || (i > 0))) {
        return OTS_FAILURE();  // minus sign should be the first character.
      }
      if (nibbles[i] == 0xa) {  // decimal point
        if (!read_decimal_point) {
          read_decimal_point = true;
        } else {
          return OTS_FAILURE();  // two or more points.
        }
      }
      if ((nibbles[i] == 0xb) ||  // E+
          (nibbles[i] == 0xc)) {  // E-
        if (!read_e) {
          read_e = true;
        } else {
          return OTS_FAILURE();  // two or more E's.
        }
      }
    }
    ++count;
  }
}

bool ParseDictDataEscapedOperator(
    ots::Buffer *table,
    std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
  uint8_t op = 0;
  if (!table->ReadU8(&op)) {
    return OTS_FAILURE();
  }

  if ((op <= 14) ||
      (op >= 17 && op <= 23) ||
      (op >= 30 && op <= 38)) {
    operands->push_back(std::make_pair((12U << 8) + op, DICT_OPERATOR));
    return true;
  }

  // reserved area.
  return OTS_FAILURE();
}

bool ParseDictDataNumber(
    ots::Buffer *table, uint8_t b0,
    std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
  uint8_t b1 = 0;
  uint8_t b2 = 0;
  uint8_t b3 = 0;
  uint8_t b4 = 0;

  switch (b0) {
    case 28:  // shortint
      if (!table->ReadU8(&b1) ||
          !table->ReadU8(&b2)) {
        return OTS_FAILURE();
      }
      operands->push_back(std::make_pair(
          static_cast<uint32_t>((b1 << 8) + b2), DICT_OPERAND_INTEGER));
      return true;

    case 29:  // longint
      if (!table->ReadU8(&b1) ||
          !table->ReadU8(&b2) ||
          !table->ReadU8(&b3) ||
          !table->ReadU8(&b4)) {
        return OTS_FAILURE();
      }
      operands->push_back(std::make_pair(
          static_cast<uint32_t>((b1 << 24) + (b2 << 16) + (b3 << 8) + b4),
          DICT_OPERAND_INTEGER));
      return true;

    case 30:  // binary coded decimal
      return ParseDictDataBcd(table, operands);

    default:
      break;
  }

  uint32_t result;
  if (b0 >=32 && b0 <=246) {
    result = b0 - 139;
  } else if (b0 >=247 && b0 <= 250) {
    if (!table->ReadU8(&b1)) {
      return OTS_FAILURE();
    }
    result = (b0 - 247) * 256 + b1 + 108;
  } else if (b0 >= 251 && b0 <= 254) {
    if (!table->ReadU8(&b1)) {
      return OTS_FAILURE();
    }
    result = -(b0 - 251) * 256 + b1 - 108;
  } else {
    return OTS_FAILURE();
  }

  operands->push_back(std::make_pair(result, DICT_OPERAND_INTEGER));
  return true;
}

bool ParseDictDataReadNext(
    ots::Buffer *table,
    std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > *operands) {
  uint8_t op = 0;
  if (!table->ReadU8(&op)) {
    return OTS_FAILURE();
  }
  if (op <= 21) {
    if (op == 12) {
      return ParseDictDataEscapedOperator(table, operands);
    }
    operands->push_back(std::make_pair(
        static_cast<uint32_t>(op), DICT_OPERATOR));
    return true;
  } else if (op <= 27 || op == 31 || op == 255) {
    // reserved area.
    return OTS_FAILURE();
  }

  return ParseDictDataNumber(table, op, operands);
}

bool ParsePrivateDictData(
    const uint8_t *data,
    size_t table_length, size_t offset, size_t dict_length,
    DICT_DATA_TYPE type, ots::OpenTypeCFF *out_cff) {
  ots::Buffer table(data + offset, dict_length);
  std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands;

  // Since a Private DICT for FDArray might not have a Local Subr (e.g. Hiragino
  // Kaku Gothic Std W8), we create an empty Local Subr here to match the size
  // of FDArray the size of |local_subrs_per_font|.
  if (type == DICT_DATA_FDARRAY) {
    out_cff->local_subrs_per_font.push_back(new ots::CFFIndex);
  }

  while (table.offset() < dict_length) {
    if (!ParseDictDataReadNext(&table, &operands)) {
      return OTS_FAILURE();
    }
    if (operands.empty()) {
      return OTS_FAILURE();
    }
    if (operands.size() > 48) {
      // An operator may be preceded by up to a maximum of 48 operands.
      return OTS_FAILURE();
    }
    if (operands.back().second != DICT_OPERATOR) {
      continue;
    }

    // got operator
    const uint32_t op = operands.back().first;
    operands.pop_back();

    switch (op) {
      // hints
      case 6:  // BlueValues
      case 7:  // OtherBlues
      case 8:  // FamilyBlues
      case 9:  // FamilyOtherBlues
        if ((operands.size() % 2) != 0) {
          return OTS_FAILURE();
        }
        break;

      // array
      case (12U << 8) + 12:  // StemSnapH (delta)
      case (12U << 8) + 13:  // StemSnapV (delta)
        if (operands.empty()) {
          return OTS_FAILURE();
        }
        break;

      // number
      case 10:  // StdHW
      case 11:  // StdVW
      case 20:  // defaultWidthX
      case 21:  // nominalWidthX
      case (12U << 8) + 9:   // BlueScale
      case (12U << 8) + 10:  // BlueShift
      case (12U << 8) + 11:  // BlueFuzz
      case (12U << 8) + 17:  // LanguageGroup
      case (12U << 8) + 18:  // ExpansionFactor
      case (12U << 8) + 19:  // initialRandomSeed
        if (operands.size() != 1) {
          return OTS_FAILURE();
        }
        break;

      // Local Subrs INDEX, offset(self)
      case 19: {
        if (operands.size() != 1) {
          return OTS_FAILURE();
        }
        if (operands.back().second != DICT_OPERAND_INTEGER) {
          return OTS_FAILURE();
        }
        if (operands.back().first >= 1024 * 1024 * 1024) {
          return OTS_FAILURE();
        }
        if (operands.back().first + offset >= table_length) {
          return OTS_FAILURE();
        }
        // parse "16. Local Subrs INDEX"
        ots::Buffer cff_table(data, table_length);
        cff_table.set_offset(operands.back().first + offset);
        ots::CFFIndex *local_subrs_index = NULL;
        if (type == DICT_DATA_FDARRAY) {
          if (out_cff->local_subrs_per_font.empty()) {
            return OTS_FAILURE();  // not reached.
          }
          local_subrs_index = out_cff->local_subrs_per_font.back();
        } else { // type == DICT_DATA_TOPLEVEL
          if (out_cff->local_subrs) {
            return OTS_FAILURE();  // two or more local_subrs?
          }
          local_subrs_index = new ots::CFFIndex;
          out_cff->local_subrs = local_subrs_index;
        }
        if (!ParseIndex(&cff_table, local_subrs_index)) {
          return OTS_FAILURE();
        }
        break;
      }

      // boolean
      case (12U << 8) + 14:  // ForceBold
        if (operands.size() != 1) {
          return OTS_FAILURE();
        }
        if (operands.back().second != DICT_OPERAND_INTEGER) {
          return OTS_FAILURE();
        }
        if (operands.back().first >= 2) {
          return OTS_FAILURE();
        }
        break;

      default:
        return OTS_FAILURE();
    }
    operands.clear();
  }

  return true;
}

bool ParseDictData(const uint8_t *data, size_t table_length,
                   const ots::CFFIndex &index, uint16_t glyphs,
                   size_t sid_max, DICT_DATA_TYPE type,
                   ots::OpenTypeCFF *out_cff) {
  for (unsigned i = 1; i < index.offsets.size(); ++i) {
    if (type == DICT_DATA_TOPLEVEL) {
      out_cff->char_strings_array.push_back(new ots::CFFIndex);
    }
    size_t dict_length = index.offsets[i] - index.offsets[i - 1];
    ots::Buffer table(data + index.offsets[i - 1], dict_length);

    std::vector<std::pair<uint32_t, DICT_OPERAND_TYPE> > operands;

    FONT_FORMAT font_format = FORMAT_UNKNOWN;
    bool have_ros = false;
    uint16_t charstring_glyphs = 0;
    size_t charset_offset = 0;

    while (table.offset() < dict_length) {
      if (!ParseDictDataReadNext(&table, &operands)) {
        return OTS_FAILURE();
      }
      if (operands.empty()) {
        return OTS_FAILURE();
      }
      if (operands.size() > 48) {
        // An operator may be preceded by up to a maximum of 48 operands.
        return OTS_FAILURE();
      }
      if (operands.back().second != DICT_OPERATOR) continue;

      // got operator
      const uint32_t op = operands.back().first;
      operands.pop_back();

      switch (op) {
        // SID
        case 0:   // version
        case 1:   // Notice
        case 2:   // Copyright
        case 3:   // FullName
        case 4:   // FamilyName
        case (12U << 8) + 0:   // Copyright
        case (12U << 8) + 21:  // PostScript
        case (12U << 8) + 22:  // BaseFontName
        case (12U << 8) + 38:  // FontName
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (!CheckSid(operands.back(), sid_max)) {
            return OTS_FAILURE();
          }
          break;

        // array
        case 5:   // FontBBox
        case 14:  // XUID
        case (12U << 8) + 7:   // FontMatrix
        case (12U << 8) + 23:  // BaseFontBlend (delta)
          if (operands.empty()) {
            return OTS_FAILURE();
          }
          break;

        // number
        case 13:  // UniqueID
        case (12U << 8) + 2:   // ItalicAngle
        case (12U << 8) + 3:   // UnderlinePosition
        case (12U << 8) + 4:   // UnderlineThickness
        case (12U << 8) + 5:   // PaintType
        case (12U << 8) + 8:   // StrokeWidth
        case (12U << 8) + 20:  // SyntheticBase
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          break;
        case (12U << 8) + 31:  // CIDFontVersion
        case (12U << 8) + 32:  // CIDFontRevision
        case (12U << 8) + 33:  // CIDFontType
        case (12U << 8) + 34:  // CIDCount
        case (12U << 8) + 35:  // UIDBase
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (font_format != FORMAT_CID_KEYED) {
            return OTS_FAILURE();
          }
          break;
        case (12U << 8) + 6:   // CharstringType
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if(operands.back().second != DICT_OPERAND_INTEGER) {
            return OTS_FAILURE();
          }
          if (operands.back().first != 2) {
            // We only support the "Type 2 Charstring Format."
            // TODO(yusukes): Support Type 1 format? Is that still in use?
            return OTS_FAILURE();
          }
          break;

        // boolean
        case (12U << 8) + 1:   // isFixedPitch
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (operands.back().second != DICT_OPERAND_INTEGER) {
            return OTS_FAILURE();
          }
          if (operands.back().first >= 2) {
            return OTS_FAILURE();
          }
          break;

        // offset(0)
        case 15:  // charset
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (operands.back().first <= 2) {
            // predefined charset, ISOAdobe, Expert or ExpertSubset, is used.
            break;
          }
          if (!CheckOffset(operands.back(), table_length)) {
            return OTS_FAILURE();
          }
          if (charset_offset) {
            return OTS_FAILURE();  // multiple charset tables?
          }
          charset_offset = operands.back().first;
          break;

        case 16: {  // Encoding
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (operands.back().first <= 1) {
            break;  // predefined encoding, "Standard" or "Expert", is used.
          }
          if (!CheckOffset(operands.back(), table_length)) {
            return OTS_FAILURE();
          }

          // parse sub dictionary INDEX.
          ots::Buffer cff_table(data, table_length);
          cff_table.set_offset(operands.back().first);
          uint8_t format = 0;
          if (!cff_table.ReadU8(&format)) {
            return OTS_FAILURE();
          }
          if (format & 0x80) {
            // supplemental encoding is not supported at the moment.
            return OTS_FAILURE();
          }
          // TODO(yusukes): support & parse supplemental encoding tables.
          break;
        }

        case 17: {  // CharStrings
          if (type != DICT_DATA_TOPLEVEL) {
            return OTS_FAILURE();
          }
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (!CheckOffset(operands.back(), table_length)) {
            return OTS_FAILURE();
          }
          // parse "14. CharStrings INDEX"
          ots::Buffer cff_table(data, table_length);
          cff_table.set_offset(operands.back().first);
          ots::CFFIndex *charstring_index = out_cff->char_strings_array.back();
          if (!ParseIndex(&cff_table, charstring_index)) {
            return OTS_FAILURE();
          }
          if (charstring_index->count < 2) {
            return OTS_FAILURE();
          }
          if (charstring_glyphs) {
            return OTS_FAILURE();  // multiple charstring tables?
          }
          charstring_glyphs = charstring_index->count;
          if (charstring_glyphs != glyphs) {
            return OTS_FAILURE();  // CFF and maxp have different number of glyphs?
          }
          break;
        }

        case (12U << 8) + 36: {  // FDArray
          if (type != DICT_DATA_TOPLEVEL) {
            return OTS_FAILURE();
          }
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (!CheckOffset(operands.back(), table_length)) {
            return OTS_FAILURE();
          }

          // parse sub dictionary INDEX.
          ots::Buffer cff_table(data, table_length);
          cff_table.set_offset(operands.back().first);
          ots::CFFIndex sub_dict_index;
          if (!ParseIndex(&cff_table, &sub_dict_index)) {
            return OTS_FAILURE();
          }
          if (!ParseDictData(data, table_length,
                             sub_dict_index,
                             glyphs, sid_max, DICT_DATA_FDARRAY,
                             out_cff)) {
            return OTS_FAILURE();
          }
          if (out_cff->font_dict_length != 0) {
            return OTS_FAILURE();  // two or more FDArray found.
          }
          out_cff->font_dict_length = sub_dict_index.count;
          break;
        }

        case (12U << 8) + 37: {  // FDSelect
          if (type != DICT_DATA_TOPLEVEL) {
            return OTS_FAILURE();
          }
          if (operands.size() != 1) {
            return OTS_FAILURE();
          }
          if (!CheckOffset(operands.back(), table_length)) {
            return OTS_FAILURE();
          }

          // parse FDSelect data structure
          ots::Buffer cff_table(data, table_length);
          cff_table.set_offset(operands.back().first);
          uint8_t format = 0;
          if (!cff_table.ReadU8(&format)) {
            return OTS_FAILURE();
          }
          if (format == 0) {
            for (uint16_t j = 0; j < glyphs; ++j) {
              uint8_t fd_index = 0;
              if (!cff_table.ReadU8(&fd_index)) {
                return OTS_FAILURE();
              }
              (out_cff->fd_select)[j] = fd_index;
            }
          } else if (format == 3) {
            uint16_t n_ranges = 0;
            if (!cff_table.ReadU16(&n_ranges)) {
              return OTS_FAILURE();
            }
            if (n_ranges == 0) {
              return OTS_FAILURE();
            }

            uint16_t last_gid = 0;
            uint8_t fd_index = 0;
            for (unsigned j = 0; j < n_ranges; ++j) {
              uint16_t first = 0;  // GID
              if (!cff_table.ReadU16(&first)) {
                return OTS_FAILURE();
              }

              // Sanity checks.
              if ((j == 0) && (first != 0)) {
                return OTS_FAILURE();
              }
              if ((j != 0) && (last_gid >= first)) {
                return OTS_FAILURE();  // not increasing order.
              }

              // Copy the mapping to |out_cff->fd_select|.
              if (j != 0) {
                for (uint16_t k = last_gid; k < first; ++k) {
                  if (!out_cff->fd_select.insert(
                          std::make_pair(k, fd_index)).second) {
                    return OTS_FAILURE();
                  }
                }
              }

              if (!cff_table.ReadU8(&fd_index)) {
                return OTS_FAILURE();
              }
              last_gid = first;
              // TODO(yusukes): check GID?
            }
            uint16_t sentinel = 0;
            if (!cff_table.ReadU16(&sentinel)) {
              return OTS_FAILURE();
            }
            if (last_gid >= sentinel) {
              return OTS_FAILURE();
            }
            for (uint16_t k = last_gid; k < sentinel; ++k) {
              if (!out_cff->fd_select.insert(
                      std::make_pair(k, fd_index)).second) {
                return OTS_FAILURE();
              }
            }
          } else {
            // unknown format
            return OTS_FAILURE();
          }
          break;
        }

        // Private DICT (2 * number)
        case 18: {
          if (operands.size() != 2) {
            return OTS_FAILURE();
          }
          if (operands.back().second != DICT_OPERAND_INTEGER) {
            return OTS_FAILURE();
          }
          const uint32_t private_offset = operands.back().first;
          operands.pop_back();
          if (operands.back().second != DICT_OPERAND_INTEGER) {
            return OTS_FAILURE();
          }
          const uint32_t private_length = operands.back().first;
          if (private_offset > table_length) {
            return OTS_FAILURE();
          }
          if (private_length >= table_length) {
            return OTS_FAILURE();
          }
          if (private_length + private_offset > table_length) {
            return OTS_FAILURE();
          }
          // parse "15. Private DICT Data"
          if (!ParsePrivateDictData(data, table_length,
                                    private_offset, private_length,
                                    type, out_cff)) {
            return OTS_FAILURE();
          }
          break;
        }

        // ROS
        case (12U << 8) + 30:
          if (font_format != FORMAT_UNKNOWN) {
            return OTS_FAILURE();
          }
          font_format = FORMAT_CID_KEYED;
          if (operands.size() != 3) {
            return OTS_FAILURE();
          }
          // check SIDs
          operands.pop_back();  // ignore the first number.
          if (!CheckSid(operands.back(), sid_max)) {
            return OTS_FAILURE();
          }
          operands.pop_back();
          if (!CheckSid(operands.back(), sid_max)) {
            return OTS_FAILURE();
          }
          if (have_ros) {
            return OTS_FAILURE();  // multiple ROS tables?
          }
          have_ros = true;
          break;

        default:
          return OTS_FAILURE();
      }
      operands.clear();

      if (font_format == FORMAT_UNKNOWN) {
        font_format = FORMAT_OTHER;
      }
    }

    // parse "13. Charsets"
    if (charset_offset) {
      ots::Buffer cff_table(data, table_length);
      cff_table.set_offset(charset_offset);
      uint8_t format = 0;
      if (!cff_table.ReadU8(&format)) {
        return OTS_FAILURE();
      }
      switch (format) {
        case 0:
          for (uint16_t j = 1 /* .notdef is omitted */; j < glyphs; ++j) {
            uint16_t sid = 0;
            if (!cff_table.ReadU16(&sid)) {
              return OTS_FAILURE();
            }
            if (!have_ros && (sid > sid_max)) {
              return OTS_FAILURE();
            }
            // TODO(yusukes): check CIDs when have_ros is true.
          }
          break;

        case 1:
        case 2: {
          uint32_t total = 1;  // .notdef is omitted.
          while (total < glyphs) {
            uint16_t sid = 0;
            if (!cff_table.ReadU16(&sid)) {
              return OTS_FAILURE();
            }
            if (!have_ros && (sid > sid_max)) {
              return OTS_FAILURE();
            }
            // TODO(yusukes): check CIDs when have_ros is true.

            if (format == 1) {
              uint8_t left = 0;
              if (!cff_table.ReadU8(&left)) {
                return OTS_FAILURE();
              }
              total += (left + 1);
            } else {
              uint16_t left = 0;
              if (!cff_table.ReadU16(&left)) {
                return OTS_FAILURE();
              }
              total += (left + 1);
            }
          }
          break;
        }

        default:
          return OTS_FAILURE();
      }
    }
  }
  return true;
}

}  // namespace

namespace ots {

bool OpenTypeCFF::Parse(const uint8_t *data, size_t length) {
  Buffer table(data, length);

  Font *font = GetFont();

  this->m_data = data;
  this->m_length = length;

  // parse "6. Header" in the Adobe Compact Font Format Specification
  uint8_t major = 0;
  uint8_t minor = 0;
  uint8_t hdr_size = 0;
  uint8_t off_size = 0;
  if (!table.ReadU8(&major)) {
    return OTS_FAILURE();
  }
  if (!table.ReadU8(&minor)) {
    return OTS_FAILURE();
  }
  if (!table.ReadU8(&hdr_size)) {
    return OTS_FAILURE();
  }
  if (!table.ReadU8(&off_size)) {
    return OTS_FAILURE();
  }
  if ((off_size == 0) || (off_size > 4)) {
    return OTS_FAILURE();
  }

  if ((major != 1) ||
      (minor != 0) ||
      (hdr_size != 4)) {
    return OTS_FAILURE();
  }
  if (hdr_size >= length) {
    return OTS_FAILURE();
  }

  // parse "7. Name INDEX"
  table.set_offset(hdr_size);
  CFFIndex name_index;
  if (!ParseIndex(&table, &name_index)) {
    return OTS_FAILURE();
  }
  if (!ParseNameData(&table, name_index, &(this->name))) {
    return OTS_FAILURE();
  }

  // parse "8. Top DICT INDEX"
  table.set_offset(name_index.offset_to_next);
  CFFIndex top_dict_index;
  if (!ParseIndex(&table, &top_dict_index)) {
    return OTS_FAILURE();
  }
  if (name_index.count != top_dict_index.count) {
    return OTS_FAILURE();
  }

  // parse "10. String INDEX"
  table.set_offset(top_dict_index.offset_to_next);
  CFFIndex string_index;
  if (!ParseIndex(&table, &string_index)) {
    return OTS_FAILURE();
  }
  if (string_index.count >= 65000 - kNStdString) {
    return OTS_FAILURE();
  }

  OpenTypeMAXP *maxp = static_cast<OpenTypeMAXP*>(
    GetFont()->GetTypedTable(OTS_TAG_MAXP));
  if (!maxp) {
    return Error("Required maxp table missing");
  }
  const uint16_t num_glyphs = maxp->num_glyphs;
  const size_t sid_max = string_index.count + kNStdString;
  // string_index.count == 0 is allowed.

  // parse "9. Top DICT Data"
  if (!ParseDictData(data, length, top_dict_index,
                     num_glyphs, sid_max,
                     DICT_DATA_TOPLEVEL, this)) {
    return OTS_FAILURE();
  }

  // parse "16. Global Subrs INDEX"
  table.set_offset(string_index.offset_to_next);
  CFFIndex global_subrs_index;
  if (!ParseIndex(&table, &global_subrs_index)) {
    return OTS_FAILURE();
  }

  // Check if all fd_index in FDSelect are valid.
  std::map<uint16_t, uint8_t>::const_iterator iter;
  std::map<uint16_t, uint8_t>::const_iterator end = this->fd_select.end();
  for (iter = this->fd_select.begin(); iter != end; ++iter) {
    if (iter->second >= this->font_dict_length) {
      return OTS_FAILURE();
    }
  }

  // Check if all charstrings (font hinting code for each glyph) are valid.
  for (size_t i = 0; i < this->char_strings_array.size(); ++i) {
    if (!ValidateType2CharStringIndex(font,
                                      *(this->char_strings_array.at(i)),
                                      global_subrs_index,
                                      this->fd_select,
                                      this->local_subrs_per_font,
                                      this->local_subrs,
                                      &table)) {
      return Error("Failed validating charstring set %d", (int) i);
    }
  }

  return true;
}

bool OpenTypeCFF::Serialize(OTSStream *out) {
  if (!out->Write(this->m_data, this->m_length)) {
    return Error("Failed to write table");
  }
  return true;
}

OpenTypeCFF::~OpenTypeCFF() {
  for (size_t i = 0; i < this->char_strings_array.size(); ++i) {
    delete (this->char_strings_array)[i];
  }
  for (size_t i = 0; i < this->local_subrs_per_font.size(); ++i) {
    delete (this->local_subrs_per_font)[i];
  }
  delete this->local_subrs;
}

}  // namespace ots

#undef TABLE_NAME
