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 int32_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 // For CFF2, |vsindex_per_font| gets a similar treatment.
413 if (type == DICT_DATA_FDARRAY) {
414 out_cff->local_subrs_per_font.push_back(new ots::CFFIndex);
415 if (cff2) {
416 out_cff->vsindex_per_font.push_back(vsindex);
417 }
418 }
419
420 while (dict.offset() < dict.length()) {
421 if (!ParseDictDataReadOperands(dict, operands, cff2)) {
422 return OTS_FAILURE();
423 }
424 if (operands.back().second != DICT_OPERATOR) {
425 continue;
426 }
427
428 // got operator
429 const uint32_t op = operands.back().first;
430 operands.pop_back();
431
432 if (cff2 && !ValidCFF2DictOp(op, DICT_DATA_PRIVATE)) {
433 return OTS_FAILURE();
434 }
435
436 bool clear_operands = true;
437 switch (op) {
438 // hints
439 case 6: // BlueValues
440 case 7: // OtherBlues
441 case 8: // FamilyBlues
442 case 9: // FamilyOtherBlues
443 if ((operands.size() % 2) != 0) {
444 return OTS_FAILURE();
445 }
446 break;
447
448 // array
449 case (12U << 8) + 12: // StemSnapH (delta)
450 case (12U << 8) + 13: // StemSnapV (delta)
451 if (operands.empty()) {
452 return OTS_FAILURE();
453 }
454 break;
455
456 // number
457 case 10: // StdHW
458 case 11: // StdVW
459 case 20: // defaultWidthX
460 case 21: // nominalWidthX
461 case (12U << 8) + 9: // BlueScale
462 case (12U << 8) + 10: // BlueShift
463 case (12U << 8) + 11: // BlueFuzz
464 case (12U << 8) + 17: // LanguageGroup
465 case (12U << 8) + 18: // ExpansionFactor
466 case (12U << 8) + 19: // initialRandomSeed
467 if (operands.size() != 1) {
468 return OTS_FAILURE();
469 }
470 break;
471
472 // Local Subrs INDEX, offset(self)
473 case 19: {
474 if (operands.size() != 1) {
475 return OTS_FAILURE();
476 }
477 if (operands.back().second != DICT_OPERAND_INTEGER) {
478 return OTS_FAILURE();
479 }
480 if (operands.back().first >= 1024 * 1024 * 1024) {
481 return OTS_FAILURE();
482 }
483 if (operands.back().first + offset >= table.length()) {
484 return OTS_FAILURE();
485 }
486 // parse "16. Local Subrs INDEX"
487 table.set_offset(operands.back().first + offset);
488 ots::CFFIndex *local_subrs_index = NULL;
489 if (type == DICT_DATA_FDARRAY) {
490 if (out_cff->local_subrs_per_font.empty()) {
491 return OTS_FAILURE(); // not reached.
492 }
493 local_subrs_index = out_cff->local_subrs_per_font.back();
494 } else { // type == DICT_DATA_TOPLEVEL
495 if (out_cff->local_subrs) {
496 return OTS_FAILURE(); // two or more local_subrs?
497 }
498 local_subrs_index = new ots::CFFIndex;
499 out_cff->local_subrs = local_subrs_index;
500 }
501 if (!ParseIndex(table, *local_subrs_index, cff2)) {
502 return OTS_FAILURE();
503 }
504 break;
505 }
506
507 // boolean
508 case (12U << 8) + 14: // ForceBold
509 if (operands.size() != 1) {
510 return OTS_FAILURE();
511 }
512 if (operands.back().second != DICT_OPERAND_INTEGER) {
513 return OTS_FAILURE();
514 }
515 if (operands.back().first >= 2) {
516 return OTS_FAILURE();
517 }
518 break;
519
520 case 22: { // vsindex
521 if (!cff2) {
522 return OTS_FAILURE();
523 }
524 if (operands.size() != 1) {
525 return OTS_FAILURE();
526 }
527 if (operands.back().second != DICT_OPERAND_INTEGER) {
528 return OTS_FAILURE();
529 }
530 if (blend_seen) {
531 return OTS_FAILURE();
532 }
533 vsindex = operands.back().first;
534 if (vsindex < 0 ||
535 vsindex >= (int32_t)out_cff->region_index_count.size()) {
536 return OTS_FAILURE();
537 }
538 out_cff->vsindex_per_font.back() = vsindex;
539 break;
540 }
541
542 case 23: { // blend
543 if (!cff2) {
544 return OTS_FAILURE();
545 }
546 if (operands.size() < 1) {
547 return OTS_FAILURE();
548 }
549 if (vsindex >= (int32_t)out_cff->region_index_count.size()) {
550 return OTS_FAILURE();
551 }
552 uint16_t k = out_cff->region_index_count.at(vsindex);
553 uint16_t n = operands.back().first;
554 if (operands.size() < n * (k + 1) + 1) {
555 return OTS_FAILURE();
556 }
557 size_t operands_size = operands.size();
558 // Keep the 1st n operands on the stack for the next operator to use
559 // and pop the rest. There can be multiple consecutive blend operator,
560 // so this makes sure the operands of all of them are kept on the
561 // stack.
562 while (operands.size() > operands_size - ((n * k) + 1))
563 operands.pop_back();
564 clear_operands = false;
565 blend_seen = true;
566 break;
567 }
568
569 default:
570 return OTS_FAILURE();
571 }
572 if (clear_operands) {
573 operands.clear();
574 }
575 }
576
577 return true;
578 }
579
ParseVariationStore(ots::OpenTypeCFF & out_cff,ots::Buffer & table)580 bool ParseVariationStore(ots::OpenTypeCFF& out_cff, ots::Buffer& table) {
581 uint16_t length;
582
583 if (!table.ReadU16(&length)) {
584 return OTS_FAILURE();
585 }
586
587 // Empty VariationStore is allowed.
588 if (!length) {
589 return true;
590 }
591
592 if (length > table.remaining()) {
593 return OTS_FAILURE();
594 }
595
596 if (!ParseItemVariationStore(out_cff.GetFont(),
597 table.buffer() + table.offset(), length,
598 &(out_cff.region_index_count))) {
599 return OTS_FAILURE();
600 }
601
602 return true;
603 }
604
605 bool ParseDictData(ots::Buffer& table, ots::Buffer& dict,
606 uint16_t glyphs, size_t sid_max, DICT_DATA_TYPE type,
607 ots::OpenTypeCFF *out_cff);
608
ParseDictData(ots::Buffer & table,const ots::CFFIndex & index,uint16_t glyphs,size_t sid_max,DICT_DATA_TYPE type,ots::OpenTypeCFF * out_cff)609 bool ParseDictData(ots::Buffer& table, const ots::CFFIndex &index,
610 uint16_t glyphs, size_t sid_max, DICT_DATA_TYPE type,
611 ots::OpenTypeCFF *out_cff) {
612 for (unsigned i = 1; i < index.offsets.size(); ++i) {
613 size_t dict_length = index.offsets[i] - index.offsets[i - 1];
614 ots::Buffer dict(table.buffer() + index.offsets[i - 1], dict_length);
615
616 if (!ParseDictData(table, dict, glyphs, sid_max, type, out_cff)) {
617 return OTS_FAILURE();
618 }
619 }
620 return true;
621 }
622
ParseDictData(ots::Buffer & table,ots::Buffer & dict,uint16_t glyphs,size_t sid_max,DICT_DATA_TYPE type,ots::OpenTypeCFF * out_cff)623 bool ParseDictData(ots::Buffer& table, ots::Buffer& dict,
624 uint16_t glyphs, size_t sid_max, DICT_DATA_TYPE type,
625 ots::OpenTypeCFF *out_cff) {
626 bool cff2 = (out_cff->major == 2);
627 std::vector<Operand> operands;
628
629 FONT_FORMAT font_format = FORMAT_UNKNOWN;
630 bool have_ros = false;
631 bool have_charstrings = false;
632 bool have_vstore = false;
633 size_t charset_offset = 0;
634 bool have_private = false;
635
636 if (cff2) {
637 // Parse VariationStore first, since it might be referenced in other places
638 // (e.g. FDArray) that might be parsed after it.
639 size_t dict_offset = dict.offset();
640 while (dict.offset() < dict.length()) {
641 if (!ParseDictDataReadOperands(dict, operands, cff2)) {
642 return OTS_FAILURE();
643 }
644 if (operands.back().second != DICT_OPERATOR) continue;
645
646 // got operator
647 const uint32_t op = operands.back().first;
648 operands.pop_back();
649
650 if (op == 18 && type == DICT_DATA_FDARRAY) {
651 have_private = true;
652 }
653
654 if (op == 24) { // vstore
655 if (type != DICT_DATA_TOPLEVEL) {
656 return OTS_FAILURE();
657 }
658 if (operands.size() != 1) {
659 return OTS_FAILURE();
660 }
661 if (!CheckOffset(operands.back(), table.length())) {
662 return OTS_FAILURE();
663 }
664 // parse "VariationStore Data Contents"
665 table.set_offset(operands.back().first);
666 if (!ParseVariationStore(*out_cff, table)) {
667 return OTS_FAILURE();
668 }
669 break;
670 }
671 operands.clear();
672 }
673 operands.clear();
674 dict.set_offset(dict_offset);
675
676 if (type == DICT_DATA_FDARRAY && !have_private) {
677 return OTS_FAILURE(); // CFF2 FD must have PrivateDICT entry (even if 0, 0)
678 }
679
680 }
681
682 while (dict.offset() < dict.length()) {
683 if (!ParseDictDataReadOperands(dict, operands, cff2)) {
684 return OTS_FAILURE();
685 }
686 if (operands.back().second != DICT_OPERATOR) continue;
687
688 // got operator
689 const uint32_t op = operands.back().first;
690 operands.pop_back();
691
692 if (cff2 && !ValidCFF2DictOp(op, type)) {
693 return OTS_FAILURE();
694 }
695
696 switch (op) {
697 // SID
698 case 0: // version
699 case 1: // Notice
700 case 2: // Copyright
701 case 3: // FullName
702 case 4: // FamilyName
703 case (12U << 8) + 0: // Copyright
704 case (12U << 8) + 21: // PostScript
705 case (12U << 8) + 22: // BaseFontName
706 case (12U << 8) + 38: // FontName
707 if (operands.size() != 1) {
708 return OTS_FAILURE();
709 }
710 if (!CheckSid(operands.back(), sid_max)) {
711 return OTS_FAILURE();
712 }
713 break;
714
715 // array
716 case 5: // FontBBox
717 case 14: // XUID
718 case (12U << 8) + 7: // FontMatrix
719 case (12U << 8) + 23: // BaseFontBlend (delta)
720 if (operands.empty()) {
721 return OTS_FAILURE();
722 }
723 break;
724
725 // number
726 case 13: // UniqueID
727 case (12U << 8) + 2: // ItalicAngle
728 case (12U << 8) + 3: // UnderlinePosition
729 case (12U << 8) + 4: // UnderlineThickness
730 case (12U << 8) + 5: // PaintType
731 case (12U << 8) + 8: // StrokeWidth
732 case (12U << 8) + 20: // SyntheticBase
733 if (operands.size() != 1) {
734 return OTS_FAILURE();
735 }
736 break;
737 case (12U << 8) + 31: // CIDFontVersion
738 case (12U << 8) + 32: // CIDFontRevision
739 case (12U << 8) + 33: // CIDFontType
740 case (12U << 8) + 34: // CIDCount
741 case (12U << 8) + 35: // UIDBase
742 if (operands.size() != 1) {
743 return OTS_FAILURE();
744 }
745 if (font_format != FORMAT_CID_KEYED) {
746 return OTS_FAILURE();
747 }
748 break;
749 case (12U << 8) + 6: // CharstringType
750 if (operands.size() != 1) {
751 return OTS_FAILURE();
752 }
753 if(operands.back().second != DICT_OPERAND_INTEGER) {
754 return OTS_FAILURE();
755 }
756 if (operands.back().first != 2) {
757 // We only support the "Type 2 Charstring Format."
758 // TODO(yusukes): Support Type 1 format? Is that still in use?
759 return OTS_FAILURE();
760 }
761 break;
762
763 // boolean
764 case (12U << 8) + 1: // isFixedPitch
765 if (operands.size() != 1) {
766 return OTS_FAILURE();
767 }
768 if (operands.back().second != DICT_OPERAND_INTEGER) {
769 return OTS_FAILURE();
770 }
771 if (operands.back().first >= 2) {
772 return OTS_FAILURE();
773 }
774 break;
775
776 // offset(0)
777 case 15: // charset
778 if (operands.size() != 1) {
779 return OTS_FAILURE();
780 }
781 if (operands.back().first <= 2) {
782 // predefined charset, ISOAdobe, Expert or ExpertSubset, is used.
783 break;
784 }
785 if (!CheckOffset(operands.back(), table.length())) {
786 return OTS_FAILURE();
787 }
788 if (charset_offset) {
789 return OTS_FAILURE(); // multiple charset tables?
790 }
791 charset_offset = operands.back().first;
792 break;
793
794 case 16: { // Encoding
795 if (operands.size() != 1) {
796 return OTS_FAILURE();
797 }
798 if (operands.back().first <= 1) {
799 break; // predefined encoding, "Standard" or "Expert", is used.
800 }
801 if (!CheckOffset(operands.back(), table.length())) {
802 return OTS_FAILURE();
803 }
804
805 table.set_offset(operands.back().first);
806 uint8_t format = 0;
807 if (!table.ReadU8(&format)) {
808 return OTS_FAILURE();
809 }
810 if (format & 0x80) {
811 // supplemental encoding is not supported at the moment.
812 return OTS_FAILURE();
813 }
814 // TODO(yusukes): support & parse supplemental encoding tables.
815 break;
816 }
817
818 case 17: { // CharStrings
819 if (type != DICT_DATA_TOPLEVEL) {
820 return OTS_FAILURE();
821 }
822 if (operands.size() != 1) {
823 return OTS_FAILURE();
824 }
825 if (!CheckOffset(operands.back(), table.length())) {
826 return OTS_FAILURE();
827 }
828 // parse "14. CharStrings INDEX"
829 table.set_offset(operands.back().first);
830 ots::CFFIndex *charstring_index = out_cff->charstrings_index;
831 if (!ParseIndex(table, *charstring_index, cff2)) {
832 return OTS_FAILURE();
833 }
834 if (charstring_index->count < 2) {
835 return OTS_FAILURE();
836 }
837 if (have_charstrings) {
838 return OTS_FAILURE(); // multiple charstring tables?
839 }
840 have_charstrings = true;
841 if (charstring_index->count != glyphs) {
842 return OTS_FAILURE(); // CFF and maxp have different number of glyphs?
843 }
844 break;
845 }
846
847 case 24: { // vstore
848 if (!cff2) {
849 return OTS_FAILURE();
850 }
851 if (have_vstore) {
852 return OTS_FAILURE(); // multiple vstore tables?
853 }
854 have_vstore = true;
855 // parsed above.
856 break;
857 }
858
859 case (12U << 8) + 36: { // FDArray
860 if (type != DICT_DATA_TOPLEVEL) {
861 return OTS_FAILURE();
862 }
863 if (operands.size() != 1) {
864 return OTS_FAILURE();
865 }
866 if (!CheckOffset(operands.back(), table.length())) {
867 return OTS_FAILURE();
868 }
869
870 // parse Font DICT INDEX.
871 table.set_offset(operands.back().first);
872 ots::CFFIndex sub_dict_index;
873 if (!ParseIndex(table, sub_dict_index, cff2)) {
874 return OTS_FAILURE();
875 }
876 if (!ParseDictData(table, sub_dict_index,
877 glyphs, sid_max, DICT_DATA_FDARRAY,
878 out_cff)) {
879 return OTS_FAILURE();
880 }
881 if (out_cff->font_dict_length != 0) {
882 return OTS_FAILURE(); // two or more FDArray found.
883 }
884 out_cff->font_dict_length = sub_dict_index.count;
885 break;
886 }
887
888 case (12U << 8) + 37: { // FDSelect
889 if (type != DICT_DATA_TOPLEVEL) {
890 return OTS_FAILURE();
891 }
892 if (operands.size() != 1) {
893 return OTS_FAILURE();
894 }
895 if (!CheckOffset(operands.back(), table.length())) {
896 return OTS_FAILURE();
897 }
898
899 // parse FDSelect data structure
900 table.set_offset(operands.back().first);
901 uint8_t format = 0;
902 if (!table.ReadU8(&format)) {
903 return OTS_FAILURE();
904 }
905 if (format == 0) {
906 for (uint16_t j = 0; j < glyphs; ++j) {
907 uint8_t fd_index = 0;
908 if (!table.ReadU8(&fd_index)) {
909 return OTS_FAILURE();
910 }
911 (out_cff->fd_select)[j] = fd_index;
912 }
913 } else if (format == 3) {
914 uint16_t n_ranges = 0;
915 if (!table.ReadU16(&n_ranges)) {
916 return OTS_FAILURE();
917 }
918 if (n_ranges == 0) {
919 return OTS_FAILURE();
920 }
921
922 uint16_t last_gid = 0;
923 uint8_t fd_index = 0;
924 for (unsigned j = 0; j < n_ranges; ++j) {
925 uint16_t first = 0; // GID
926 if (!table.ReadU16(&first)) {
927 return OTS_FAILURE();
928 }
929
930 // Sanity checks.
931 if ((j == 0) && (first != 0)) {
932 return OTS_FAILURE();
933 }
934 if ((j != 0) && (last_gid >= first)) {
935 return OTS_FAILURE(); // not increasing order.
936 }
937 if (first >= glyphs) {
938 return OTS_FAILURE(); // invalid gid.
939 }
940
941 // Copy the mapping to |out_cff->fd_select|.
942 if (j != 0) {
943 for (auto k = last_gid; k < first; ++k) {
944 if (!out_cff->fd_select.insert(
945 std::make_pair(k, fd_index)).second) {
946 return OTS_FAILURE();
947 }
948 }
949 }
950
951 if (!table.ReadU8(&fd_index)) {
952 return OTS_FAILURE();
953 }
954 last_gid = first;
955 }
956 uint16_t sentinel = 0;
957 if (!table.ReadU16(&sentinel)) {
958 return OTS_FAILURE();
959 }
960 if (last_gid >= sentinel) {
961 return OTS_FAILURE();
962 }
963 if (sentinel > glyphs) {
964 return OTS_FAILURE(); // invalid gid.
965 }
966 for (auto k = last_gid; k < sentinel; ++k) {
967 if (!out_cff->fd_select.insert(
968 std::make_pair(k, fd_index)).second) {
969 return OTS_FAILURE();
970 }
971 }
972 } else if (cff2 && format == 4) {
973 uint32_t n_ranges = 0;
974 if (!table.ReadU32(&n_ranges)) {
975 return OTS_FAILURE();
976 }
977 if (n_ranges == 0) {
978 return OTS_FAILURE();
979 }
980
981 uint32_t last_gid = 0;
982 uint16_t fd_index = 0;
983 for (unsigned j = 0; j < n_ranges; ++j) {
984 uint32_t first = 0; // GID
985 if (!table.ReadU32(&first)) {
986 return OTS_FAILURE();
987 }
988
989 // Sanity checks.
990 if ((j == 0) && (first != 0)) {
991 return OTS_FAILURE();
992 }
993 if ((j != 0) && (last_gid >= first)) {
994 return OTS_FAILURE(); // not increasing order.
995 }
996 if (first >= glyphs) {
997 return OTS_FAILURE(); // invalid gid.
998 }
999
1000 // Copy the mapping to |out_cff->fd_select|.
1001 if (j != 0) {
1002 for (auto k = last_gid; k < first; ++k) {
1003 if (!out_cff->fd_select.insert(
1004 std::make_pair(k, fd_index)).second) {
1005 return OTS_FAILURE();
1006 }
1007 }
1008 }
1009
1010 if (!table.ReadU16(&fd_index)) {
1011 return OTS_FAILURE();
1012 }
1013 last_gid = first;
1014 }
1015 uint32_t sentinel = 0;
1016 if (!table.ReadU32(&sentinel)) {
1017 return OTS_FAILURE();
1018 }
1019 if (last_gid >= sentinel) {
1020 return OTS_FAILURE();
1021 }
1022 if (sentinel > glyphs) {
1023 return OTS_FAILURE(); // invalid gid.
1024 }
1025 for (auto k = last_gid; k < sentinel; ++k) {
1026 if (!out_cff->fd_select.insert(
1027 std::make_pair(k, fd_index)).second) {
1028 return OTS_FAILURE();
1029 }
1030 }
1031 } else {
1032 // unknown format
1033 return OTS_FAILURE();
1034 }
1035 break;
1036 }
1037
1038 // Private DICT (2 * number)
1039 case 18: {
1040 if (operands.size() != 2) {
1041 return OTS_FAILURE();
1042 }
1043 if (operands.back().second != DICT_OPERAND_INTEGER) {
1044 return OTS_FAILURE();
1045 }
1046 const uint32_t private_offset = operands.back().first;
1047 operands.pop_back();
1048 if (operands.back().second != DICT_OPERAND_INTEGER) {
1049 return OTS_FAILURE();
1050 }
1051 const uint32_t private_length = operands.back().first;
1052 if (private_offset > table.length()) {
1053 return OTS_FAILURE();
1054 }
1055 if (private_length >= table.length()) {
1056 return OTS_FAILURE();
1057 }
1058 if (private_length + private_offset > table.length()) {
1059 return OTS_FAILURE();
1060 }
1061 // parse "15. Private DICT data"
1062 if (!ParsePrivateDictData(table, private_offset, private_length,
1063 type, out_cff)) {
1064 return OTS_FAILURE();
1065 }
1066 break;
1067 }
1068
1069 // ROS
1070 case (12U << 8) + 30:
1071 if (font_format != FORMAT_UNKNOWN) {
1072 return OTS_FAILURE();
1073 }
1074 font_format = FORMAT_CID_KEYED;
1075 if (operands.size() != 3) {
1076 return OTS_FAILURE();
1077 }
1078 // check SIDs
1079 operands.pop_back(); // ignore the first number.
1080 if (!CheckSid(operands.back(), sid_max)) {
1081 return OTS_FAILURE();
1082 }
1083 operands.pop_back();
1084 if (!CheckSid(operands.back(), sid_max)) {
1085 return OTS_FAILURE();
1086 }
1087 if (have_ros) {
1088 return OTS_FAILURE(); // multiple ROS tables?
1089 }
1090 have_ros = true;
1091 break;
1092
1093 default:
1094 return OTS_FAILURE();
1095 }
1096 operands.clear();
1097
1098 if (font_format == FORMAT_UNKNOWN) {
1099 font_format = FORMAT_OTHER;
1100 }
1101 }
1102
1103 // parse "13. Charsets"
1104 if (charset_offset) {
1105 table.set_offset(charset_offset);
1106 uint8_t format = 0;
1107 if (!table.ReadU8(&format)) {
1108 return OTS_FAILURE();
1109 }
1110 switch (format) {
1111 case 0:
1112 for (uint16_t j = 1 /* .notdef is omitted */; j < glyphs; ++j) {
1113 uint16_t sid = 0;
1114 if (!table.ReadU16(&sid)) {
1115 return OTS_FAILURE();
1116 }
1117 if (!have_ros && (sid > sid_max)) {
1118 return OTS_FAILURE();
1119 }
1120 // TODO(yusukes): check CIDs when have_ros is true.
1121 }
1122 break;
1123
1124 case 1:
1125 case 2: {
1126 uint32_t total = 1; // .notdef is omitted.
1127 while (total < glyphs) {
1128 uint16_t sid = 0;
1129 if (!table.ReadU16(&sid)) {
1130 return OTS_FAILURE();
1131 }
1132 if (!have_ros && (sid > sid_max)) {
1133 return OTS_FAILURE();
1134 }
1135 // TODO(yusukes): check CIDs when have_ros is true.
1136
1137 if (format == 1) {
1138 uint8_t left = 0;
1139 if (!table.ReadU8(&left)) {
1140 return OTS_FAILURE();
1141 }
1142 total += (left + 1);
1143 } else {
1144 uint16_t left = 0;
1145 if (!table.ReadU16(&left)) {
1146 return OTS_FAILURE();
1147 }
1148 total += (left + 1);
1149 }
1150 }
1151 break;
1152 }
1153
1154 default:
1155 return OTS_FAILURE();
1156 }
1157 }
1158 return true;
1159 }
1160
1161 } // namespace
1162
1163 namespace ots {
1164
ValidateFDSelect(uint16_t num_glyphs)1165 bool OpenTypeCFF::ValidateFDSelect(uint16_t num_glyphs) {
1166 for (const auto& fd_select : this->fd_select) {
1167 if (fd_select.first >= num_glyphs) {
1168 return Error("Invalid glyph index in FDSelect: %d >= %d\n",
1169 fd_select.first, num_glyphs);
1170 }
1171 if (fd_select.second >= this->font_dict_length) {
1172 return Error("Invalid FD index: %d >= %d\n",
1173 fd_select.second, this->font_dict_length);
1174 }
1175 }
1176 return true;
1177 }
1178
Parse(const uint8_t * data,size_t length)1179 bool OpenTypeCFF::Parse(const uint8_t *data, size_t length) {
1180 Buffer table(data, length);
1181
1182 Font *font = GetFont();
1183
1184 this->m_data = data;
1185 this->m_length = length;
1186
1187 // parse "6. Header" in the Adobe Compact Font Format Specification
1188 uint8_t major = 0;
1189 uint8_t minor = 0;
1190 uint8_t hdr_size = 0;
1191 uint8_t off_size = 0;
1192 if (!table.ReadU8(&major) ||
1193 !table.ReadU8(&minor) ||
1194 !table.ReadU8(&hdr_size) ||
1195 !table.ReadU8(&off_size)) {
1196 return Error("Failed to read table header");
1197 }
1198
1199 if (off_size < 1 || off_size > 4) {
1200 return Error("Bad offSize: %d", off_size);
1201 }
1202
1203 if (major != 1 || minor != 0) {
1204 return Error("Unsupported table version: %d.%d", major, minor);
1205 }
1206
1207 this->major = major;
1208
1209 if (hdr_size != 4 || hdr_size >= length) {
1210 return Error("Bad hdrSize: %d", hdr_size);
1211 }
1212
1213 // parse "7. Name INDEX"
1214 table.set_offset(hdr_size);
1215 CFFIndex name_index;
1216 if (!ParseIndex(table, name_index)) {
1217 return Error("Failed to parse Name INDEX");
1218 }
1219 if (name_index.count != 1 || name_index.offsets.size() != 2) {
1220 return Error("Name INDEX must contain only one entry, not %d",
1221 name_index.count);
1222 }
1223 if (!ParseNameData(&table, name_index, &(this->name))) {
1224 return Error("Failed to parse Name INDEX data");
1225 }
1226
1227 // parse "8. Top DICT INDEX"
1228 table.set_offset(name_index.offset_to_next);
1229 CFFIndex top_dict_index;
1230 if (!ParseIndex(table, top_dict_index)) {
1231 return Error("Failed to parse Top DICT INDEX");
1232 }
1233 if (top_dict_index.count != 1) {
1234 return Error("Top DICT INDEX must contain only one entry, not %d",
1235 top_dict_index.count);
1236 }
1237
1238 // parse "10. String INDEX"
1239 table.set_offset(top_dict_index.offset_to_next);
1240 CFFIndex string_index;
1241 if (!ParseIndex(table, string_index)) {
1242 return Error("Failed to parse String INDEX");
1243 }
1244 if (string_index.count >= 65000 - kNStdString) {
1245 return Error("Too many entries in String INDEX: %d", string_index.count);
1246 }
1247
1248 OpenTypeMAXP *maxp = static_cast<OpenTypeMAXP*>(
1249 font->GetTypedTable(OTS_TAG_MAXP));
1250 if (!maxp) {
1251 return Error("Required maxp table missing");
1252 }
1253 const uint16_t num_glyphs = maxp->num_glyphs;
1254 const size_t sid_max = string_index.count + kNStdString;
1255 // string_index.count == 0 is allowed.
1256
1257 // parse "9. Top DICT Data"
1258 this->charstrings_index = new ots::CFFIndex;
1259 if (!ParseDictData(table, top_dict_index,
1260 num_glyphs, sid_max,
1261 DICT_DATA_TOPLEVEL, this)) {
1262 return Error("Failed to parse Top DICT Data");
1263 }
1264
1265 // parse "16. Global Subrs INDEX"
1266 table.set_offset(string_index.offset_to_next);
1267 CFFIndex global_subrs_index;
1268 if (!ParseIndex(table, global_subrs_index)) {
1269 return Error("Failed to parse Global Subrs INDEX");
1270 }
1271
1272 // Check if all fd and glyph indices in FDSelect are valid.
1273 if (!ValidateFDSelect(num_glyphs)) {
1274 return Error("Failed to validate FDSelect");
1275 }
1276
1277 // Check if all charstrings (font hinting code for each glyph) are valid.
1278 if (!ValidateCFFCharStrings(*this, global_subrs_index, &table)) {
1279 return Error("Failed validating CharStrings INDEX");
1280 }
1281
1282 return true;
1283 }
1284
Serialize(OTSStream * out)1285 bool OpenTypeCFF::Serialize(OTSStream *out) {
1286 if (!out->Write(this->m_data, this->m_length)) {
1287 return Error("Failed to write table");
1288 }
1289 return true;
1290 }
1291
~OpenTypeCFF()1292 OpenTypeCFF::~OpenTypeCFF() {
1293 for (size_t i = 0; i < this->local_subrs_per_font.size(); ++i) {
1294 delete (this->local_subrs_per_font)[i];
1295 }
1296 delete this->charstrings_index;
1297 delete this->local_subrs;
1298 }
1299
Parse(const uint8_t * data,size_t length)1300 bool OpenTypeCFF2::Parse(const uint8_t *data, size_t length) {
1301 Buffer table(data, length);
1302
1303 Font *font = GetFont();
1304
1305 this->m_data = data;
1306 this->m_length = length;
1307
1308 // parse "6. Header"
1309 uint8_t major = 0;
1310 uint8_t minor = 0;
1311 uint8_t hdr_size = 0;
1312 uint16_t top_dict_size = 0;
1313 if (!table.ReadU8(&major) ||
1314 !table.ReadU8(&minor) ||
1315 !table.ReadU8(&hdr_size) ||
1316 !table.ReadU16(&top_dict_size)) {
1317 return Error("Failed to read table header");
1318 }
1319
1320 if (major != 2 || minor != 0) {
1321 return Error("Unsupported table version: %d.%d", major, minor);
1322 }
1323
1324 this->major = major;
1325
1326 if (hdr_size >= length) {
1327 return Error("Bad hdrSize: %d", hdr_size);
1328 }
1329
1330 if (top_dict_size == 0 || hdr_size + top_dict_size > length) {
1331 return Error("Bad topDictLength: %d", top_dict_size);
1332 }
1333
1334 OpenTypeMAXP *maxp = static_cast<OpenTypeMAXP*>(
1335 font->GetTypedTable(OTS_TAG_MAXP));
1336 if (!maxp) {
1337 return Error("Required maxp table missing");
1338 }
1339 const uint16_t num_glyphs = maxp->num_glyphs;
1340 const size_t sid_max = kNStdString;
1341
1342 // parse "7. Top DICT Data"
1343 ots::Buffer top_dict(data + hdr_size, top_dict_size);
1344 table.set_offset(hdr_size);
1345 this->charstrings_index = new ots::CFFIndex;
1346 if (!ParseDictData(table, top_dict,
1347 num_glyphs, sid_max,
1348 DICT_DATA_TOPLEVEL, this)) {
1349 return Error("Failed to parse Top DICT Data");
1350 }
1351
1352 // parse "9. Global Subrs INDEX"
1353 table.set_offset(hdr_size + top_dict_size);
1354 CFFIndex global_subrs_index;
1355 if (!ParseIndex(table, global_subrs_index, true)) {
1356 return Error("Failed to parse Global Subrs INDEX");
1357 }
1358
1359 // Check if all fd and glyph indices in FDSelect are valid.
1360 if (!ValidateFDSelect(num_glyphs)) {
1361 return Error("Failed to validate FDSelect");
1362 }
1363
1364 // Check if all charstrings (font hinting code for each glyph) are valid.
1365 if (!ValidateCFFCharStrings(*this, global_subrs_index, &table)) {
1366 return Error("Failed validating CharStrings INDEX");
1367 }
1368
1369 return true;
1370 }
1371
Serialize(OTSStream * out)1372 bool OpenTypeCFF2::Serialize(OTSStream *out) {
1373 if (!out->Write(this->m_data, this->m_length)) {
1374 return Error("Failed to write table");
1375 }
1376 return true;
1377 }
1378
1379 } // namespace ots
1380
1381 #undef TABLE_NAME
1382