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