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