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