1 // Copyright (c) 2012-2017 The OTS 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_charstring.h"
13 #include "variations.h"
14 
15 // CFF - PostScript font program (Compact Font Format) table
16 // http://www.microsoft.com/typography/otspec/cff.htm
17 // http://www.microsoft.com/typography/otspec/cffspec.htm
18 
19 #define TABLE_NAME "CFF"
20 
21 namespace {
22 
23 enum DICT_OPERAND_TYPE {
24   DICT_OPERAND_INTEGER,
25   DICT_OPERAND_REAL,
26   DICT_OPERATOR,
27 };
28 
29 enum DICT_DATA_TYPE {
30   DICT_DATA_TOPLEVEL,
31   DICT_DATA_FDARRAY,
32   DICT_DATA_PRIVATE,
33 };
34 
35 enum FONT_FORMAT {
36   FORMAT_UNKNOWN,
37   FORMAT_CID_KEYED,
38   FORMAT_OTHER,  // Including synthetic fonts
39 };
40 
41 // see Appendix. A
42 const size_t kNStdString = 390;
43 
44 typedef std::pair<uint32_t, DICT_OPERAND_TYPE> Operand;
45 
ReadOffset(ots::Buffer & table,uint8_t off_size,uint32_t * offset)46 bool ReadOffset(ots::Buffer &table, uint8_t off_size, uint32_t *offset) {
47   if (off_size > 4) {
48     return OTS_FAILURE();
49   }
50 
51   uint32_t tmp32 = 0;
52   for (unsigned i = 0; i < off_size; ++i) {
53     uint8_t tmp8 = 0;
54     if (!table.ReadU8(&tmp8)) {
55       return OTS_FAILURE();
56     }
57     tmp32 <<= 8;
58     tmp32 += tmp8;
59   }
60   *offset = tmp32;
61   return true;
62 }
63 
ParseIndex(ots::Buffer & table,ots::CFFIndex & index,bool cff2=false)64 bool ParseIndex(ots::Buffer &table, ots::CFFIndex &index, bool cff2 = false) {
65   index.off_size = 0;
66   index.offsets.clear();
67 
68   if (cff2) {
69     if (!table.ReadU32(&(index.count))) {
70       return OTS_FAILURE();
71     }
72   } else {
73     uint16_t count;
74     if (!table.ReadU16(&count)) {
75       return OTS_FAILURE();
76     }
77     index.count = count;
78   }
79 
80   if (index.count == 0) {
81     // An empty INDEX.
82     index.offset_to_next = table.offset();
83     return true;
84   }
85 
86   if (!table.ReadU8(&(index.off_size))) {
87     return OTS_FAILURE();
88   }
89   if (index.off_size < 1 || index.off_size > 4) {
90     return OTS_FAILURE();
91   }
92 
93   const size_t array_size = (index.count + 1) * index.off_size;
94   // less than ((64k + 1) * 4), thus does not overflow.
95   const size_t object_data_offset = table.offset() + array_size;
96   // does not overflow too, since offset() <= 1GB.
97 
98   if (object_data_offset >= table.length()) {
99     return OTS_FAILURE();
100   }
101 
102   for (unsigned i = 0; i <= index.count; ++i) {  // '<=' is not a typo.
103     uint32_t rel_offset = 0;
104     if (!ReadOffset(table, index.off_size, &rel_offset)) {
105       return OTS_FAILURE();
106     }
107     if (rel_offset < 1) {
108       return OTS_FAILURE();
109     }
110     if (i == 0 && rel_offset != 1) {
111       return OTS_FAILURE();
112     }
113 
114     if (rel_offset > table.length()) {
115       return OTS_FAILURE();
116     }
117 
118     // does not underflow.
119     if (object_data_offset > table.length() - (rel_offset - 1)) {
120       return OTS_FAILURE();
121     }
122 
123     index.offsets.push_back(
124         object_data_offset + (rel_offset - 1));  // less than length(), 1GB.
125   }
126 
127   for (unsigned i = 1; i < index.offsets.size(); ++i) {
128     // We allow consecutive identical offsets here for zero-length strings.
129     // See http://crbug.com/69341 for more details.
130     if (index.offsets[i] < index.offsets[i - 1]) {
131       return OTS_FAILURE();
132     }
133   }
134 
135   index.offset_to_next = index.offsets.back();
136   return true;
137 }
138 
ParseNameData(ots::Buffer * table,const ots::CFFIndex & index,std::string * out_name)139 bool ParseNameData(
140     ots::Buffer *table, const ots::CFFIndex &index, std::string* out_name) {
141   uint8_t name[256] = {0};
142 
143   const size_t length = index.offsets[1] - index.offsets[0];
144   // font names should be no longer than 127 characters.
145   if (length > 127) {
146     return OTS_FAILURE();
147   }
148 
149   table->set_offset(index.offsets[0]);
150   if (!table->Read(name, length)) {
151     return OTS_FAILURE();
152   }
153 
154   for (size_t i = 0; i < length; ++i) {
155     // setting the first byte to NUL is allowed.
156     if (i == 0 && name[i] == 0) continue;
157     // non-ASCII characters are not recommended (except the first character).
158     if (name[i] < 33 || name[i] > 126) {
159       return OTS_FAILURE();
160     }
161     // [, ], ... are not allowed.
162     if (std::strchr("[](){}<>/% ", name[i])) {
163       return OTS_FAILURE();
164     }
165   }
166 
167   *out_name = reinterpret_cast<char *>(name);
168   return true;
169 }
170 
CheckOffset(const Operand & operand,size_t table_length)171 bool CheckOffset(const Operand& operand, size_t table_length) {
172   if (operand.second != DICT_OPERAND_INTEGER) {
173     return OTS_FAILURE();
174   }
175   if (operand.first >= table_length) {
176     return OTS_FAILURE();
177   }
178   return true;
179 }
180 
CheckSid(const Operand & operand,size_t sid_max)181 bool CheckSid(const Operand& operand, size_t sid_max) {
182   if (operand.second != DICT_OPERAND_INTEGER) {
183     return OTS_FAILURE();
184   }
185   if (operand.first > sid_max) {
186     return OTS_FAILURE();
187   }
188   return true;
189 }
190 
ParseDictDataBcd(ots::Buffer & table,std::vector<Operand> & operands)191 bool ParseDictDataBcd(ots::Buffer &table, std::vector<Operand> &operands) {
192   bool read_decimal_point = false;
193   bool read_e = false;
194 
195   uint8_t nibble = 0;
196   size_t count = 0;
197   while (true) {
198     if (!table.ReadU8(&nibble)) {
199       return OTS_FAILURE();
200     }
201     if ((nibble & 0xf0) == 0xf0) {
202       if ((nibble & 0xf) == 0xf) {
203         // TODO(yusukes): would be better to store actual double value,
204         // rather than the dummy integer.
205         operands.push_back(std::make_pair(static_cast<uint32_t>(0),
206                                            DICT_OPERAND_REAL));
207         return true;
208       }
209       return OTS_FAILURE();
210     }
211     if ((nibble & 0x0f) == 0x0f) {
212       operands.push_back(std::make_pair(static_cast<uint32_t>(0),
213                                          DICT_OPERAND_REAL));
214       return true;
215     }
216 
217     // check number format
218     uint8_t nibbles[2];
219     nibbles[0] = (nibble & 0xf0) >> 8;
220     nibbles[1] = (nibble & 0x0f);
221     for (unsigned i = 0; i < 2; ++i) {
222       if (nibbles[i] == 0xd) {  // reserved number
223         return OTS_FAILURE();
224       }
225       if ((nibbles[i] == 0xe) &&  // minus
226           ((count > 0) || (i > 0))) {
227         return OTS_FAILURE();  // minus sign should be the first character.
228       }
229       if (nibbles[i] == 0xa) {  // decimal point
230         if (!read_decimal_point) {
231           read_decimal_point = true;
232         } else {
233           return OTS_FAILURE();  // two or more points.
234         }
235       }
236       if ((nibbles[i] == 0xb) ||  // E+
237           (nibbles[i] == 0xc)) {  // E-
238         if (!read_e) {
239           read_e = true;
240         } else {
241           return OTS_FAILURE();  // two or more E's.
242         }
243       }
244     }
245     ++count;
246   }
247 }
248 
ParseDictDataEscapedOperator(ots::Buffer & table,std::vector<Operand> & operands)249 bool ParseDictDataEscapedOperator(ots::Buffer &table,
250                                   std::vector<Operand> &operands) {
251   uint8_t op = 0;
252   if (!table.ReadU8(&op)) {
253     return OTS_FAILURE();
254   }
255 
256   if ((op <= 14) ||
257       (op >= 17 && op <= 23) ||
258       (op >= 30 && op <= 38)) {
259     operands.push_back(std::make_pair((12U << 8) + op, DICT_OPERATOR));
260     return true;
261   }
262 
263   // reserved area.
264   return OTS_FAILURE();
265 }
266 
ParseDictDataNumber(ots::Buffer & table,uint8_t b0,std::vector<Operand> & operands)267 bool ParseDictDataNumber(ots::Buffer &table, uint8_t b0,
268                          std::vector<Operand> &operands) {
269   uint8_t b1 = 0;
270   uint8_t b2 = 0;
271   uint8_t b3 = 0;
272   uint8_t b4 = 0;
273 
274   switch (b0) {
275     case 28:  // shortint
276       if (!table.ReadU8(&b1) ||
277           !table.ReadU8(&b2)) {
278         return OTS_FAILURE();
279       }
280       operands.push_back(std::make_pair(
281           static_cast<uint32_t>((b1 << 8) + b2), DICT_OPERAND_INTEGER));
282       return true;
283 
284     case 29:  // longint
285       if (!table.ReadU8(&b1) ||
286           !table.ReadU8(&b2) ||
287           !table.ReadU8(&b3) ||
288           !table.ReadU8(&b4)) {
289         return OTS_FAILURE();
290       }
291       operands.push_back(std::make_pair(
292           static_cast<uint32_t>((b1 << 24) + (b2 << 16) + (b3 << 8) + b4),
293           DICT_OPERAND_INTEGER));
294       return true;
295 
296     case 30:  // binary coded decimal
297       return ParseDictDataBcd(table, operands);
298 
299     default:
300       break;
301   }
302 
303   uint32_t result;
304   if (b0 >=32 && b0 <=246) {
305     result = b0 - 139;
306   } else if (b0 >=247 && b0 <= 250) {
307     if (!table.ReadU8(&b1)) {
308       return OTS_FAILURE();
309     }
310     result = (b0 - 247) * 256 + b1 + 108;
311   } else if (b0 >= 251 && b0 <= 254) {
312     if (!table.ReadU8(&b1)) {
313       return OTS_FAILURE();
314     }
315     result = -(b0 - 251) * 256 + b1 - 108;
316   } else {
317     return OTS_FAILURE();
318   }
319 
320   operands.push_back(std::make_pair(result, DICT_OPERAND_INTEGER));
321   return true;
322 }
323 
ParseDictDataReadNext(ots::Buffer & table,std::vector<Operand> & operands)324 bool ParseDictDataReadNext(ots::Buffer &table,
325                            std::vector<Operand> &operands) {
326   uint8_t op = 0;
327   if (!table.ReadU8(&op)) {
328     return OTS_FAILURE();
329   }
330   if (op <= 24) {
331     if (op == 12) {
332       return ParseDictDataEscapedOperator(table, operands);
333     }
334     operands.push_back(std::make_pair(
335         static_cast<uint32_t>(op), DICT_OPERATOR));
336     return true;
337   } else if (op <= 27 || op == 31 || op == 255) {
338     // reserved area.
339     return OTS_FAILURE();
340   }
341 
342   return ParseDictDataNumber(table, op, operands);
343 }
344 
OperandsOverflow(std::vector<Operand> & operands,bool cff2)345 bool OperandsOverflow(std::vector<Operand>& operands, bool cff2) {
346   // An operator may be preceded by up to a maximum of 48 operands in CFF1 and
347   // 513 operands in CFF2.
348   if ((cff2 && operands.size() > ots::kMaxCFF2ArgumentStack) ||
349       (!cff2 && operands.size() > ots::kMaxCFF1ArgumentStack)) {
350     return true;
351   }
352   return false;
353 }
354 
ParseDictDataReadOperands(ots::Buffer & dict,std::vector<Operand> & operands,bool cff2)355 bool ParseDictDataReadOperands(ots::Buffer& dict,
356                                std::vector<Operand>& operands,
357                                bool cff2) {
358   if (!ParseDictDataReadNext(dict, operands)) {
359     return OTS_FAILURE();
360   }
361   if (operands.empty()) {
362     return OTS_FAILURE();
363   }
364   if (OperandsOverflow(operands, cff2)) {
365     return OTS_FAILURE();
366   }
367   return true;
368 }
369 
ValidCFF2DictOp(uint32_t op,DICT_DATA_TYPE type)370 bool ValidCFF2DictOp(uint32_t op, DICT_DATA_TYPE type) {
371   if (type == DICT_DATA_TOPLEVEL) {
372     switch (op) {
373       case (12U << 8) + 7:  // FontMatrix
374       case 17:              // CharStrings
375       case (12U << 8) + 36: // FDArray
376       case (12U << 8) + 37: // FDSelect
377       case 24:              // vstore
378         return true;
379       default:
380         return false;
381     }
382   } else if (type == DICT_DATA_FDARRAY) {
383     if (op == 18) // Private DICT
384       return true;
385   } else if (type == DICT_DATA_PRIVATE) {
386     switch (op) {
387       case (12U << 8) + 14: // ForceBold
388       case (12U << 8) + 19: // initialRandomSeed
389       case 20:              // defaultWidthX
390       case 21:              // nominalWidthX
391         return false;
392       default:
393         return true;
394     }
395   }
396 
397   return false;
398 }
399 
ParsePrivateDictData(ots::Buffer & table,size_t offset,size_t dict_length,DICT_DATA_TYPE type,ots::OpenTypeCFF * out_cff)400 bool ParsePrivateDictData(
401     ots::Buffer &table, size_t offset, size_t dict_length,
402     DICT_DATA_TYPE type, ots::OpenTypeCFF *out_cff) {
403   ots::Buffer dict(table.buffer() + offset, dict_length);
404   std::vector<Operand> operands;
405   bool cff2 = (out_cff->major == 2);
406   bool blend_seen = false;
407   uint32_t vsindex = 0;
408 
409   // Since a Private DICT for FDArray might not have a Local Subr (e.g. Hiragino
410   // Kaku Gothic Std W8), we create an empty Local Subr here to match the size
411   // of FDArray the size of |local_subrs_per_font|.
412   if (type == DICT_DATA_FDARRAY) {
413     out_cff->local_subrs_per_font.push_back(new ots::CFFIndex);
414   }
415 
416   while (dict.offset() < dict.length()) {
417     if (!ParseDictDataReadOperands(dict, operands, cff2)) {
418       return OTS_FAILURE();
419     }
420     if (operands.back().second != DICT_OPERATOR) {
421       continue;
422     }
423 
424     // got operator
425     const uint32_t op = operands.back().first;
426     operands.pop_back();
427 
428     if (cff2 && !ValidCFF2DictOp(op, DICT_DATA_PRIVATE)) {
429       return OTS_FAILURE();
430     }
431 
432     bool clear_operands = true;
433     switch (op) {
434       // hints
435       case 6:  // BlueValues
436       case 7:  // OtherBlues
437       case 8:  // FamilyBlues
438       case 9:  // FamilyOtherBlues
439         if ((operands.size() % 2) != 0) {
440           return OTS_FAILURE();
441         }
442         break;
443 
444       // array
445       case (12U << 8) + 12:  // StemSnapH (delta)
446       case (12U << 8) + 13:  // StemSnapV (delta)
447         if (operands.empty()) {
448           return OTS_FAILURE();
449         }
450         break;
451 
452       // number
453       case 10:  // StdHW
454       case 11:  // StdVW
455       case 20:  // defaultWidthX
456       case 21:  // nominalWidthX
457       case (12U << 8) + 9:   // BlueScale
458       case (12U << 8) + 10:  // BlueShift
459       case (12U << 8) + 11:  // BlueFuzz
460       case (12U << 8) + 17:  // LanguageGroup
461       case (12U << 8) + 18:  // ExpansionFactor
462       case (12U << 8) + 19:  // initialRandomSeed
463         if (operands.size() != 1) {
464           return OTS_FAILURE();
465         }
466         break;
467 
468       // Local Subrs INDEX, offset(self)
469       case 19: {
470         if (operands.size() != 1) {
471           return OTS_FAILURE();
472         }
473         if (operands.back().second != DICT_OPERAND_INTEGER) {
474           return OTS_FAILURE();
475         }
476         if (operands.back().first >= 1024 * 1024 * 1024) {
477           return OTS_FAILURE();
478         }
479         if (operands.back().first + offset >= table.length()) {
480           return OTS_FAILURE();
481         }
482         // parse "16. Local Subrs INDEX"
483         table.set_offset(operands.back().first + offset);
484         ots::CFFIndex *local_subrs_index = NULL;
485         if (type == DICT_DATA_FDARRAY) {
486           if (out_cff->local_subrs_per_font.empty()) {
487             return OTS_FAILURE();  // not reached.
488           }
489           local_subrs_index = out_cff->local_subrs_per_font.back();
490         } else { // type == DICT_DATA_TOPLEVEL
491           if (out_cff->local_subrs) {
492             return OTS_FAILURE();  // two or more local_subrs?
493           }
494           local_subrs_index = new ots::CFFIndex;
495           out_cff->local_subrs = local_subrs_index;
496         }
497         if (!ParseIndex(table, *local_subrs_index, cff2)) {
498           return OTS_FAILURE();
499         }
500         break;
501       }
502 
503       // boolean
504       case (12U << 8) + 14:  // ForceBold
505         if (operands.size() != 1) {
506           return OTS_FAILURE();
507         }
508         if (operands.back().second != DICT_OPERAND_INTEGER) {
509           return OTS_FAILURE();
510         }
511         if (operands.back().first >= 2) {
512           return OTS_FAILURE();
513         }
514         break;
515 
516       case 22: { // vsindex
517         if (!cff2) {
518           return OTS_FAILURE();
519         }
520         if (operands.size() != 1) {
521           return OTS_FAILURE();
522         }
523         if (operands.back().second != DICT_OPERAND_INTEGER) {
524           return OTS_FAILURE();
525         }
526         if (blend_seen) {
527           return OTS_FAILURE();
528         }
529         vsindex = operands.back().first;
530         if (vsindex >= out_cff->region_index_count.size()) {
531           return OTS_FAILURE();
532         }
533         break;
534       }
535 
536       case 23: { // blend
537         if (!cff2) {
538           return OTS_FAILURE();
539         }
540         if (operands.size() < 1) {
541           return OTS_FAILURE();
542         }
543         if (vsindex >= out_cff->region_index_count.size()) {
544           return OTS_FAILURE();
545         }
546         uint16_t k = out_cff->region_index_count.at(vsindex);
547         uint16_t n = operands.back().first;
548         if (operands.size() < n * (k + 1) + 1) {
549           return OTS_FAILURE();
550         }
551         size_t operands_size = operands.size();
552         // Keep the 1st n operands on the stack for the next operator to use
553         // and pop the rest. There can be multiple consecutive blend operator,
554         // so this makes sure the operands of all of them are kept on the
555         // stack.
556         while (operands.size() > operands_size - ((n * k) + 1))
557           operands.pop_back();
558         clear_operands = false;
559         blend_seen = true;
560         break;
561       }
562 
563       default:
564         return OTS_FAILURE();
565     }
566     if (clear_operands) {
567       operands.clear();
568     }
569   }
570 
571   return true;
572 }
573 
ParseVariationStore(ots::OpenTypeCFF & out_cff,ots::Buffer & table)574 bool ParseVariationStore(ots::OpenTypeCFF& out_cff, ots::Buffer& table) {
575   uint16_t length;
576 
577   if (!table.ReadU16(&length)) {
578     return OTS_FAILURE();
579   }
580 
581   // Empty VariationStore is allowed.
582   if (!length) {
583     return true;
584   }
585 
586   if (length > table.remaining()) {
587     return OTS_FAILURE();
588   }
589 
590   if (!ParseItemVariationStore(out_cff.GetFont(),
591                                table.buffer() + table.offset(), length,
592                                &(out_cff.region_index_count))) {
593     return OTS_FAILURE();
594   }
595 
596   return true;
597 }
598 
599 bool ParseDictData(ots::Buffer& table, ots::Buffer& dict,
600                    uint16_t glyphs, size_t sid_max, DICT_DATA_TYPE type,
601                    ots::OpenTypeCFF *out_cff);
602 
ParseDictData(ots::Buffer & table,const ots::CFFIndex & index,uint16_t glyphs,size_t sid_max,DICT_DATA_TYPE type,ots::OpenTypeCFF * out_cff)603 bool ParseDictData(ots::Buffer& table, const ots::CFFIndex &index,
604                    uint16_t glyphs, size_t sid_max, DICT_DATA_TYPE type,
605                    ots::OpenTypeCFF *out_cff) {
606   for (unsigned i = 1; i < index.offsets.size(); ++i) {
607     size_t dict_length = index.offsets[i] - index.offsets[i - 1];
608     ots::Buffer dict(table.buffer() + index.offsets[i - 1], dict_length);
609 
610     if (!ParseDictData(table, dict, glyphs, sid_max, type, out_cff)) {
611       return OTS_FAILURE();
612     }
613   }
614   return true;
615 }
616 
ParseDictData(ots::Buffer & table,ots::Buffer & dict,uint16_t glyphs,size_t sid_max,DICT_DATA_TYPE type,ots::OpenTypeCFF * out_cff)617 bool ParseDictData(ots::Buffer& table, ots::Buffer& dict,
618                    uint16_t glyphs, size_t sid_max, DICT_DATA_TYPE type,
619                    ots::OpenTypeCFF *out_cff) {
620   bool cff2 = (out_cff->major == 2);
621   std::vector<Operand> operands;
622 
623   FONT_FORMAT font_format = FORMAT_UNKNOWN;
624   bool have_ros = false;
625   bool have_charstrings = false;
626   bool have_vstore = false;
627   size_t charset_offset = 0;
628 
629   if (cff2) {
630     // Parse VariationStore first, since it might be referenced in other places
631     // (e.g. FDArray) that might be parsed after it.
632     size_t dict_offset = dict.offset();
633     while (dict.offset() < dict.length()) {
634       if (!ParseDictDataReadOperands(dict, operands, cff2)) {
635         return OTS_FAILURE();
636       }
637       if (operands.back().second != DICT_OPERATOR) continue;
638 
639       // got operator
640       const uint32_t op = operands.back().first;
641       operands.pop_back();
642 
643       if (op == 24) {  // vstore
644         if (type != DICT_DATA_TOPLEVEL) {
645           return OTS_FAILURE();
646         }
647         if (operands.size() != 1) {
648           return OTS_FAILURE();
649         }
650         if (!CheckOffset(operands.back(), table.length())) {
651           return OTS_FAILURE();
652         }
653         // parse "VariationStore Data Contents"
654         table.set_offset(operands.back().first);
655         if (!ParseVariationStore(*out_cff, table)) {
656           return OTS_FAILURE();
657         }
658         break;
659       }
660       operands.clear();
661     }
662     operands.clear();
663     dict.set_offset(dict_offset);
664   }
665 
666   while (dict.offset() < dict.length()) {
667     if (!ParseDictDataReadOperands(dict, operands, cff2)) {
668       return OTS_FAILURE();
669     }
670     if (operands.back().second != DICT_OPERATOR) continue;
671 
672     // got operator
673     const uint32_t op = operands.back().first;
674     operands.pop_back();
675 
676     if (cff2 && !ValidCFF2DictOp(op, type)) {
677       return OTS_FAILURE();
678     }
679 
680     switch (op) {
681       // SID
682       case 0:   // version
683       case 1:   // Notice
684       case 2:   // Copyright
685       case 3:   // FullName
686       case 4:   // FamilyName
687       case (12U << 8) + 0:   // Copyright
688       case (12U << 8) + 21:  // PostScript
689       case (12U << 8) + 22:  // BaseFontName
690       case (12U << 8) + 38:  // FontName
691         if (operands.size() != 1) {
692           return OTS_FAILURE();
693         }
694         if (!CheckSid(operands.back(), sid_max)) {
695           return OTS_FAILURE();
696         }
697         break;
698 
699       // array
700       case 5:   // FontBBox
701       case 14:  // XUID
702       case (12U << 8) + 7:   // FontMatrix
703       case (12U << 8) + 23:  // BaseFontBlend (delta)
704         if (operands.empty()) {
705           return OTS_FAILURE();
706         }
707         break;
708 
709       // number
710       case 13:  // UniqueID
711       case (12U << 8) + 2:   // ItalicAngle
712       case (12U << 8) + 3:   // UnderlinePosition
713       case (12U << 8) + 4:   // UnderlineThickness
714       case (12U << 8) + 5:   // PaintType
715       case (12U << 8) + 8:   // StrokeWidth
716       case (12U << 8) + 20:  // SyntheticBase
717         if (operands.size() != 1) {
718           return OTS_FAILURE();
719         }
720         break;
721       case (12U << 8) + 31:  // CIDFontVersion
722       case (12U << 8) + 32:  // CIDFontRevision
723       case (12U << 8) + 33:  // CIDFontType
724       case (12U << 8) + 34:  // CIDCount
725       case (12U << 8) + 35:  // UIDBase
726         if (operands.size() != 1) {
727           return OTS_FAILURE();
728         }
729         if (font_format != FORMAT_CID_KEYED) {
730           return OTS_FAILURE();
731         }
732         break;
733       case (12U << 8) + 6:   // CharstringType
734         if (operands.size() != 1) {
735           return OTS_FAILURE();
736         }
737         if(operands.back().second != DICT_OPERAND_INTEGER) {
738           return OTS_FAILURE();
739         }
740         if (operands.back().first != 2) {
741           // We only support the "Type 2 Charstring Format."
742           // TODO(yusukes): Support Type 1 format? Is that still in use?
743           return OTS_FAILURE();
744         }
745         break;
746 
747       // boolean
748       case (12U << 8) + 1:   // isFixedPitch
749         if (operands.size() != 1) {
750           return OTS_FAILURE();
751         }
752         if (operands.back().second != DICT_OPERAND_INTEGER) {
753           return OTS_FAILURE();
754         }
755         if (operands.back().first >= 2) {
756           return OTS_FAILURE();
757         }
758         break;
759 
760       // offset(0)
761       case 15:  // charset
762         if (operands.size() != 1) {
763           return OTS_FAILURE();
764         }
765         if (operands.back().first <= 2) {
766           // predefined charset, ISOAdobe, Expert or ExpertSubset, is used.
767           break;
768         }
769         if (!CheckOffset(operands.back(), table.length())) {
770           return OTS_FAILURE();
771         }
772         if (charset_offset) {
773           return OTS_FAILURE();  // multiple charset tables?
774         }
775         charset_offset = operands.back().first;
776         break;
777 
778       case 16: {  // Encoding
779         if (operands.size() != 1) {
780           return OTS_FAILURE();
781         }
782         if (operands.back().first <= 1) {
783           break;  // predefined encoding, "Standard" or "Expert", is used.
784         }
785         if (!CheckOffset(operands.back(), table.length())) {
786           return OTS_FAILURE();
787         }
788 
789         table.set_offset(operands.back().first);
790         uint8_t format = 0;
791         if (!table.ReadU8(&format)) {
792           return OTS_FAILURE();
793         }
794         if (format & 0x80) {
795           // supplemental encoding is not supported at the moment.
796           return OTS_FAILURE();
797         }
798         // TODO(yusukes): support & parse supplemental encoding tables.
799         break;
800       }
801 
802       case 17: {  // CharStrings
803         if (type != DICT_DATA_TOPLEVEL) {
804           return OTS_FAILURE();
805         }
806         if (operands.size() != 1) {
807           return OTS_FAILURE();
808         }
809         if (!CheckOffset(operands.back(), table.length())) {
810           return OTS_FAILURE();
811         }
812         // parse "14. CharStrings INDEX"
813         table.set_offset(operands.back().first);
814         ots::CFFIndex *charstring_index = out_cff->charstrings_index;
815         if (!ParseIndex(table, *charstring_index, cff2)) {
816           return OTS_FAILURE();
817         }
818         if (charstring_index->count < 2) {
819           return OTS_FAILURE();
820         }
821         if (have_charstrings) {
822           return OTS_FAILURE();  // multiple charstring tables?
823         }
824         have_charstrings = true;
825         if (charstring_index->count != glyphs) {
826           return OTS_FAILURE();  // CFF and maxp have different number of glyphs?
827         }
828         break;
829       }
830 
831       case 24: {  // vstore
832         if (!cff2) {
833           return OTS_FAILURE();
834         }
835         if (have_vstore) {
836           return OTS_FAILURE();  // multiple vstore tables?
837         }
838         have_vstore = true;
839         // parsed above.
840         break;
841       }
842 
843       case (12U << 8) + 36: {  // FDArray
844         if (type != DICT_DATA_TOPLEVEL) {
845           return OTS_FAILURE();
846         }
847         if (operands.size() != 1) {
848           return OTS_FAILURE();
849         }
850         if (!CheckOffset(operands.back(), table.length())) {
851           return OTS_FAILURE();
852         }
853 
854         // parse Font DICT INDEX.
855         table.set_offset(operands.back().first);
856         ots::CFFIndex sub_dict_index;
857         if (!ParseIndex(table, sub_dict_index, cff2)) {
858           return OTS_FAILURE();
859         }
860         if (!ParseDictData(table, sub_dict_index,
861                            glyphs, sid_max, DICT_DATA_FDARRAY,
862                            out_cff)) {
863           return OTS_FAILURE();
864         }
865         if (out_cff->font_dict_length != 0) {
866           return OTS_FAILURE();  // two or more FDArray found.
867         }
868         out_cff->font_dict_length = sub_dict_index.count;
869         break;
870       }
871 
872       case (12U << 8) + 37: {  // FDSelect
873         if (type != DICT_DATA_TOPLEVEL) {
874           return OTS_FAILURE();
875         }
876         if (operands.size() != 1) {
877           return OTS_FAILURE();
878         }
879         if (!CheckOffset(operands.back(), table.length())) {
880           return OTS_FAILURE();
881         }
882 
883         // parse FDSelect data structure
884         table.set_offset(operands.back().first);
885         uint8_t format = 0;
886         if (!table.ReadU8(&format)) {
887           return OTS_FAILURE();
888         }
889         if (format == 0) {
890           for (uint16_t j = 0; j < glyphs; ++j) {
891             uint8_t fd_index = 0;
892             if (!table.ReadU8(&fd_index)) {
893               return OTS_FAILURE();
894             }
895             (out_cff->fd_select)[j] = fd_index;
896           }
897         } else if (format == 3) {
898           uint16_t n_ranges = 0;
899           if (!table.ReadU16(&n_ranges)) {
900             return OTS_FAILURE();
901           }
902           if (n_ranges == 0) {
903             return OTS_FAILURE();
904           }
905 
906           uint16_t last_gid = 0;
907           uint8_t fd_index = 0;
908           for (unsigned j = 0; j < n_ranges; ++j) {
909             uint16_t first = 0;  // GID
910             if (!table.ReadU16(&first)) {
911               return OTS_FAILURE();
912             }
913 
914             // Sanity checks.
915             if ((j == 0) && (first != 0)) {
916               return OTS_FAILURE();
917             }
918             if ((j != 0) && (last_gid >= first)) {
919               return OTS_FAILURE();  // not increasing order.
920             }
921             if (first >= glyphs) {
922               return OTS_FAILURE();  // invalid gid.
923             }
924 
925             // Copy the mapping to |out_cff->fd_select|.
926             if (j != 0) {
927               for (auto k = last_gid; k < first; ++k) {
928                 if (!out_cff->fd_select.insert(
929                         std::make_pair(k, fd_index)).second) {
930                   return OTS_FAILURE();
931                 }
932               }
933             }
934 
935             if (!table.ReadU8(&fd_index)) {
936               return OTS_FAILURE();
937             }
938             last_gid = first;
939           }
940           uint16_t sentinel = 0;
941           if (!table.ReadU16(&sentinel)) {
942             return OTS_FAILURE();
943           }
944           if (last_gid >= sentinel) {
945             return OTS_FAILURE();
946           }
947           if (sentinel > glyphs) {
948             return OTS_FAILURE();  // invalid gid.
949           }
950           for (auto k = last_gid; k < sentinel; ++k) {
951             if (!out_cff->fd_select.insert(
952                     std::make_pair(k, fd_index)).second) {
953               return OTS_FAILURE();
954             }
955           }
956         } else if (cff2 && format == 4) {
957           uint32_t n_ranges = 0;
958           if (!table.ReadU32(&n_ranges)) {
959             return OTS_FAILURE();
960           }
961           if (n_ranges == 0) {
962             return OTS_FAILURE();
963           }
964 
965           uint32_t last_gid = 0;
966           uint16_t fd_index = 0;
967           for (unsigned j = 0; j < n_ranges; ++j) {
968             uint32_t first = 0;  // GID
969             if (!table.ReadU32(&first)) {
970               return OTS_FAILURE();
971             }
972 
973             // Sanity checks.
974             if ((j == 0) && (first != 0)) {
975               return OTS_FAILURE();
976             }
977             if ((j != 0) && (last_gid >= first)) {
978               return OTS_FAILURE();  // not increasing order.
979             }
980             if (first >= glyphs) {
981               return OTS_FAILURE();  // invalid gid.
982             }
983 
984             // Copy the mapping to |out_cff->fd_select|.
985             if (j != 0) {
986               for (auto k = last_gid; k < first; ++k) {
987                 if (!out_cff->fd_select.insert(
988                         std::make_pair(k, fd_index)).second) {
989                   return OTS_FAILURE();
990                 }
991               }
992             }
993 
994             if (!table.ReadU16(&fd_index)) {
995               return OTS_FAILURE();
996             }
997             last_gid = first;
998           }
999           uint32_t sentinel = 0;
1000           if (!table.ReadU32(&sentinel)) {
1001             return OTS_FAILURE();
1002           }
1003           if (last_gid >= sentinel) {
1004             return OTS_FAILURE();
1005           }
1006           if (sentinel > glyphs) {
1007             return OTS_FAILURE();  // invalid gid.
1008           }
1009           for (auto k = last_gid; k < sentinel; ++k) {
1010             if (!out_cff->fd_select.insert(
1011                     std::make_pair(k, fd_index)).second) {
1012               return OTS_FAILURE();
1013             }
1014           }
1015         } else {
1016           // unknown format
1017           return OTS_FAILURE();
1018         }
1019         break;
1020       }
1021 
1022       // Private DICT (2 * number)
1023       case 18: {
1024         if (operands.size() != 2) {
1025           return OTS_FAILURE();
1026         }
1027         if (operands.back().second != DICT_OPERAND_INTEGER) {
1028           return OTS_FAILURE();
1029         }
1030         const uint32_t private_offset = operands.back().first;
1031         operands.pop_back();
1032         if (operands.back().second != DICT_OPERAND_INTEGER) {
1033           return OTS_FAILURE();
1034         }
1035         const uint32_t private_length = operands.back().first;
1036         if (private_offset > table.length()) {
1037           return OTS_FAILURE();
1038         }
1039         if (private_length >= table.length()) {
1040           return OTS_FAILURE();
1041         }
1042         if (private_length + private_offset > table.length()) {
1043           return OTS_FAILURE();
1044         }
1045         // parse "15. Private DICT data"
1046         if (!ParsePrivateDictData(table, private_offset, private_length,
1047                                   type, out_cff)) {
1048           return OTS_FAILURE();
1049         }
1050         break;
1051       }
1052 
1053       // ROS
1054       case (12U << 8) + 30:
1055         if (font_format != FORMAT_UNKNOWN) {
1056           return OTS_FAILURE();
1057         }
1058         font_format = FORMAT_CID_KEYED;
1059         if (operands.size() != 3) {
1060           return OTS_FAILURE();
1061         }
1062         // check SIDs
1063         operands.pop_back();  // ignore the first number.
1064         if (!CheckSid(operands.back(), sid_max)) {
1065           return OTS_FAILURE();
1066         }
1067         operands.pop_back();
1068         if (!CheckSid(operands.back(), sid_max)) {
1069           return OTS_FAILURE();
1070         }
1071         if (have_ros) {
1072           return OTS_FAILURE();  // multiple ROS tables?
1073         }
1074         have_ros = true;
1075         break;
1076 
1077       default:
1078         return OTS_FAILURE();
1079     }
1080     operands.clear();
1081 
1082     if (font_format == FORMAT_UNKNOWN) {
1083       font_format = FORMAT_OTHER;
1084     }
1085   }
1086 
1087   // parse "13. Charsets"
1088   if (charset_offset) {
1089     table.set_offset(charset_offset);
1090     uint8_t format = 0;
1091     if (!table.ReadU8(&format)) {
1092       return OTS_FAILURE();
1093     }
1094     switch (format) {
1095       case 0:
1096         for (uint16_t j = 1 /* .notdef is omitted */; j < glyphs; ++j) {
1097           uint16_t sid = 0;
1098           if (!table.ReadU16(&sid)) {
1099             return OTS_FAILURE();
1100           }
1101           if (!have_ros && (sid > sid_max)) {
1102             return OTS_FAILURE();
1103           }
1104           // TODO(yusukes): check CIDs when have_ros is true.
1105         }
1106         break;
1107 
1108       case 1:
1109       case 2: {
1110         uint32_t total = 1;  // .notdef is omitted.
1111         while (total < glyphs) {
1112           uint16_t sid = 0;
1113           if (!table.ReadU16(&sid)) {
1114             return OTS_FAILURE();
1115           }
1116           if (!have_ros && (sid > sid_max)) {
1117             return OTS_FAILURE();
1118           }
1119           // TODO(yusukes): check CIDs when have_ros is true.
1120 
1121           if (format == 1) {
1122             uint8_t left = 0;
1123             if (!table.ReadU8(&left)) {
1124               return OTS_FAILURE();
1125             }
1126             total += (left + 1);
1127           } else {
1128             uint16_t left = 0;
1129             if (!table.ReadU16(&left)) {
1130               return OTS_FAILURE();
1131             }
1132             total += (left + 1);
1133           }
1134         }
1135         break;
1136       }
1137 
1138       default:
1139         return OTS_FAILURE();
1140     }
1141   }
1142   return true;
1143 }
1144 
1145 }  // namespace
1146 
1147 namespace ots {
1148 
ValidateFDSelect(uint16_t num_glyphs)1149 bool OpenTypeCFF::ValidateFDSelect(uint16_t num_glyphs) {
1150   for (const auto& fd_select : this->fd_select) {
1151     if (fd_select.first >= num_glyphs) {
1152       return Error("Invalid glyph index in FDSelect: %d >= %d\n",
1153                    fd_select.first, num_glyphs);
1154     }
1155     if (fd_select.second >= this->font_dict_length) {
1156       return Error("Invalid FD index: %d >= %d\n",
1157                    fd_select.second, this->font_dict_length);
1158     }
1159   }
1160   return true;
1161 }
1162 
Parse(const uint8_t * data,size_t length)1163 bool OpenTypeCFF::Parse(const uint8_t *data, size_t length) {
1164   Buffer table(data, length);
1165 
1166   Font *font = GetFont();
1167 
1168   this->m_data = data;
1169   this->m_length = length;
1170 
1171   // parse "6. Header" in the Adobe Compact Font Format Specification
1172   uint8_t major = 0;
1173   uint8_t minor = 0;
1174   uint8_t hdr_size = 0;
1175   uint8_t off_size = 0;
1176   if (!table.ReadU8(&major) ||
1177       !table.ReadU8(&minor) ||
1178       !table.ReadU8(&hdr_size) ||
1179       !table.ReadU8(&off_size)) {
1180     return Error("Failed to read table header");
1181   }
1182 
1183   if (off_size < 1 || off_size > 4) {
1184     return Error("Bad offSize: %d", off_size);
1185   }
1186 
1187   if (major != 1 || minor != 0) {
1188     return Error("Unsupported table version: %d.%d", major, minor);
1189   }
1190 
1191   this->major = major;
1192 
1193   if (hdr_size != 4 || hdr_size >= length) {
1194     return Error("Bad hdrSize: %d", hdr_size);
1195   }
1196 
1197   // parse "7. Name INDEX"
1198   table.set_offset(hdr_size);
1199   CFFIndex name_index;
1200   if (!ParseIndex(table, name_index)) {
1201     return Error("Failed to parse Name INDEX");
1202   }
1203   if (name_index.count != 1 || name_index.offsets.size() != 2) {
1204     return Error("Name INDEX must contain only one entry, not %d",
1205                  name_index.count);
1206   }
1207   if (!ParseNameData(&table, name_index, &(this->name))) {
1208     return Error("Failed to parse Name INDEX data");
1209   }
1210 
1211   // parse "8. Top DICT INDEX"
1212   table.set_offset(name_index.offset_to_next);
1213   CFFIndex top_dict_index;
1214   if (!ParseIndex(table, top_dict_index)) {
1215     return Error("Failed to parse Top DICT INDEX");
1216   }
1217   if (top_dict_index.count != 1) {
1218     return Error("Top DICT INDEX must contain only one entry, not %d",
1219                  top_dict_index.count);
1220   }
1221 
1222   // parse "10. String INDEX"
1223   table.set_offset(top_dict_index.offset_to_next);
1224   CFFIndex string_index;
1225   if (!ParseIndex(table, string_index)) {
1226     return Error("Failed to parse String INDEX");
1227   }
1228   if (string_index.count >= 65000 - kNStdString) {
1229     return Error("Too many entries in String INDEX: %d", string_index.count);
1230   }
1231 
1232   OpenTypeMAXP *maxp = static_cast<OpenTypeMAXP*>(
1233     font->GetTypedTable(OTS_TAG_MAXP));
1234   if (!maxp) {
1235     return Error("Required maxp table missing");
1236   }
1237   const uint16_t num_glyphs = maxp->num_glyphs;
1238   const size_t sid_max = string_index.count + kNStdString;
1239   // string_index.count == 0 is allowed.
1240 
1241   // parse "9. Top DICT Data"
1242   this->charstrings_index = new ots::CFFIndex;
1243   if (!ParseDictData(table, top_dict_index,
1244                      num_glyphs, sid_max,
1245                      DICT_DATA_TOPLEVEL, this)) {
1246     return Error("Failed to parse Top DICT Data");
1247   }
1248 
1249   // parse "16. Global Subrs INDEX"
1250   table.set_offset(string_index.offset_to_next);
1251   CFFIndex global_subrs_index;
1252   if (!ParseIndex(table, global_subrs_index)) {
1253     return Error("Failed to parse Global Subrs INDEX");
1254   }
1255 
1256   // Check if all fd and glyph indices in FDSelect are valid.
1257   if (!ValidateFDSelect(num_glyphs)) {
1258     return Error("Failed to validate FDSelect");
1259   }
1260 
1261   // Check if all charstrings (font hinting code for each glyph) are valid.
1262   if (!ValidateCFFCharStrings(*this, global_subrs_index, &table)) {
1263     return Error("Failed validating CharStrings INDEX");
1264   }
1265 
1266   return true;
1267 }
1268 
Serialize(OTSStream * out)1269 bool OpenTypeCFF::Serialize(OTSStream *out) {
1270   if (!out->Write(this->m_data, this->m_length)) {
1271     return Error("Failed to write table");
1272   }
1273   return true;
1274 }
1275 
~OpenTypeCFF()1276 OpenTypeCFF::~OpenTypeCFF() {
1277   for (size_t i = 0; i < this->local_subrs_per_font.size(); ++i) {
1278     delete (this->local_subrs_per_font)[i];
1279   }
1280   delete this->charstrings_index;
1281   delete this->local_subrs;
1282 }
1283 
Parse(const uint8_t * data,size_t length)1284 bool OpenTypeCFF2::Parse(const uint8_t *data, size_t length) {
1285   Buffer table(data, length);
1286 
1287   Font *font = GetFont();
1288 
1289   this->m_data = data;
1290   this->m_length = length;
1291 
1292   // parse "6. Header"
1293   uint8_t major = 0;
1294   uint8_t minor = 0;
1295   uint8_t hdr_size = 0;
1296   uint16_t top_dict_size = 0;
1297   if (!table.ReadU8(&major) ||
1298       !table.ReadU8(&minor) ||
1299       !table.ReadU8(&hdr_size) ||
1300       !table.ReadU16(&top_dict_size)) {
1301     return Error("Failed to read table header");
1302   }
1303 
1304   if (major != 2 || minor != 0) {
1305     return Error("Unsupported table version: %d.%d", major, minor);
1306   }
1307 
1308   this->major = major;
1309 
1310   if (hdr_size >= length) {
1311     return Error("Bad hdrSize: %d", hdr_size);
1312   }
1313 
1314   if (top_dict_size == 0 || hdr_size + top_dict_size > length) {
1315     return Error("Bad topDictLength: %d", top_dict_size);
1316   }
1317 
1318   OpenTypeMAXP *maxp = static_cast<OpenTypeMAXP*>(
1319     font->GetTypedTable(OTS_TAG_MAXP));
1320   if (!maxp) {
1321     return Error("Required maxp table missing");
1322   }
1323   const uint16_t num_glyphs = maxp->num_glyphs;
1324   const size_t sid_max = kNStdString;
1325 
1326   // parse "7. Top DICT Data"
1327   ots::Buffer top_dict(data + hdr_size, top_dict_size);
1328   table.set_offset(hdr_size);
1329   this->charstrings_index = new ots::CFFIndex;
1330   if (!ParseDictData(table, top_dict,
1331                      num_glyphs, sid_max,
1332                      DICT_DATA_TOPLEVEL, this)) {
1333     return Error("Failed to parse Top DICT Data");
1334   }
1335 
1336   // parse "9. Global Subrs INDEX"
1337   table.set_offset(hdr_size + top_dict_size);
1338   CFFIndex global_subrs_index;
1339   if (!ParseIndex(table, global_subrs_index, true)) {
1340     return Error("Failed to parse Global Subrs INDEX");
1341   }
1342 
1343   // Check if all fd and glyph indices in FDSelect are valid.
1344   if (!ValidateFDSelect(num_glyphs)) {
1345     return Error("Failed to validate FDSelect");
1346   }
1347 
1348   // Check if all charstrings (font hinting code for each glyph) are valid.
1349   if (!ValidateCFFCharStrings(*this, global_subrs_index, &table)) {
1350     return Error("Failed validating CharStrings INDEX");
1351   }
1352 
1353   return true;
1354 }
1355 
Serialize(OTSStream * out)1356 bool OpenTypeCFF2::Serialize(OTSStream *out) {
1357   if (!out->Write(this->m_data, this->m_length)) {
1358     return Error("Failed to write table");
1359   }
1360   return true;
1361 }
1362 
1363 }  // namespace ots
1364 
1365 #undef TABLE_NAME
1366