• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ReadOffset(ots::Buffer * table,uint8_t off_size,uint32_t * offset)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 
ParseIndex(ots::Buffer * table,ots::CFFIndex * index)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 
ParseNameData(ots::Buffer * table,const ots::CFFIndex & index,std::string * out_name)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 
CheckOffset(const std::pair<uint32_t,DICT_OPERAND_TYPE> & operand,size_t table_length)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 
CheckSid(const std::pair<uint32_t,DICT_OPERAND_TYPE> & operand,size_t sid_max)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 
ParseDictDataBcd(ots::Buffer * table,std::vector<std::pair<uint32_t,DICT_OPERAND_TYPE>> * operands)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 
ParseDictDataEscapedOperator(ots::Buffer * table,std::vector<std::pair<uint32_t,DICT_OPERAND_TYPE>> * operands)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 
ParseDictDataNumber(ots::Buffer * table,uint8_t b0,std::vector<std::pair<uint32_t,DICT_OPERAND_TYPE>> * operands)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 
ParseDictDataReadNext(ots::Buffer * table,std::vector<std::pair<uint32_t,DICT_OPERAND_TYPE>> * operands)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 
ParsePrivateDictData(const uint8_t * data,size_t table_length,size_t offset,size_t dict_length,DICT_DATA_TYPE type,ots::OpenTypeCFF * out_cff)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 
ParseDictData(const uint8_t * data,size_t table_length,const ots::CFFIndex & index,size_t sid_max,DICT_DATA_TYPE type,ots::OpenTypeCFF * out_cff)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 
ots_cff_parse(OpenTypeFile * file,const uint8_t * data,size_t length)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 
ots_cff_should_serialise(OpenTypeFile * file)1002 bool ots_cff_should_serialise(OpenTypeFile *file) {
1003   return file->cff != NULL;
1004 }
1005 
ots_cff_serialise(OTSStream * out,OpenTypeFile * file)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 
ots_cff_free(OpenTypeFile * file)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