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