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
17namespace {
18
19enum DICT_OPERAND_TYPE {
20  DICT_OPERAND_INTEGER,
21  DICT_OPERAND_REAL,
22  DICT_OPERATOR,
23};
24
25enum DICT_DATA_TYPE {
26  DICT_DATA_TOPLEVEL,
27  DICT_DATA_FDARRAY,
28};
29
30enum FONT_FORMAT {
31  FORMAT_UNKNOWN,
32  FORMAT_CID_KEYED,
33  FORMAT_OTHER,  // Including synthetic fonts
34};
35
36// see Appendix. A
37const size_t kNStdString = 390;
38
39bool 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
57bool 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
124bool 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
160bool 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
171bool 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
182bool 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
242bool 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
261bool 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
319bool 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
341bool 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
461bool 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
891namespace ots {
892
893bool 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
1002bool ots_cff_should_serialise(OpenTypeFile *file) {
1003  return file->cff != NULL;
1004}
1005
1006bool 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
1015void 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