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