1// Copyright (c) 2010 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// A parser for the Type 2 Charstring Format.
6// http://www.adobe.com/devnet/font/pdfs/5177.Type2.pdf
7
8#include "cff_type2_charstring.h"
9
10#include <climits>
11#include <cstdio>
12#include <cstring>
13#include <stack>
14#include <string>
15#include <utility>
16
17namespace {
18
19// Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical
20// Note #5177.
21const int32_t kMaxSubrsCount = 65536;
22const size_t kMaxCharStringLength = 65535;
23const size_t kMaxArgumentStack = 48;
24const size_t kMaxNumberOfStemHints = 96;
25const size_t kMaxSubrNesting = 10;
26
27// |dummy_result| should be a huge positive integer so callsubr and callgsubr
28// will fail with the dummy value.
29const int32_t dummy_result = INT_MAX;
30
31bool ExecuteType2CharString(size_t call_depth,
32                            const ots::CFFIndex& global_subrs_index,
33                            const ots::CFFIndex& local_subrs_index,
34                            ots::Buffer *cff_table,
35                            ots::Buffer *char_string,
36                            std::stack<int32_t> *argument_stack,
37                            bool *out_found_endchar,
38                            bool *out_found_width,
39                            size_t *in_out_num_stems);
40
41// Read one or more bytes from the |char_string| buffer and stores the number
42// read on |out_number|. If the number read is an operator (ex 'vstem'), sets
43// true on |out_is_operator|. Returns true if the function read a number.
44bool ReadNextNumberFromType2CharString(ots::Buffer *char_string,
45                                       int32_t *out_number,
46                                       bool *out_is_operator) {
47  uint8_t v = 0;
48  if (!char_string->ReadU8(&v)) {
49    return OTS_FAILURE();
50  }
51  *out_is_operator = false;
52
53  // The conversion algorithm is described in Adobe Technical Note #5177, page
54  // 13, Table 1.
55  if (v <= 11) {
56    *out_number = v;
57    *out_is_operator = true;
58  } else if (v == 12) {
59    uint16_t result = (v << 8);
60    if (!char_string->ReadU8(&v)) {
61      return OTS_FAILURE();
62    }
63    result += v;
64    *out_number = result;
65    *out_is_operator = true;
66  } else if (v <= 27) {
67    // Special handling for v==19 and v==20 are implemented in
68    // ExecuteType2CharStringOperator().
69    *out_number = v;
70    *out_is_operator = true;
71  } else if (v == 28) {
72    if (!char_string->ReadU8(&v)) {
73      return OTS_FAILURE();
74    }
75    uint16_t result = (v << 8);
76    if (!char_string->ReadU8(&v)) {
77      return OTS_FAILURE();
78    }
79    result += v;
80    *out_number = result;
81  } else if (v <= 31) {
82    *out_number = v;
83    *out_is_operator = true;
84  } else if (v <= 246) {
85    *out_number = static_cast<int32_t>(v) - 139;
86  } else if (v <= 250) {
87    uint8_t w = 0;
88    if (!char_string->ReadU8(&w)) {
89      return OTS_FAILURE();
90    }
91    *out_number = ((static_cast<int32_t>(v) - 247) * 256) +
92        static_cast<int32_t>(w) + 108;
93  } else if (v <= 254) {
94    uint8_t w = 0;
95    if (!char_string->ReadU8(&w)) {
96      return OTS_FAILURE();
97    }
98    *out_number = -((static_cast<int32_t>(v) - 251) * 256) -
99        static_cast<int32_t>(w) - 108;
100  } else if (v == 255) {
101    // TODO(yusukes): We should not skip the 4 bytes. Note that when v is 255,
102    // we should treat the following 4-bytes as a 16.16 fixed-point number
103    // rather than 32bit signed int.
104    if (!char_string->Skip(4)) {
105      return OTS_FAILURE();
106    }
107    *out_number = dummy_result;
108  } else {
109    return OTS_FAILURE();
110  }
111
112  return true;
113}
114
115// Executes |op| and updates |argument_stack|. Returns true if the execution
116// succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively
117// calls ExecuteType2CharString() function. The arguments other than |op| and
118// |argument_stack| are passed for that reason.
119bool ExecuteType2CharStringOperator(int32_t op,
120                                    size_t call_depth,
121                                    const ots::CFFIndex& global_subrs_index,
122                                    const ots::CFFIndex& local_subrs_index,
123                                    ots::Buffer *cff_table,
124                                    ots::Buffer *char_string,
125                                    std::stack<int32_t> *argument_stack,
126                                    bool *out_found_endchar,
127                                    bool *in_out_found_width,
128                                    size_t *in_out_num_stems) {
129  const size_t stack_size = argument_stack->size();
130
131  switch (op) {
132  case ots::kCallSubr:
133  case ots::kCallGSubr: {
134    const ots::CFFIndex& subrs_index =
135        (op == ots::kCallSubr ? local_subrs_index : global_subrs_index);
136
137    if (stack_size < 1) {
138      return OTS_FAILURE();
139    }
140    int32_t subr_number = argument_stack->top();
141    argument_stack->pop();
142    if (subr_number == dummy_result) {
143      // For safety, we allow subr calls only with immediate subr numbers for
144      // now. For example, we allow "123 callgsubr", but does not allow "100 12
145      // add callgsubr". Please note that arithmetic and conditional operators
146      // always push the |dummy_result| in this implementation.
147      return OTS_FAILURE();
148    }
149
150    // See Adobe Technical Note #5176 (CFF), "16. Local/GlobalSubrs INDEXes."
151    int32_t bias = 32768;
152    if (subrs_index.count < 1240) {
153      bias = 107;
154    } else if (subrs_index.count < 33900) {
155      bias = 1131;
156    }
157    subr_number += bias;
158
159    // Sanity checks of |subr_number|.
160    if (subr_number < 0) {
161      return OTS_FAILURE();
162    }
163    if (subr_number >= kMaxSubrsCount) {
164      return OTS_FAILURE();
165    }
166    if (subrs_index.offsets.size() <= static_cast<size_t>(subr_number + 1)) {
167      return OTS_FAILURE();  // The number is out-of-bounds.
168    }
169
170    // Prepare ots::Buffer where we're going to jump.
171    const size_t length =
172      subrs_index.offsets[subr_number + 1] - subrs_index.offsets[subr_number];
173    if (length > kMaxCharStringLength) {
174      return OTS_FAILURE();
175    }
176    const size_t offset = subrs_index.offsets[subr_number];
177    cff_table->set_offset(offset);
178    if (!cff_table->Skip(length)) {
179      return OTS_FAILURE();
180    }
181    ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length);
182
183    return ExecuteType2CharString(call_depth + 1,
184                                  global_subrs_index,
185                                  local_subrs_index,
186                                  cff_table,
187                                  &char_string_to_jump,
188                                  argument_stack,
189                                  out_found_endchar,
190                                  in_out_found_width,
191                                  in_out_num_stems);
192  }
193
194  case ots::kReturn:
195    return true;
196
197  case ots::kEndChar:
198    *out_found_endchar = true;
199    *in_out_found_width = true;  // just in case.
200    return true;
201
202  case ots::kHStem:
203  case ots::kVStem:
204  case ots::kHStemHm:
205  case ots::kVStemHm: {
206    bool successful = false;
207    if (stack_size < 2) {
208      return OTS_FAILURE();
209    }
210    if ((stack_size % 2) == 0) {
211      successful = true;
212    } else if ((!(*in_out_found_width)) && (((stack_size - 1) % 2) == 0)) {
213      // The -1 is for "width" argument. For details, see Adobe Technical Note
214      // #5177, page 16, note 4.
215      successful = true;
216    }
217    (*in_out_num_stems) += (stack_size / 2);
218    if ((*in_out_num_stems) > kMaxNumberOfStemHints) {
219      return OTS_FAILURE();
220    }
221    while (!argument_stack->empty())
222      argument_stack->pop();
223    *in_out_found_width = true;  // always set true since "w" might be 0 byte.
224    return successful ? true : OTS_FAILURE();
225  }
226
227  case ots::kRMoveTo: {
228    bool successful = false;
229    if (stack_size == 2) {
230      successful = true;
231    } else if ((!(*in_out_found_width)) && (stack_size - 1 == 2)) {
232      successful = true;
233    }
234    while (!argument_stack->empty())
235      argument_stack->pop();
236    *in_out_found_width = true;
237    return successful ? true : OTS_FAILURE();
238  }
239
240  case ots::kVMoveTo:
241  case ots::kHMoveTo: {
242    bool successful = false;
243    if (stack_size == 1) {
244      successful = true;
245    } else if ((!(*in_out_found_width)) && (stack_size - 1 == 1)) {
246      successful = true;
247    }
248    while (!argument_stack->empty())
249      argument_stack->pop();
250    *in_out_found_width = true;
251    return successful ? true : OTS_FAILURE();
252  }
253
254  case ots::kHintMask:
255  case ots::kCntrMask: {
256    bool successful = false;
257    if (stack_size == 0) {
258      successful = true;
259    } else if ((!(*in_out_found_width)) && (stack_size == 1)) {
260      // A number for "width" is found.
261      successful = true;
262    } else if ((!(*in_out_found_width)) ||  // in this case, any sizes are ok.
263               ((stack_size % 2) == 0)) {
264      // The numbers are vstem definition.
265      // See Adobe Technical Note #5177, page 24, hintmask.
266      (*in_out_num_stems) += (stack_size / 2);
267      if ((*in_out_num_stems) > kMaxNumberOfStemHints) {
268        return OTS_FAILURE();
269      }
270      successful = true;
271    }
272    if (!successful) {
273       return OTS_FAILURE();
274    }
275
276    if ((*in_out_num_stems) == 0) {
277      return OTS_FAILURE();
278    }
279    const size_t mask_bytes = (*in_out_num_stems + 7) / 8;
280    if (!char_string->Skip(mask_bytes)) {
281      return OTS_FAILURE();
282    }
283    while (!argument_stack->empty())
284      argument_stack->pop();
285    *in_out_found_width = true;
286    return true;
287  }
288
289  case ots::kRLineTo:
290    if (!(*in_out_found_width)) {
291      // The first stack-clearing operator should be one of hstem, hstemhm,
292      // vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, rmoveto, or
293      // endchar. For details, see Adobe Technical Note #5177, page 16, note 4.
294      return OTS_FAILURE();
295    }
296    if (stack_size < 2) {
297      return OTS_FAILURE();
298    }
299    if ((stack_size % 2) != 0) {
300      return OTS_FAILURE();
301    }
302    while (!argument_stack->empty())
303      argument_stack->pop();
304    return true;
305
306  case ots::kHLineTo:
307  case ots::kVLineTo:
308    if (!(*in_out_found_width)) {
309      return OTS_FAILURE();
310    }
311    if (stack_size < 1) {
312      return OTS_FAILURE();
313    }
314    while (!argument_stack->empty())
315      argument_stack->pop();
316    return true;
317
318  case ots::kRRCurveTo:
319    if (!(*in_out_found_width)) {
320      return OTS_FAILURE();
321    }
322    if (stack_size < 6) {
323      return OTS_FAILURE();
324    }
325    if ((stack_size % 6) != 0) {
326      return OTS_FAILURE();
327    }
328    while (!argument_stack->empty())
329      argument_stack->pop();
330    return true;
331
332  case ots::kRCurveLine:
333    if (!(*in_out_found_width)) {
334      return OTS_FAILURE();
335    }
336    if (stack_size < 8) {
337      return OTS_FAILURE();
338    }
339    if (((stack_size - 2) % 6) != 0) {
340      return OTS_FAILURE();
341    }
342    while (!argument_stack->empty())
343      argument_stack->pop();
344    return true;
345
346  case ots::kRLineCurve:
347    if (!(*in_out_found_width)) {
348      return OTS_FAILURE();
349    }
350    if (stack_size < 8) {
351      return OTS_FAILURE();
352    }
353    if (((stack_size - 6) % 2) != 0) {
354      return OTS_FAILURE();
355    }
356    while (!argument_stack->empty())
357      argument_stack->pop();
358    return true;
359
360  case ots::kVVCurveTo:
361    if (!(*in_out_found_width)) {
362      return OTS_FAILURE();
363    }
364    if (stack_size < 4) {
365      return OTS_FAILURE();
366    }
367    if (((stack_size % 4) != 0) &&
368        (((stack_size - 1) % 4) != 0)) {
369      return OTS_FAILURE();
370    }
371    while (!argument_stack->empty())
372      argument_stack->pop();
373    return true;
374
375  case ots::kHHCurveTo: {
376    bool successful = false;
377    if (!(*in_out_found_width)) {
378      return OTS_FAILURE();
379    }
380    if (stack_size < 4) {
381      return OTS_FAILURE();
382    }
383    if ((stack_size % 4) == 0) {
384      // {dxa dxb dyb dxc}+
385      successful = true;
386    } else if (((stack_size - 1) % 4) == 0) {
387      // dy1? {dxa dxb dyb dxc}+
388      successful = true;
389    }
390    while (!argument_stack->empty())
391      argument_stack->pop();
392    return successful ? true : OTS_FAILURE();
393  }
394
395  case ots::kVHCurveTo:
396  case ots::kHVCurveTo: {
397    bool successful = false;
398    if (!(*in_out_found_width)) {
399      return OTS_FAILURE();
400    }
401    if (stack_size < 4) {
402      return OTS_FAILURE();
403    }
404    if (((stack_size - 4) % 8) == 0) {
405      // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}*
406      successful = true;
407    } else if ((stack_size >= 5) &&
408               ((stack_size - 5) % 8) == 0) {
409      // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf
410      successful = true;
411    } else if ((stack_size >= 8) &&
412               ((stack_size - 8) % 8) == 0) {
413      // {dxa dxb dyb dyc dyd dxe dye dxf}+
414      successful = true;
415    } else if ((stack_size >= 9) &&
416               ((stack_size - 9) % 8) == 0) {
417      // {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
418      successful = true;
419    }
420    while (!argument_stack->empty())
421      argument_stack->pop();
422    return successful ? true : OTS_FAILURE();
423  }
424
425  case ots::kAnd:
426  case ots::kOr:
427  case ots::kEq:
428  case ots::kAdd:
429  case ots::kSub:
430    if (stack_size < 2) {
431      return OTS_FAILURE();
432    }
433    argument_stack->pop();
434    argument_stack->pop();
435    argument_stack->push(dummy_result);
436    // TODO(yusukes): Implement this. We should push a real value for all
437    // arithmetic and conditional operations.
438    return true;
439
440  case ots::kNot:
441  case ots::kAbs:
442  case ots::kNeg:
443    if (stack_size < 1) {
444      return OTS_FAILURE();
445    }
446    argument_stack->pop();
447    argument_stack->push(dummy_result);
448    // TODO(yusukes): Implement this. We should push a real value for all
449    // arithmetic and conditional operations.
450    return true;
451
452  case ots::kDiv:
453    // TODO(yusukes): Should detect div-by-zero errors.
454    if (stack_size < 2) {
455      return OTS_FAILURE();
456    }
457    argument_stack->pop();
458    argument_stack->pop();
459    argument_stack->push(dummy_result);
460    // TODO(yusukes): Implement this. We should push a real value for all
461    // arithmetic and conditional operations.
462    return true;
463
464  case ots::kDrop:
465    if (stack_size < 1) {
466      return OTS_FAILURE();
467    }
468    argument_stack->pop();
469    return true;
470
471  case ots::kPut:
472  case ots::kGet:
473  case ots::kIndex:
474    // For now, just call OTS_FAILURE since there is no way to check whether the
475    // index argument, |i|, is out-of-bounds or not. Fortunately, no OpenType
476    // fonts I have (except malicious ones!) use the operators.
477    // TODO(yusukes): Implement them in a secure way.
478    return OTS_FAILURE();
479
480  case ots::kRoll:
481    // Likewise, just call OTS_FAILURE for kRoll since there is no way to check
482    // whether |N| is smaller than the current stack depth or not.
483    // TODO(yusukes): Implement them in a secure way.
484    return OTS_FAILURE();
485
486  case ots::kRandom:
487    // For now, we don't handle the 'random' operator since the operator makes
488    // it hard to analyze hinting code statically.
489    return OTS_FAILURE();
490
491  case ots::kIfElse:
492    if (stack_size < 4) {
493      return OTS_FAILURE();
494    }
495    argument_stack->pop();
496    argument_stack->pop();
497    argument_stack->pop();
498    argument_stack->pop();
499    argument_stack->push(dummy_result);
500    // TODO(yusukes): Implement this. We should push a real value for all
501    // arithmetic and conditional operations.
502    return true;
503
504  case ots::kMul:
505    // TODO(yusukes): Should detect overflows.
506    if (stack_size < 2) {
507      return OTS_FAILURE();
508    }
509    argument_stack->pop();
510    argument_stack->pop();
511    argument_stack->push(dummy_result);
512    // TODO(yusukes): Implement this. We should push a real value for all
513    // arithmetic and conditional operations.
514    return true;
515
516  case ots::kSqrt:
517    // TODO(yusukes): Should check if the argument is negative.
518    if (stack_size < 1) {
519      return OTS_FAILURE();
520    }
521    argument_stack->pop();
522    argument_stack->push(dummy_result);
523    // TODO(yusukes): Implement this. We should push a real value for all
524    // arithmetic and conditional operations.
525    return true;
526
527  case ots::kDup:
528    if (stack_size < 1) {
529      return OTS_FAILURE();
530    }
531    argument_stack->pop();
532    argument_stack->push(dummy_result);
533    argument_stack->push(dummy_result);
534    if (argument_stack->size() > kMaxArgumentStack) {
535      return OTS_FAILURE();
536    }
537    // TODO(yusukes): Implement this. We should push a real value for all
538    // arithmetic and conditional operations.
539    return true;
540
541  case ots::kExch:
542    if (stack_size < 2) {
543      return OTS_FAILURE();
544    }
545    argument_stack->pop();
546    argument_stack->pop();
547    argument_stack->push(dummy_result);
548    argument_stack->push(dummy_result);
549    // TODO(yusukes): Implement this. We should push a real value for all
550    // arithmetic and conditional operations.
551    return true;
552
553  case ots::kHFlex:
554    if (!(*in_out_found_width)) {
555      return OTS_FAILURE();
556    }
557    if (stack_size != 7) {
558      return OTS_FAILURE();
559    }
560    while (!argument_stack->empty())
561      argument_stack->pop();
562    return true;
563
564  case ots::kFlex:
565    if (!(*in_out_found_width)) {
566      return OTS_FAILURE();
567    }
568    if (stack_size != 13) {
569      return OTS_FAILURE();
570    }
571    while (!argument_stack->empty())
572      argument_stack->pop();
573    return true;
574
575  case ots::kHFlex1:
576    if (!(*in_out_found_width)) {
577      return OTS_FAILURE();
578    }
579    if (stack_size != 9) {
580      return OTS_FAILURE();
581    }
582    while (!argument_stack->empty())
583      argument_stack->pop();
584    return true;
585
586  case ots::kFlex1:
587    if (!(*in_out_found_width)) {
588      return OTS_FAILURE();
589    }
590    if (stack_size != 11) {
591      return OTS_FAILURE();
592    }
593    while (!argument_stack->empty())
594      argument_stack->pop();
595    return true;
596  }
597
598  OTS_WARNING("Undefined operator: %d (0x%x)", op, op);
599  return OTS_FAILURE();
600}
601
602// Executes |char_string| and updates |argument_stack|.
603//
604// call_depth: The current call depth. Initial value is zero.
605// global_subrs_index: Global subroutines.
606// local_subrs_index: Local subroutines for the current glyph.
607// cff_table: A whole CFF table which contains all global and local subroutines.
608// char_string: A charstring we'll execute. |char_string| can be a main routine
609//              in CharString INDEX, or a subroutine in GlobalSubr/LocalSubr.
610// argument_stack: The stack which an operator in |char_string| operates.
611// out_found_endchar: true is set if |char_string| contains 'endchar'.
612// in_out_found_width: true is set if |char_string| contains 'width' byte (which
613//                     is 0 or 1 byte.)
614// in_out_num_stems: total number of hstems and vstems processed so far.
615bool ExecuteType2CharString(size_t call_depth,
616                            const ots::CFFIndex& global_subrs_index,
617                            const ots::CFFIndex& local_subrs_index,
618                            ots::Buffer *cff_table,
619                            ots::Buffer *char_string,
620                            std::stack<int32_t> *argument_stack,
621                            bool *out_found_endchar,
622                            bool *in_out_found_width,
623                            size_t *in_out_num_stems) {
624  if (call_depth > kMaxSubrNesting) {
625    return OTS_FAILURE();
626  }
627  *out_found_endchar = false;
628
629  const size_t length = char_string->length();
630  while (char_string->offset() < length) {
631    int32_t operator_or_operand = 0;
632    bool is_operator = false;
633    if (!ReadNextNumberFromType2CharString(char_string,
634                                           &operator_or_operand,
635                                           &is_operator)) {
636      return OTS_FAILURE();
637    }
638
639    /*
640      You can dump all operators and operands (except mask bytes for hintmask
641      and cntrmask) by the following code:
642
643      if (!is_operator) {
644        std::fprintf(stderr, "#%d# ", operator_or_operand);
645      } else {
646        std::fprintf(stderr, "#%s#\n",
647           Type2CharStringOperatorToString(
648               Type2CharStringOperator(operator_or_operand)),
649           operator_or_operand);
650      }
651    */
652
653    if (!is_operator) {
654      argument_stack->push(operator_or_operand);
655      if (argument_stack->size() > kMaxArgumentStack) {
656        return OTS_FAILURE();
657      }
658      continue;
659    }
660
661    // An operator is found. Execute it.
662    if (!ExecuteType2CharStringOperator(operator_or_operand,
663                                        call_depth,
664                                        global_subrs_index,
665                                        local_subrs_index,
666                                        cff_table,
667                                        char_string,
668                                        argument_stack,
669                                        out_found_endchar,
670                                        in_out_found_width,
671                                        in_out_num_stems)) {
672      return OTS_FAILURE();
673    }
674    if (*out_found_endchar) {
675      return true;
676    }
677    if (operator_or_operand == ots::kReturn) {
678      return true;
679    }
680  }
681
682  // No endchar operator is found.
683  return OTS_FAILURE();
684}
685
686// Selects a set of subroutings for |glyph_index| from |cff| and sets it on
687// |out_local_subrs_to_use|. Returns true on success.
688bool SelectLocalSubr(const std::map<uint16_t, uint8_t> &fd_select,
689                     const std::vector<ots::CFFIndex *> &local_subrs_per_font,
690                     const ots::CFFIndex *local_subrs,
691                     uint16_t glyph_index,  // 0-origin
692                     const ots::CFFIndex **out_local_subrs_to_use) {
693  *out_local_subrs_to_use = NULL;
694
695  // First, find local subrs from |local_subrs_per_font|.
696  if ((fd_select.size() > 0) &&
697      (!local_subrs_per_font.empty())) {
698    // Look up FDArray index for the glyph.
699    std::map<uint16_t, uint8_t>::const_iterator iter =
700        fd_select.find(glyph_index);
701    if (iter == fd_select.end()) {
702      return OTS_FAILURE();
703    }
704    const uint8_t fd_index = iter->second;
705    if (fd_index >= local_subrs_per_font.size()) {
706      return OTS_FAILURE();
707    }
708    *out_local_subrs_to_use = local_subrs_per_font.at(fd_index);
709  } else if (local_subrs) {
710    // Second, try to use |local_subrs|. Most Latin fonts don't have FDSelect
711    // entries. If The font has a local subrs index associated with the Top
712    // DICT (not FDArrays), use it.
713    *out_local_subrs_to_use = local_subrs;
714  } else {
715    // Just return NULL.
716    *out_local_subrs_to_use = NULL;
717  }
718
719  return true;
720}
721
722}  // namespace
723
724namespace ots {
725
726bool ValidateType2CharStringIndex(
727    const CFFIndex& char_strings_index,
728    const CFFIndex& global_subrs_index,
729    const std::map<uint16_t, uint8_t> &fd_select,
730    const std::vector<CFFIndex *> &local_subrs_per_font,
731    const CFFIndex *local_subrs,
732    Buffer* cff_table) {
733  if (char_strings_index.offsets.size() == 0) {
734    return OTS_FAILURE();  // no charstring.
735  }
736
737  // For each glyph, validate the corresponding charstring.
738  for (unsigned i = 1; i < char_strings_index.offsets.size(); ++i) {
739    // Prepare a Buffer object, |char_string|, which contains the charstring
740    // for the |i|-th glyph.
741    const size_t length =
742      char_strings_index.offsets[i] - char_strings_index.offsets[i - 1];
743    if (length > kMaxCharStringLength) {
744      return OTS_FAILURE();
745    }
746    const size_t offset = char_strings_index.offsets[i - 1];
747    cff_table->set_offset(offset);
748    if (!cff_table->Skip(length)) {
749      return OTS_FAILURE();
750    }
751    Buffer char_string(cff_table->buffer() + offset, length);
752
753    // Get a local subrs for the glyph.
754    const unsigned glyph_index = i - 1;  // index in the map is 0-origin.
755    const CFFIndex *local_subrs_to_use = NULL;
756    if (!SelectLocalSubr(fd_select,
757                         local_subrs_per_font,
758                         local_subrs,
759                         glyph_index,
760                         &local_subrs_to_use)) {
761      return OTS_FAILURE();
762    }
763    // If |local_subrs_to_use| is still NULL, use an empty one.
764    CFFIndex default_empty_subrs;
765    if (!local_subrs_to_use){
766      local_subrs_to_use = &default_empty_subrs;
767    }
768
769    // Check a charstring for the |i|-th glyph.
770    std::stack<int32_t> argument_stack;
771    bool found_endchar = false;
772    bool found_width = false;
773    size_t num_stems = 0;
774    if (!ExecuteType2CharString(0 /* initial call_depth is zero */,
775                                global_subrs_index, *local_subrs_to_use,
776                                cff_table, &char_string, &argument_stack,
777                                &found_endchar, &found_width, &num_stems)) {
778      return OTS_FAILURE();
779    }
780    if (!found_endchar) {
781      return OTS_FAILURE();
782    }
783  }
784  return true;
785}
786
787}  // namespace ots
788