Home | History | Annotate | Download | only in src
      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 
     17 namespace {
     18 
     19 // Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical
     20 // Note #5177.
     21 const int32_t kMaxSubrsCount = 65536;
     22 const size_t kMaxCharStringLength = 65535;
     23 const size_t kMaxArgumentStack = 48;
     24 const size_t kMaxNumberOfStemHints = 96;
     25 const 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.
     29 const int32_t dummy_result = INT_MAX;
     30 
     31 bool 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.
     44 bool 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.
    119 bool 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.
    615 bool 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.
    688 bool 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 
    724 namespace ots {
    725 
    726 bool 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