1 // Copyright (c) 2010-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 // A parser for the Type 2 Charstring Format.
6 // http://www.adobe.com/devnet/font/pdfs/5177.Type2.pdf
7
8 #include "cff_charstring.h"
9
10 #include <climits>
11 #include <cstdio>
12 #include <cstring>
13 #include <stack>
14 #include <string>
15 #include <utility>
16
17 #define TABLE_NAME "CFF"
18
19 namespace {
20
21 // Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical
22 // Note #5177.
23 const int32_t kMaxSubrsCount = 65536;
24 const size_t kMaxCharStringLength = 65535;
25 const size_t kMaxNumberOfStemHints = 96;
26 const size_t kMaxSubrNesting = 10;
27
28 // |dummy_result| should be a huge positive integer so callsubr and callgsubr
29 // will fail with the dummy value.
30 const int32_t dummy_result = INT_MAX;
31
32 bool ExecuteCharString(ots::OpenTypeCFF& cff,
33 size_t call_depth,
34 const ots::CFFIndex& global_subrs_index,
35 const ots::CFFIndex& local_subrs_index,
36 ots::Buffer *cff_table,
37 ots::Buffer *char_string,
38 std::stack<int32_t> *argument_stack,
39 bool *out_found_endchar,
40 bool *out_found_width,
41 size_t *in_out_num_stems,
42 bool cff2);
43
ArgumentStackOverflows(std::stack<int32_t> * argument_stack,bool cff2)44 bool ArgumentStackOverflows(std::stack<int32_t> *argument_stack, bool cff2) {
45 if ((cff2 && argument_stack->size() > ots::kMaxCFF2ArgumentStack) ||
46 (!cff2 && argument_stack->size() > ots::kMaxCFF1ArgumentStack)) {
47 return true;
48 }
49 return false;
50 }
51
52 #ifdef DUMP_T2CHARSTRING
53 // Converts |op| to a string and returns it.
CharStringOperatorToString(ots::CharStringOperator op)54 const char *CharStringOperatorToString(ots::CharStringOperator op) {
55 switch (op) {
56 case ots::kHStem:
57 return "hstem";
58 case ots::kVStem:
59 return "vstem";
60 case ots::kVMoveTo:
61 return "vmoveto";
62 case ots::kRLineTo:
63 return "rlineto";
64 case ots::kHLineTo:
65 return "hlineto";
66 case ots::kVLineTo:
67 return "vlineto";
68 case ots::kRRCurveTo:
69 return "rrcurveto";
70 case ots::kCallSubr:
71 return "callsubr";
72 case ots::kReturn:
73 return "return";
74 case ots::kEndChar:
75 return "endchar";
76 case ots::kVSIndex:
77 return "vsindex";
78 case ots::kBlend:
79 return "blend";
80 case ots::kHStemHm:
81 return "hstemhm";
82 case ots::kHintMask:
83 return "hintmask";
84 case ots::kCntrMask:
85 return "cntrmask";
86 case ots::kRMoveTo:
87 return "rmoveto";
88 case ots::kHMoveTo:
89 return "hmoveto";
90 case ots::kVStemHm:
91 return "vstemhm";
92 case ots::kRCurveLine:
93 return "rcurveline";
94 case ots::kRLineCurve:
95 return "rlinecurve";
96 case ots::kVVCurveTo:
97 return "VVCurveTo";
98 case ots::kHHCurveTo:
99 return "hhcurveto";
100 case ots::kCallGSubr:
101 return "callgsubr";
102 case ots::kVHCurveTo:
103 return "vhcurveto";
104 case ots::kHVCurveTo:
105 return "HVCurveTo";
106 case ots::kDotSection:
107 return "dotsection";
108 case ots::kAnd:
109 return "and";
110 case ots::kOr:
111 return "or";
112 case ots::kNot:
113 return "not";
114 case ots::kAbs:
115 return "abs";
116 case ots::kAdd:
117 return "add";
118 case ots::kSub:
119 return "sub";
120 case ots::kDiv:
121 return "div";
122 case ots::kNeg:
123 return "neg";
124 case ots::kEq:
125 return "eq";
126 case ots::kDrop:
127 return "drop";
128 case ots::kPut:
129 return "put";
130 case ots::kGet:
131 return "get";
132 case ots::kIfElse:
133 return "ifelse";
134 case ots::kRandom:
135 return "random";
136 case ots::kMul:
137 return "mul";
138 case ots::kSqrt:
139 return "sqrt";
140 case ots::kDup:
141 return "dup";
142 case ots::kExch:
143 return "exch";
144 case ots::kIndex:
145 return "index";
146 case ots::kRoll:
147 return "roll";
148 case ots::kHFlex:
149 return "hflex";
150 case ots::kFlex:
151 return "flex";
152 case ots::kHFlex1:
153 return "hflex1";
154 case ots::kFlex1:
155 return "flex1";
156 }
157
158 return "UNKNOWN";
159 }
160 #endif
161
162 // Read one or more bytes from the |char_string| buffer and stores the number
163 // read on |out_number|. If the number read is an operator (ex 'vstem'), sets
164 // true on |out_is_operator|. Returns true if the function read a number.
ReadNextNumberFromCharString(ots::Buffer * char_string,int32_t * out_number,bool * out_is_operator)165 bool ReadNextNumberFromCharString(ots::Buffer *char_string,
166 int32_t *out_number,
167 bool *out_is_operator) {
168 uint8_t v = 0;
169 if (!char_string->ReadU8(&v)) {
170 return OTS_FAILURE();
171 }
172 *out_is_operator = false;
173
174 // The conversion algorithm is described in Adobe Technical Note #5177, page
175 // 13, Table 1.
176 if (v <= 11) {
177 *out_number = v;
178 *out_is_operator = true;
179 } else if (v == 12) {
180 uint16_t result = (v << 8);
181 if (!char_string->ReadU8(&v)) {
182 return OTS_FAILURE();
183 }
184 result += v;
185 *out_number = result;
186 *out_is_operator = true;
187 } else if (v <= 27) {
188 // Special handling for v==19 and v==20 are implemented in
189 // ExecuteCharStringOperator().
190 *out_number = v;
191 *out_is_operator = true;
192 } else if (v == 28) {
193 if (!char_string->ReadU8(&v)) {
194 return OTS_FAILURE();
195 }
196 uint16_t result = (v << 8);
197 if (!char_string->ReadU8(&v)) {
198 return OTS_FAILURE();
199 }
200 result += v;
201 *out_number = result;
202 } else if (v <= 31) {
203 *out_number = v;
204 *out_is_operator = true;
205 } else if (v <= 246) {
206 *out_number = static_cast<int32_t>(v) - 139;
207 } else if (v <= 250) {
208 uint8_t w = 0;
209 if (!char_string->ReadU8(&w)) {
210 return OTS_FAILURE();
211 }
212 *out_number = ((static_cast<int32_t>(v) - 247) * 256) +
213 static_cast<int32_t>(w) + 108;
214 } else if (v <= 254) {
215 uint8_t w = 0;
216 if (!char_string->ReadU8(&w)) {
217 return OTS_FAILURE();
218 }
219 *out_number = -((static_cast<int32_t>(v) - 251) * 256) -
220 static_cast<int32_t>(w) - 108;
221 } else if (v == 255) {
222 // TODO(yusukes): We should not skip the 4 bytes. Note that when v is 255,
223 // we should treat the following 4-bytes as a 16.16 fixed-point number
224 // rather than 32bit signed int.
225 if (!char_string->Skip(4)) {
226 return OTS_FAILURE();
227 }
228 *out_number = dummy_result;
229 } else {
230 return OTS_FAILURE();
231 }
232
233 return true;
234 }
235
ValidCFF2Operator(int32_t op)236 bool ValidCFF2Operator(int32_t op) {
237 switch (op) {
238 case ots::kReturn:
239 case ots::kEndChar:
240 case ots::kAbs:
241 case ots::kAdd:
242 case ots::kSub:
243 case ots::kDiv:
244 case ots::kNeg:
245 case ots::kRandom:
246 case ots::kMul:
247 case ots::kSqrt:
248 case ots::kDrop:
249 case ots::kExch:
250 case ots::kIndex:
251 case ots::kRoll:
252 case ots::kDup:
253 case ots::kPut:
254 case ots::kGet:
255 case ots::kDotSection:
256 case ots::kAnd:
257 case ots::kOr:
258 case ots::kNot:
259 case ots::kEq:
260 case ots::kIfElse:
261 return false;
262 }
263
264 return true;
265 }
266
267 // Executes |op| and updates |argument_stack|. Returns true if the execution
268 // succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively
269 // calls ExecuteCharString() function. The arguments other than |op| and
270 // |argument_stack| are passed for that reason.
ExecuteCharStringOperator(ots::OpenTypeCFF & cff,int32_t op,size_t call_depth,const ots::CFFIndex & global_subrs_index,const ots::CFFIndex & local_subrs_index,ots::Buffer * cff_table,ots::Buffer * char_string,std::stack<int32_t> * argument_stack,bool * out_found_endchar,bool * in_out_found_width,size_t * in_out_num_stems,bool * in_out_have_blend,bool * in_out_have_visindex,int32_t * in_out_vsindex,bool cff2)271 bool ExecuteCharStringOperator(ots::OpenTypeCFF& cff,
272 int32_t op,
273 size_t call_depth,
274 const ots::CFFIndex& global_subrs_index,
275 const ots::CFFIndex& local_subrs_index,
276 ots::Buffer *cff_table,
277 ots::Buffer *char_string,
278 std::stack<int32_t> *argument_stack,
279 bool *out_found_endchar,
280 bool *in_out_found_width,
281 size_t *in_out_num_stems,
282 bool *in_out_have_blend,
283 bool *in_out_have_visindex,
284 int32_t *in_out_vsindex,
285 bool cff2) {
286 ots::Font* font = cff.GetFont();
287 const size_t stack_size = argument_stack->size();
288
289 if (cff2 && !ValidCFF2Operator(op)) {
290 return OTS_FAILURE();
291 }
292
293 switch (op) {
294 case ots::kCallSubr:
295 case ots::kCallGSubr: {
296 const ots::CFFIndex& subrs_index =
297 (op == ots::kCallSubr ? local_subrs_index : global_subrs_index);
298
299 if (stack_size < 1) {
300 return OTS_FAILURE();
301 }
302 int32_t subr_number = argument_stack->top();
303 argument_stack->pop();
304 if (subr_number == dummy_result) {
305 // For safety, we allow subr calls only with immediate subr numbers for
306 // now. For example, we allow "123 callgsubr", but does not allow "100 12
307 // add callgsubr". Please note that arithmetic and conditional operators
308 // always push the |dummy_result| in this implementation.
309 return OTS_FAILURE();
310 }
311
312 // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes."
313 int32_t bias = 32768;
314 if (subrs_index.count < 1240) {
315 bias = 107;
316 } else if (subrs_index.count < 33900) {
317 bias = 1131;
318 }
319 subr_number += bias;
320
321 // Sanity checks of |subr_number|.
322 if (subr_number < 0) {
323 return OTS_FAILURE();
324 }
325 if (subr_number >= kMaxSubrsCount) {
326 return OTS_FAILURE();
327 }
328 if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number + 1)) {
329 return OTS_FAILURE(); // The number is out-of-bounds.
330 }
331
332 // Prepare ots::Buffer where we're going to jump.
333 const size_t length =
334 subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number];
335 if (length > kMaxCharStringLength) {
336 return OTS_FAILURE();
337 }
338 const size_t offset = subrs_index.offsets[subr_number];
339 cff_table->set_offset(offset);
340 if (!cff_table->Skip(length)) {
341 return OTS_FAILURE();
342 }
343 ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length);
344
345 return ExecuteCharString(cff,
346 call_depth + 1,
347 global_subrs_index,
348 local_subrs_index,
349 cff_table,
350 &char_string_to_jump,
351 argument_stack,
352 out_found_endchar,
353 in_out_found_width,
354 in_out_num_stems,
355 cff2);
356 }
357
358 case ots::kReturn:
359 return true;
360
361 case ots::kEndChar:
362 *out_found_endchar = true;
363 *in_out_found_width = true; // just in case.
364 return true;
365
366 case ots::kVSIndex: {
367 if (!cff2) {
368 return OTS_FAILURE();
369 }
370 if (stack_size != 1) {
371 return OTS_FAILURE();
372 }
373 if (*in_out_have_blend || *in_out_have_visindex) {
374 return OTS_FAILURE();
375 }
376 if (argument_stack->top() >= cff.region_index_count.size()) {
377 return OTS_FAILURE();
378 }
379 *in_out_have_visindex = true;
380 *in_out_vsindex = argument_stack->top();
381 while (!argument_stack->empty())
382 argument_stack->pop();
383 return true;
384 }
385
386 case ots::kBlend: {
387 if (!cff2) {
388 return OTS_FAILURE();
389 }
390 if (stack_size < 1) {
391 return OTS_FAILURE();
392 }
393 if (*in_out_vsindex >= cff.region_index_count.size()) {
394 return OTS_FAILURE();
395 }
396 uint16_t k = cff.region_index_count.at(*in_out_vsindex);
397 uint16_t n = argument_stack->top();
398 if (stack_size < n * (k + 1) + 1) {
399 return OTS_FAILURE();
400 }
401
402 // Keep the 1st n operands on the stack for the next operator to use and
403 // pop the rest. There can be multiple consecutive blend operator, so this
404 // makes sure the operands of all of them are kept on the stack.
405 while (argument_stack->size() > stack_size - ((n * k) + 1))
406 argument_stack->pop();
407 *in_out_have_blend = true;
408 return true;
409 }
410
411 case ots::kHStem:
412 case ots::kVStem:
413 case ots::kHStemHm:
414 case ots::kVStemHm: {
415 bool successful = false;
416 if (stack_size < 2) {
417 return OTS_FAILURE();
418 }
419 if ((stack_size % 2) == 0) {
420 successful = true;
421 } else if ((!(*in_out_found_width)) && (((stack_size - 1) % 2) == 0)) {
422 // The -1 is for "width" argument. For details, see Adobe Technical Note
423 // #5177, page 16, note 4.
424 successful = true;
425 }
426 (*in_out_num_stems) += (stack_size / 2);
427 if ((*in_out_num_stems) > kMaxNumberOfStemHints) {
428 return OTS_FAILURE();
429 }
430 while (!argument_stack->empty())
431 argument_stack->pop();
432 *in_out_found_width = true; // always set true since "w" might be 0 byte.
433 return successful ? true : OTS_FAILURE();
434 }
435
436 case ots::kRMoveTo: {
437 bool successful = false;
438 if (stack_size == 2) {
439 successful = true;
440 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 2)) {
441 successful = true;
442 }
443 while (!argument_stack->empty())
444 argument_stack->pop();
445 *in_out_found_width = true;
446 return successful ? true : OTS_FAILURE();
447 }
448
449 case ots::kVMoveTo:
450 case ots::kHMoveTo: {
451 bool successful = false;
452 if (stack_size == 1) {
453 successful = true;
454 } else if ((!(*in_out_found_width)) && (stack_size - 1 == 1)) {
455 successful = true;
456 }
457 while (!argument_stack->empty())
458 argument_stack->pop();
459 *in_out_found_width = true;
460 return successful ? true : OTS_FAILURE();
461 }
462
463 case ots::kHintMask:
464 case ots::kCntrMask: {
465 bool successful = false;
466 if (stack_size == 0) {
467 successful = true;
468 } else if ((!(*in_out_found_width)) && (stack_size == 1)) {
469 // A number for "width" is found.
470 successful = true;
471 } else if ((!(*in_out_found_width)) || // in this case, any sizes are ok.
472 ((stack_size % 2) == 0)) {
473 // The numbers are vstem definition.
474 // See Adobe Technical Note #5177, page 24, hintmask.
475 (*in_out_num_stems) += (stack_size / 2);
476 if ((*in_out_num_stems) > kMaxNumberOfStemHints) {
477 return OTS_FAILURE();
478 }
479 successful = true;
480 }
481 if (!successful) {
482 return OTS_FAILURE();
483 }
484
485 if ((*in_out_num_stems) == 0) {
486 return OTS_FAILURE();
487 }
488 const size_t mask_bytes = (*in_out_num_stems + 7) / 8;
489 if (!char_string->Skip(mask_bytes)) {
490 return OTS_FAILURE();
491 }
492 while (!argument_stack->empty())
493 argument_stack->pop();
494 *in_out_found_width = true;
495 return true;
496 }
497
498 case ots::kRLineTo:
499 if (!(*in_out_found_width)) {
500 // The first stack-clearing operator should be one of hstem, hstemhm,
501 // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or
502 // endchar. For details, see Adobe Technical Note #5177, page 16, note 4.
503 return OTS_FAILURE();
504 }
505 if (stack_size < 2) {
506 return OTS_FAILURE();
507 }
508 if ((stack_size % 2) != 0) {
509 return OTS_FAILURE();
510 }
511 while (!argument_stack->empty())
512 argument_stack->pop();
513 return true;
514
515 case ots::kHLineTo:
516 case ots::kVLineTo:
517 if (!(*in_out_found_width)) {
518 return OTS_FAILURE();
519 }
520 if (stack_size < 1) {
521 return OTS_FAILURE();
522 }
523 while (!argument_stack->empty())
524 argument_stack->pop();
525 return true;
526
527 case ots::kRRCurveTo:
528 if (!(*in_out_found_width)) {
529 return OTS_FAILURE();
530 }
531 if (stack_size < 6) {
532 return OTS_FAILURE();
533 }
534 if ((stack_size % 6) != 0) {
535 return OTS_FAILURE();
536 }
537 while (!argument_stack->empty())
538 argument_stack->pop();
539 return true;
540
541 case ots::kRCurveLine:
542 if (!(*in_out_found_width)) {
543 return OTS_FAILURE();
544 }
545 if (stack_size < 8) {
546 return OTS_FAILURE();
547 }
548 if (((stack_size - 2) % 6) != 0) {
549 return OTS_FAILURE();
550 }
551 while (!argument_stack->empty())
552 argument_stack->pop();
553 return true;
554
555 case ots::kRLineCurve:
556 if (!(*in_out_found_width)) {
557 return OTS_FAILURE();
558 }
559 if (stack_size < 8) {
560 return OTS_FAILURE();
561 }
562 if (((stack_size - 6) % 2) != 0) {
563 return OTS_FAILURE();
564 }
565 while (!argument_stack->empty())
566 argument_stack->pop();
567 return true;
568
569 case ots::kVVCurveTo:
570 if (!(*in_out_found_width)) {
571 return OTS_FAILURE();
572 }
573 if (stack_size < 4) {
574 return OTS_FAILURE();
575 }
576 if (((stack_size % 4) != 0) &&
577 (((stack_size - 1) % 4) != 0)) {
578 return OTS_FAILURE();
579 }
580 while (!argument_stack->empty())
581 argument_stack->pop();
582 return true;
583
584 case ots::kHHCurveTo: {
585 bool successful = false;
586 if (!(*in_out_found_width)) {
587 return OTS_FAILURE();
588 }
589 if (stack_size < 4) {
590 return OTS_FAILURE();
591 }
592 if ((stack_size % 4) == 0) {
593 // {dxa dxb dyb dxc}+
594 successful = true;
595 } else if (((stack_size - 1) % 4) == 0) {
596 // dy1? {dxa dxb dyb dxc}+
597 successful = true;
598 }
599 while (!argument_stack->empty())
600 argument_stack->pop();
601 return successful ? true : OTS_FAILURE();
602 }
603
604 case ots::kVHCurveTo:
605 case ots::kHVCurveTo: {
606 bool successful = false;
607 if (!(*in_out_found_width)) {
608 return OTS_FAILURE();
609 }
610 if (stack_size < 4) {
611 return OTS_FAILURE();
612 }
613 if (((stack_size - 4) % 8) == 0) {
614 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}*
615 successful = true;
616 } else if ((stack_size >= 5) &&
617 ((stack_size - 5) % 8) == 0) {
618 // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf
619 successful = true;
620 } else if ((stack_size >= 8) &&
621 ((stack_size - 8) % 8) == 0) {
622 // {dxa dxb dyb dyc dyd dxe dye dxf}+
623 successful = true;
624 } else if ((stack_size >= 9) &&
625 ((stack_size - 9) % 8) == 0) {
626 // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
627 successful = true;
628 }
629 while (!argument_stack->empty())
630 argument_stack->pop();
631 return successful ? true : OTS_FAILURE();
632 }
633
634 case ots::kDotSection:
635 // Deprecated operator but harmless, we probably should drop it some how.
636 if (stack_size != 0) {
637 return OTS_FAILURE();
638 }
639 return true;
640
641 case ots::kAnd:
642 case ots::kOr:
643 case ots::kEq:
644 case ots::kAdd:
645 case ots::kSub:
646 if (stack_size < 2) {
647 return OTS_FAILURE();
648 }
649 argument_stack->pop();
650 argument_stack->pop();
651 argument_stack->push(dummy_result);
652 // TODO(yusukes): Implement this. We should push a real value for all
653 // arithmetic and conditional operations.
654 return true;
655
656 case ots::kNot:
657 case ots::kAbs:
658 case ots::kNeg:
659 if (stack_size < 1) {
660 return OTS_FAILURE();
661 }
662 argument_stack->pop();
663 argument_stack->push(dummy_result);
664 // TODO(yusukes): Implement this. We should push a real value for all
665 // arithmetic and conditional operations.
666 return true;
667
668 case ots::kDiv:
669 // TODO(yusukes): Should detect div-by-zero errors.
670 if (stack_size < 2) {
671 return OTS_FAILURE();
672 }
673 argument_stack->pop();
674 argument_stack->pop();
675 argument_stack->push(dummy_result);
676 // TODO(yusukes): Implement this. We should push a real value for all
677 // arithmetic and conditional operations.
678 return true;
679
680 case ots::kDrop:
681 if (stack_size < 1) {
682 return OTS_FAILURE();
683 }
684 argument_stack->pop();
685 return true;
686
687 case ots::kPut:
688 case ots::kGet:
689 case ots::kIndex:
690 // For now, just call OTS_FAILURE since there is no way to check whether the
691 // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType
692 // fonts I have (except malicious ones!) use the operators.
693 // TODO(yusukes): Implement them in a secure way.
694 return OTS_FAILURE();
695
696 case ots::kRoll:
697 // Likewise, just call OTS_FAILURE for kRoll since there is no way to check
698 // whether |N| is smaller than the current stack depth or not.
699 // TODO(yusukes): Implement them in a secure way.
700 return OTS_FAILURE();
701
702 case ots::kRandom:
703 // For now, we don't handle the 'random' operator since the operator makes
704 // it hard to analyze hinting code statically.
705 return OTS_FAILURE();
706
707 case ots::kIfElse:
708 if (stack_size < 4) {
709 return OTS_FAILURE();
710 }
711 argument_stack->pop();
712 argument_stack->pop();
713 argument_stack->pop();
714 argument_stack->pop();
715 argument_stack->push(dummy_result);
716 // TODO(yusukes): Implement this. We should push a real value for all
717 // arithmetic and conditional operations.
718 return true;
719
720 case ots::kMul:
721 // TODO(yusukes): Should detect overflows.
722 if (stack_size < 2) {
723 return OTS_FAILURE();
724 }
725 argument_stack->pop();
726 argument_stack->pop();
727 argument_stack->push(dummy_result);
728 // TODO(yusukes): Implement this. We should push a real value for all
729 // arithmetic and conditional operations.
730 return true;
731
732 case ots::kSqrt:
733 // TODO(yusukes): Should check if the argument is negative.
734 if (stack_size < 1) {
735 return OTS_FAILURE();
736 }
737 argument_stack->pop();
738 argument_stack->push(dummy_result);
739 // TODO(yusukes): Implement this. We should push a real value for all
740 // arithmetic and conditional operations.
741 return true;
742
743 case ots::kDup:
744 if (stack_size < 1) {
745 return OTS_FAILURE();
746 }
747 argument_stack->pop();
748 argument_stack->push(dummy_result);
749 argument_stack->push(dummy_result);
750 if (ArgumentStackOverflows(argument_stack, cff2)) {
751 return OTS_FAILURE();
752 }
753 // TODO(yusukes): Implement this. We should push a real value for all
754 // arithmetic and conditional operations.
755 return true;
756
757 case ots::kExch:
758 if (stack_size < 2) {
759 return OTS_FAILURE();
760 }
761 argument_stack->pop();
762 argument_stack->pop();
763 argument_stack->push(dummy_result);
764 argument_stack->push(dummy_result);
765 // TODO(yusukes): Implement this. We should push a real value for all
766 // arithmetic and conditional operations.
767 return true;
768
769 case ots::kHFlex:
770 if (!(*in_out_found_width)) {
771 return OTS_FAILURE();
772 }
773 if (stack_size != 7) {
774 return OTS_FAILURE();
775 }
776 while (!argument_stack->empty())
777 argument_stack->pop();
778 return true;
779
780 case ots::kFlex:
781 if (!(*in_out_found_width)) {
782 return OTS_FAILURE();
783 }
784 if (stack_size != 13) {
785 return OTS_FAILURE();
786 }
787 while (!argument_stack->empty())
788 argument_stack->pop();
789 return true;
790
791 case ots::kHFlex1:
792 if (!(*in_out_found_width)) {
793 return OTS_FAILURE();
794 }
795 if (stack_size != 9) {
796 return OTS_FAILURE();
797 }
798 while (!argument_stack->empty())
799 argument_stack->pop();
800 return true;
801
802 case ots::kFlex1:
803 if (!(*in_out_found_width)) {
804 return OTS_FAILURE();
805 }
806 if (stack_size != 11) {
807 return OTS_FAILURE();
808 }
809 while (!argument_stack->empty())
810 argument_stack->pop();
811 return true;
812 }
813
814 return OTS_FAILURE_MSG("Undefined operator: %d (0x%x)", op, op);
815 }
816
817 // Executes |char_string| and updates |argument_stack|.
818 //
819 // call_depth: The current call depth. Initial value is zero.
820 // global_subrs_index: Global subroutines.
821 // local_subrs_index: Local subroutines for the current glyph.
822 // cff_table: A whole CFF table which contains all global and local subroutines.
823 // char_string: A charstring we'll execute. |char_string| can be a main routine
824 // in CharString INDEX, or a subroutine in GlobalSubr/LocalSubr.
825 // argument_stack: The stack which an operator in |char_string| operates.
826 // out_found_endchar: true is set if |char_string| contains 'endchar'.
827 // in_out_found_width: true is set if |char_string| contains 'width' byte (which
828 // is 0 or 1 byte.)
829 // in_out_num_stems: total number of hstems and vstems processed so far.
ExecuteCharString(ots::OpenTypeCFF & cff,size_t call_depth,const ots::CFFIndex & global_subrs_index,const ots::CFFIndex & local_subrs_index,ots::Buffer * cff_table,ots::Buffer * char_string,std::stack<int32_t> * argument_stack,bool * out_found_endchar,bool * in_out_found_width,size_t * in_out_num_stems,bool cff2)830 bool ExecuteCharString(ots::OpenTypeCFF& cff,
831 size_t call_depth,
832 const ots::CFFIndex& global_subrs_index,
833 const ots::CFFIndex& local_subrs_index,
834 ots::Buffer *cff_table,
835 ots::Buffer *char_string,
836 std::stack<int32_t> *argument_stack,
837 bool *out_found_endchar,
838 bool *in_out_found_width,
839 size_t *in_out_num_stems,
840 bool cff2) {
841 if (call_depth > kMaxSubrNesting) {
842 return OTS_FAILURE();
843 }
844 *out_found_endchar = false;
845
846 bool in_out_have_blend = false, in_out_have_visindex = false;
847 int32_t in_out_vsindex = 0;
848 const size_t length = char_string->length();
849 while (char_string->offset() < length) {
850 int32_t operator_or_operand = 0;
851 bool is_operator = false;
852 if (!ReadNextNumberFromCharString(char_string,
853 &operator_or_operand,
854 &is_operator)) {
855 return OTS_FAILURE();
856 }
857
858 #ifdef DUMP_T2CHARSTRING
859 /*
860 You can dump all operators and operands (except mask bytes for hintmask
861 and cntrmask) by the following code:
862 */
863
864 if (!is_operator) {
865 std::fprintf(stderr, "%d ", operator_or_operand);
866 } else {
867 std::fprintf(stderr, "%s\n",
868 CharStringOperatorToString(
869 ots::CharStringOperator(operator_or_operand))
870 );
871 }
872 #endif
873
874 if (!is_operator) {
875 argument_stack->push(operator_or_operand);
876 if (ArgumentStackOverflows(argument_stack, cff2)) {
877 return OTS_FAILURE();
878 }
879 continue;
880 }
881
882 // An operator is found. Execute it.
883 if (!ExecuteCharStringOperator(cff,
884 operator_or_operand,
885 call_depth,
886 global_subrs_index,
887 local_subrs_index,
888 cff_table,
889 char_string,
890 argument_stack,
891 out_found_endchar,
892 in_out_found_width,
893 in_out_num_stems,
894 &in_out_have_blend,
895 &in_out_have_visindex,
896 &in_out_vsindex,
897 cff2)) {
898 return OTS_FAILURE();
899 }
900 if (*out_found_endchar) {
901 return true;
902 }
903 if (operator_or_operand == ots::kReturn) {
904 return true;
905 }
906 }
907
908 // No endchar operator is found.
909 if (cff2)
910 return true;
911 return OTS_FAILURE();
912 }
913
914 // Selects a set of subroutings for |glyph_index| from |cff| and sets it on
915 // |out_local_subrs_to_use|. Returns true on success.
SelectLocalSubr(const ots::OpenTypeCFF & cff,uint16_t glyph_index,const ots::CFFIndex ** out_local_subrs_to_use)916 bool SelectLocalSubr(const ots::OpenTypeCFF& cff,
917 uint16_t glyph_index, // 0-origin
918 const ots::CFFIndex **out_local_subrs_to_use) {
919 bool cff2 = (cff.major == 2);
920 *out_local_subrs_to_use = NULL;
921
922 // First, find local subrs from |local_subrs_per_font|.
923 if ((cff.fd_select.size() > 0) &&
924 (!cff.local_subrs_per_font.empty())) {
925 // Look up FDArray index for the glyph.
926 const auto& iter = cff.fd_select.find(glyph_index);
927 if (iter == cff.fd_select.end()) {
928 return OTS_FAILURE();
929 }
930 const auto fd_index = iter->second;
931 if (fd_index >= cff.local_subrs_per_font.size()) {
932 return OTS_FAILURE();
933 }
934 *out_local_subrs_to_use = cff.local_subrs_per_font.at(fd_index);
935 } else if (cff.local_subrs) {
936 // Second, try to use |local_subrs|. Most Latin fonts don't have FDSelect
937 // entries. If The font has a local subrs index associated with the Top
938 // DICT (not FDArrays), use it.
939 *out_local_subrs_to_use = cff.local_subrs;
940 } else if (cff2 && cff.local_subrs_per_font.size() == 1) {
941 *out_local_subrs_to_use = cff.local_subrs_per_font.at(0);
942 } else {
943 // Just return NULL.
944 *out_local_subrs_to_use = NULL;
945 }
946
947 return true;
948 }
949
950 } // namespace
951
952 namespace ots {
953
ValidateCFFCharStrings(ots::OpenTypeCFF & cff,const CFFIndex & global_subrs_index,Buffer * cff_table)954 bool ValidateCFFCharStrings(
955 ots::OpenTypeCFF& cff,
956 const CFFIndex& global_subrs_index,
957 Buffer* cff_table) {
958 const CFFIndex& char_strings_index = *(cff.charstrings_index);
959 if (char_strings_index.offsets.size() == 0) {
960 return OTS_FAILURE(); // no charstring.
961 }
962
963 bool cff2 = (cff.major == 2);
964 // For each glyph, validate the corresponding charstring.
965 for (unsigned i = 1; i < char_strings_index.offsets.size(); ++i) {
966 // Prepare a Buffer object, |char_string|, which contains the charstring
967 // for the |i|-th glyph.
968 const size_t length =
969 char_strings_index.offsets[i] - char_strings_index.offsets[i - 1];
970 if (length > kMaxCharStringLength) {
971 return OTS_FAILURE();
972 }
973 const size_t offset = char_strings_index.offsets[i - 1];
974 cff_table->set_offset(offset);
975 if (!cff_table->Skip(length)) {
976 return OTS_FAILURE();
977 }
978 Buffer char_string(cff_table->buffer() + offset, length);
979
980 // Get a local subrs for the glyph.
981 const unsigned glyph_index = i - 1; // index in the map is 0-origin.
982 const CFFIndex *local_subrs_to_use = NULL;
983 if (!SelectLocalSubr(cff,
984 glyph_index,
985 &local_subrs_to_use)) {
986 return OTS_FAILURE();
987 }
988 // If |local_subrs_to_use| is still NULL, use an empty one.
989 CFFIndex default_empty_subrs;
990 if (!local_subrs_to_use){
991 local_subrs_to_use = &default_empty_subrs;
992 }
993
994 // Check a charstring for the |i|-th glyph.
995 std::stack<int32_t> argument_stack;
996 bool found_endchar = false;
997 // CFF2 CharString has no value for width, so we start with true here to
998 // error out if width is found.
999 bool found_width = cff2;
1000 size_t num_stems = 0;
1001 if (!ExecuteCharString(cff,
1002 0 /* initial call_depth is zero */,
1003 global_subrs_index, *local_subrs_to_use,
1004 cff_table, &char_string, &argument_stack,
1005 &found_endchar, &found_width, &num_stems,
1006 cff2)) {
1007 return OTS_FAILURE();
1008 }
1009 if (!cff2 && !found_endchar) {
1010 return OTS_FAILURE();
1011 }
1012 }
1013 return true;
1014 }
1015
1016 } // namespace ots
1017
1018 #undef TABLE_NAME
1019