tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cff_charstring_test.cc (45037B)


      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 #include "cff_charstring.h"
      6 
      7 #include <gtest/gtest.h>
      8 
      9 #include <climits>
     10 #include <vector>
     11 
     12 #include "cff.h"
     13 
     14 // Returns a biased number for callsubr and callgsubr operators.
     15 #define GET_SUBR_NUMBER(n) ((n) - 107)
     16 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
     17 
     18 namespace {
     19 
     20 // A constant which is used in AddSubr function below.
     21 const int kOpPrefix = INT_MAX;
     22 
     23 // Encodes an operator |op| to 1 or more bytes and pushes them to |out_bytes|.
     24 // Returns true if the conversion succeeds.
     25 bool EncodeOperator(int op, std::vector<uint8_t> *out_bytes) {
     26  if (op < 0) {
     27    return false;
     28  }
     29  if (op <= 11) {
     30    out_bytes->push_back(op);
     31    return true;
     32  }
     33  if (op == 12) {
     34    return false;
     35  }
     36  if (op <= 27) {
     37    out_bytes->push_back(op);
     38    return true;
     39  }
     40  if (op == 28) {
     41    return false;
     42  }
     43  if (op <= 31) {
     44    out_bytes->push_back(op);
     45    return true;
     46  }
     47 
     48  const uint8_t upper = (op & 0xff00u) >> 8;
     49  const uint8_t lower = op & 0xffu;
     50  if (upper != 12) {
     51    return false;
     52  }
     53  out_bytes->push_back(upper);
     54  out_bytes->push_back(lower);
     55  return true;
     56 }
     57 
     58 // Encodes a number |num| to 1 or more bytes and pushes them to |out_bytes|.
     59 // Returns true if the conversion succeeds. The function does not support 16.16
     60 // Fixed number.
     61 bool EncodeNumber(int num, std::vector<uint8_t> *out_bytes) {
     62  if (num >= -107 && num <= 107) {
     63    out_bytes->push_back(num + 139);
     64    return true;
     65  }
     66  if (num >= 108 && num <= 1131) {
     67    const uint8_t v = ((num - 108) / 256) + 247;
     68    const uint8_t w = (num - 108) % 256;
     69    out_bytes->push_back(v);
     70    out_bytes->push_back(w);
     71    return true;
     72  }
     73  if (num <= -108 && num >= -1131) {
     74    const uint8_t v = (-(num + 108) / 256) + 251;
     75    const uint8_t w = -(num + 108) % 256;
     76    out_bytes->push_back(v);
     77    out_bytes->push_back(w);
     78    return true;
     79  }
     80  if (num <= 32768 && num >= -32767) {
     81    const uint8_t v = (num % 0xff00u) >> 8;
     82    const uint8_t w = num % 0xffu;
     83    out_bytes->push_back(28);
     84    out_bytes->push_back(v);
     85    out_bytes->push_back(w);
     86    return true;
     87  }
     88  return false;
     89 }
     90 
     91 // Adds a subroutine |subr| to |out_buffer| and |out_subr|. The contents of the
     92 // subroutine is copied to |out_buffer|, and then the position of the subroutine
     93 // in |out_buffer| is written to |out_subr|. Returns true on success.
     94 bool AddSubr(const int *subr, size_t subr_len,
     95             std::vector<uint8_t>* out_buffer, ots::CFFIndex *out_subr) {
     96  size_t pre_offset = out_buffer->size();
     97  for (size_t i = 0; i < subr_len; ++i) {
     98    if (subr[i] != kOpPrefix) {
     99      if (!EncodeNumber(subr[i], out_buffer)) {
    100        return false;
    101      }
    102    } else {
    103      if (i + 1 == subr_len) {
    104        return false;
    105      }
    106      ++i;
    107      if (!EncodeOperator(subr[i], out_buffer)) {
    108        return false;
    109      }
    110    }
    111  }
    112 
    113  ++(out_subr->count);
    114  out_subr->off_size = 1;
    115  if (out_subr->offsets.empty()) {
    116    out_subr->offsets.push_back(pre_offset);
    117  }
    118  out_subr->offsets.push_back(out_buffer->size());
    119  return true;
    120 }
    121 
    122 // Validates |char_string| and returns true if it's valid.
    123 bool Validate(const int *char_string, size_t char_string_len,
    124              const int *global_subrs, size_t global_subrs_len,
    125              const int *local_subrs, size_t local_subrs_len) {
    126  std::vector<uint8_t> buffer;
    127  ots::CFFIndex* char_strings_index = new ots::CFFIndex;
    128  ots::CFFIndex global_subrs_index;
    129  ots::CFFIndex* local_subrs_index = new ots::CFFIndex;
    130 
    131  if (char_string) {
    132    if (!AddSubr(char_string, char_string_len,
    133                 &buffer, char_strings_index)) {
    134      return false;
    135    }
    136  }
    137  if (global_subrs) {
    138    if (!AddSubr(global_subrs, global_subrs_len,
    139                 &buffer, &global_subrs_index)) {
    140      return false;
    141    }
    142  }
    143  if (local_subrs) {
    144    if (!AddSubr(local_subrs, local_subrs_len,
    145                 &buffer, local_subrs_index)) {
    146      return false;
    147    }
    148  }
    149 
    150  ots::Buffer ots_buffer(&buffer[0], buffer.size());
    151 
    152  ots::FontFile* file = new ots::FontFile();
    153  file->context = new ots::OTSContext();
    154  ots::Font* font = new ots::Font(file);
    155  ots::OpenTypeCFF* cff = new ots::OpenTypeCFF(font, OTS_TAG_CFF);
    156  cff->charstrings_index = char_strings_index;
    157  cff->local_subrs = local_subrs_index;
    158  bool ret = ots::ValidateCFFCharStrings(*cff,
    159                                         global_subrs_index,
    160                                         &ots_buffer);
    161  delete file->context;
    162  delete file;
    163  delete font;
    164  delete cff;
    165 
    166  return ret;
    167 }
    168 
    169 // Validates |char_string| and returns true if it's valid.
    170 bool ValidateCharStrings(const int *char_string, size_t char_string_len) {
    171  return Validate(char_string, char_string_len, NULL, 0, NULL, 0);
    172 }
    173 
    174 }  // namespace
    175 
    176 TEST(ValidateTest, TestRMoveTo) {
    177  {
    178    const int char_string[] = {
    179      1, 2, kOpPrefix, ots::kRMoveTo,
    180      kOpPrefix, ots::kEndChar,
    181    };
    182    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    183  }
    184  {
    185    const int char_string[] = {
    186      1,  // width
    187      1, 2, kOpPrefix, ots::kRMoveTo,
    188      kOpPrefix, ots::kEndChar,
    189    };
    190    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    191  }
    192  {
    193    const int char_string[] = {
    194      1, 2, kOpPrefix, ots::kRMoveTo,
    195      1, 2, 3, kOpPrefix, ots::kRMoveTo,  // invalid number of args
    196      kOpPrefix, ots::kEndChar,
    197    };
    198    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    199  }
    200 }
    201 
    202 TEST(ValidateTest, TestHMoveTo) {
    203  {
    204    const int char_string[] = {
    205      1, kOpPrefix, ots::kHMoveTo,
    206      kOpPrefix, ots::kEndChar,
    207    };
    208    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    209  }
    210  {
    211    const int char_string[] = {
    212      1,  // width
    213      1, kOpPrefix, ots::kHMoveTo,
    214      kOpPrefix, ots::kEndChar,
    215    };
    216    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    217  }
    218  {
    219    const int char_string[] = {
    220      1, kOpPrefix, ots::kHMoveTo,
    221      1, 2, kOpPrefix, ots::kHMoveTo,  // invalid
    222      kOpPrefix, ots::kEndChar,
    223    };
    224    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    225  }
    226 }
    227 
    228 TEST(ValidateTest, TestVMoveTo) {
    229  {
    230    const int char_string[] = {
    231      1, kOpPrefix, ots::kVMoveTo,
    232      kOpPrefix, ots::kEndChar,
    233    };
    234    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    235  }
    236  {
    237    const int char_string[] = {
    238      1,  // width
    239      1, kOpPrefix, ots::kVMoveTo,
    240      kOpPrefix, ots::kEndChar,
    241    };
    242    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    243  }
    244  {
    245    const int char_string[] = {
    246      1, kOpPrefix, ots::kVMoveTo,
    247      1, 2, kOpPrefix, ots::kVMoveTo,  // invalid
    248      kOpPrefix, ots::kEndChar,
    249    };
    250    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    251  }
    252 }
    253 
    254 TEST(ValidateTest, TestRLineTo) {
    255  {
    256    const int char_string[] = {
    257      1, kOpPrefix, ots::kVMoveTo,
    258      1, 2, kOpPrefix, ots::kRLineTo,
    259      kOpPrefix, ots::kEndChar,
    260    };
    261    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    262  }
    263  {
    264    const int char_string[] = {
    265      1, kOpPrefix, ots::kVMoveTo,
    266      1, 2, 3, kOpPrefix, ots::kRLineTo,  // invalid
    267      kOpPrefix, ots::kEndChar,
    268    };
    269    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    270  }
    271  {
    272    const int char_string[] = {
    273      1, kOpPrefix, ots::kVMoveTo,
    274      1, 2, 3, 4, kOpPrefix, ots::kRLineTo,
    275      kOpPrefix, ots::kEndChar,
    276    };
    277    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    278  }
    279  {
    280    const int char_string[] = {
    281      1, 2, kOpPrefix, ots::kRLineTo,  // can't be the first op.
    282      kOpPrefix, ots::kEndChar,
    283    };
    284    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    285  }
    286 }
    287 
    288 TEST(ValidateTest, TestHLineTo) {
    289  {
    290    const int char_string[] = {
    291      1, kOpPrefix, ots::kVMoveTo,
    292      1, kOpPrefix, ots::kHLineTo,
    293      1, 2, kOpPrefix, ots::kHLineTo,
    294      1, 2, 3, kOpPrefix, ots::kHLineTo,
    295      1, 2, 3, 4, kOpPrefix, ots::kHLineTo,
    296      1, 2, 3, 4, 5, kOpPrefix, ots::kHLineTo,
    297      kOpPrefix, ots::kEndChar,
    298    };
    299    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    300  }
    301  {
    302    const int char_string[] = {
    303      1, kOpPrefix, ots::kVMoveTo,
    304      kOpPrefix, ots::kHLineTo,  // invalid
    305      kOpPrefix, ots::kEndChar,
    306    };
    307    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    308  }
    309  {
    310    const int char_string[] = {
    311      1, kOpPrefix, ots::kHLineTo,  // can't be the first op.
    312      kOpPrefix, ots::kEndChar,
    313    };
    314    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    315  }
    316 }
    317 
    318 TEST(ValidateTest, TestVLineTo) {
    319  {
    320    const int char_string[] = {
    321      1, kOpPrefix, ots::kVMoveTo,
    322      1, kOpPrefix, ots::kVLineTo,
    323      1, 2, kOpPrefix, ots::kVLineTo,
    324      1, 2, 3, kOpPrefix, ots::kVLineTo,
    325      1, 2, 3, 4, kOpPrefix, ots::kVLineTo,
    326      1, 2, 3, 4, 5, kOpPrefix, ots::kVLineTo,
    327      kOpPrefix, ots::kEndChar,
    328    };
    329    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    330  }
    331  {
    332    const int char_string[] = {
    333      1, kOpPrefix, ots::kVMoveTo,
    334      kOpPrefix, ots::kVLineTo,  // invalid
    335      kOpPrefix, ots::kEndChar,
    336    };
    337    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    338  }
    339  {
    340    const int char_string[] = {
    341      1, kOpPrefix, ots::kVLineTo,  // can't be the first op.
    342      kOpPrefix, ots::kEndChar,
    343    };
    344    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    345  }
    346 }
    347 
    348 TEST(ValidateTest, TestRRCurveTo) {
    349  {
    350    const int char_string[] = {
    351      1, kOpPrefix, ots::kVMoveTo,
    352      1, 2, 3, 4, 5, 6, kOpPrefix, ots::kRRCurveTo,
    353      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, kOpPrefix, ots::kRRCurveTo,
    354      kOpPrefix, ots::kEndChar,
    355    };
    356    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    357  }
    358  {
    359    const int char_string[] = {
    360      1, kOpPrefix, ots::kVMoveTo,
    361      kOpPrefix, ots::kRRCurveTo,  // invalid
    362      kOpPrefix, ots::kEndChar,
    363    };
    364    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    365  }
    366  {
    367    const int char_string[] = {
    368      1, 2, 3, 4, 5, 6, kOpPrefix, ots::kRRCurveTo,  // can't be the first op.
    369      kOpPrefix, ots::kEndChar,
    370    };
    371    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    372  }
    373 }
    374 
    375 TEST(ValidateTest, TestHHCurveTo) {
    376  {
    377    const int char_string[] = {
    378      1, kOpPrefix, ots::kVMoveTo,
    379      1, 2, 3, 4, kOpPrefix, ots::kHHCurveTo,
    380      1, 2, 3, 4, 5, kOpPrefix, ots::kHHCurveTo,
    381      1, 2, 3, 4, 5, 6, 7, 8, 9, kOpPrefix, ots::kHHCurveTo,
    382      kOpPrefix, ots::kEndChar,
    383    };
    384    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    385  }
    386  {
    387    const int char_string[] = {
    388      1, kOpPrefix, ots::kVMoveTo,
    389      1, kOpPrefix, ots::kHHCurveTo,  // invalid
    390      kOpPrefix, ots::kEndChar,
    391    };
    392    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    393  }
    394  {
    395    const int char_string[] = {
    396      1, kOpPrefix, ots::kVMoveTo,
    397      1, 2, 3, kOpPrefix, ots::kHHCurveTo,  // invalid
    398      kOpPrefix, ots::kEndChar,
    399    };
    400    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    401  }
    402  {
    403    const int char_string[] = {
    404      1, 2, 3, 4, 5, kOpPrefix, ots::kHHCurveTo,  // can't be the first op.
    405      kOpPrefix, ots::kEndChar,
    406    };
    407    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    408  }
    409 }
    410 
    411 TEST(ValidateTest, TestHVCurveTo) {
    412  {
    413    const int char_string[] = {
    414      1, kOpPrefix, ots::kVMoveTo,
    415      // The first form.
    416      1, 2, 3, 4, kOpPrefix, ots::kHVCurveTo,
    417      1, 2, 3, 4, 5, kOpPrefix, ots::kHVCurveTo,
    418      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, kOpPrefix, ots::kHVCurveTo,
    419      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
    420      kOpPrefix, ots::kHVCurveTo,
    421      // The second form.
    422      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kHVCurveTo,
    423      1, 2, 3, 4, 5, 6, 7, 8, 9, kOpPrefix, ots::kHVCurveTo,
    424      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
    425      kOpPrefix, ots::kHVCurveTo,
    426      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
    427      22, 23, 24, 25, kOpPrefix, ots::kHVCurveTo,
    428      kOpPrefix, ots::kEndChar,
    429    };
    430    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    431  }
    432  {
    433    const int char_string[] = {
    434      1, kOpPrefix, ots::kVMoveTo,
    435      1, kOpPrefix, ots::kHVCurveTo,  // invalid
    436      kOpPrefix, ots::kEndChar,
    437    };
    438    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    439  }
    440  {
    441    const int char_string[] = {
    442      1, kOpPrefix, ots::kVMoveTo,
    443      1, 2, 3, kOpPrefix, ots::kHVCurveTo,  // invalid
    444      kOpPrefix, ots::kEndChar,
    445    };
    446    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    447  }
    448  {
    449    const int char_string[] = {
    450      1, 2, 3, 4, kOpPrefix, ots::kHVCurveTo,  // can't be the first op.
    451      kOpPrefix, ots::kEndChar,
    452    };
    453    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    454  }
    455 }
    456 
    457 TEST(ValidateTest, TestRCurveLine) {
    458  {
    459    const int char_string[] = {
    460      1, kOpPrefix, ots::kVMoveTo,
    461      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kRCurveLine,
    462      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    463      kOpPrefix, ots::kRCurveLine,
    464      kOpPrefix, ots::kEndChar,
    465    };
    466    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    467  }
    468  {
    469    const int char_string[] = {
    470      1, kOpPrefix, ots::kVMoveTo,
    471      1, 2, 3, 4, 5, 6, 7, kOpPrefix, ots::kRCurveLine,  // invalid
    472      kOpPrefix, ots::kEndChar,
    473    };
    474    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    475  }
    476  {
    477    const int char_string[] = {
    478      // can't be the first op.
    479      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kRCurveLine,
    480      kOpPrefix, ots::kEndChar,
    481    };
    482    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    483  }
    484 }
    485 
    486 TEST(ValidateTest, TestRLineCurve) {
    487  {
    488    const int char_string[] = {
    489      1, kOpPrefix, ots::kVMoveTo,
    490      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kRLineCurve,
    491      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, kOpPrefix, ots::kRLineCurve,
    492      kOpPrefix, ots::kEndChar,
    493    };
    494    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    495  }
    496  {
    497    const int char_string[] = {
    498      1, kOpPrefix, ots::kVMoveTo,
    499      1, 2, 3, 4, 5, 6, 7, kOpPrefix, ots::kRLineCurve,  // invalid
    500      kOpPrefix, ots::kEndChar,
    501    };
    502    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    503  }
    504  {
    505    const int char_string[] = {
    506      // can't be the first op.
    507      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kRLineCurve,
    508      kOpPrefix, ots::kEndChar,
    509    };
    510    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    511  }
    512 }
    513 
    514 TEST(ValidateTest, TestVHCurveTo) {
    515  {
    516    const int char_string[] = {
    517      1, kOpPrefix, ots::kVMoveTo,
    518      // The first form.
    519      1, 2, 3, 4, kOpPrefix, ots::kVHCurveTo,
    520      1, 2, 3, 4, 5, kOpPrefix, ots::kVHCurveTo,
    521      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, kOpPrefix, ots::kVHCurveTo,
    522      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
    523      kOpPrefix, ots::kVHCurveTo,
    524      // The second form.
    525      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kVHCurveTo,
    526      1, 2, 3, 4, 5, 6, 7, 8, 9, kOpPrefix, ots::kVHCurveTo,
    527      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
    528      kOpPrefix, ots::kVHCurveTo,
    529      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
    530      22, 23, 24, 25, kOpPrefix, ots::kVHCurveTo,
    531      kOpPrefix, ots::kEndChar,
    532    };
    533    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    534  }
    535  {
    536    const int char_string[] = {
    537      1, kOpPrefix, ots::kVMoveTo,
    538      1, kOpPrefix, ots::kVHCurveTo,  // invalid
    539      kOpPrefix, ots::kEndChar,
    540    };
    541    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    542  }
    543  {
    544    const int char_string[] = {
    545      1, kOpPrefix, ots::kVMoveTo,
    546      1, 2, 3, kOpPrefix, ots::kVHCurveTo,  // invalid
    547      kOpPrefix, ots::kEndChar,
    548    };
    549    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    550  }
    551  {
    552    const int char_string[] = {
    553      1, 2, 3, 4, kOpPrefix, ots::kVHCurveTo,  // can't be the first op.
    554      kOpPrefix, ots::kEndChar,
    555    };
    556    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    557  }
    558 }
    559 
    560 TEST(ValidateTest, TestVVCurveTo) {
    561  {
    562    const int char_string[] = {
    563      1, kOpPrefix, ots::kVMoveTo,
    564      1, 2, 3, 4, kOpPrefix, ots::kVVCurveTo,
    565      1, 2, 3, 4, 5, kOpPrefix, ots::kVVCurveTo,
    566      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kVVCurveTo,
    567      1, 2, 3, 4, 5, 6, 7, 8, 9, kOpPrefix, ots::kVVCurveTo,
    568      kOpPrefix, ots::kEndChar,
    569    };
    570    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    571  }
    572  {
    573    const int char_string[] = {
    574      1, kOpPrefix, ots::kVMoveTo,
    575      kOpPrefix, ots::kVVCurveTo,  // invalid
    576      kOpPrefix, ots::kEndChar,
    577    };
    578    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    579  }
    580  {
    581    const int char_string[] = {
    582      1, kOpPrefix, ots::kVMoveTo,
    583      1, kOpPrefix, ots::kVVCurveTo,  // invalid
    584      kOpPrefix, ots::kEndChar,
    585    };
    586    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    587  }
    588  {
    589    const int char_string[] = {
    590      1, 2, 3, 4, kOpPrefix, ots::kVVCurveTo,  // can't be the first op.
    591      kOpPrefix, ots::kEndChar,
    592    };
    593    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    594  }
    595 }
    596 
    597 TEST(ValidateTest, TestFlex) {
    598  {
    599    const int char_string[] = {
    600      1, kOpPrefix, ots::kVMoveTo,
    601      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, kOpPrefix, ots::kFlex,
    602      kOpPrefix, ots::kEndChar,
    603    };
    604    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    605  }
    606  {
    607    const int char_string[] = {
    608      1, kOpPrefix, ots::kVMoveTo,
    609      kOpPrefix, ots::kFlex,  // invalid
    610      kOpPrefix, ots::kEndChar,
    611    };
    612    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    613  }
    614  {
    615    const int char_string[] = {
    616      1, kOpPrefix, ots::kVMoveTo,
    617      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, kOpPrefix, ots::kFlex,  // invalid
    618      kOpPrefix, ots::kEndChar,
    619    };
    620    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    621  }
    622  {
    623    const int char_string[] = {
    624      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, kOpPrefix, ots::kFlex,
    625      kOpPrefix, ots::kEndChar,
    626    };
    627    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    628  }
    629 }
    630 
    631 TEST(ValidateTest, TestHFlex) {
    632  {
    633    const int char_string[] = {
    634      1, kOpPrefix, ots::kVMoveTo,
    635      1, 2, 3, 4, 5, 6, 7, kOpPrefix, ots::kHFlex,
    636      kOpPrefix, ots::kEndChar,
    637    };
    638    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    639  }
    640  {
    641    const int char_string[] = {
    642      1, kOpPrefix, ots::kVMoveTo,
    643      kOpPrefix, ots::kHFlex,  // invalid
    644      kOpPrefix, ots::kEndChar,
    645    };
    646    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    647  }
    648  {
    649    const int char_string[] = {
    650      1, kOpPrefix, ots::kVMoveTo,
    651      1, 2, 3, 4, 5, 6, kOpPrefix, ots::kHFlex,  // invalid
    652      kOpPrefix, ots::kEndChar,
    653    };
    654    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    655  }
    656  {
    657    const int char_string[] = {
    658      1, 2, 3, 4, 5, 6, 7, kOpPrefix, ots::kHFlex,
    659      kOpPrefix, ots::kEndChar,
    660    };
    661    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    662  }
    663 }
    664 
    665 TEST(ValidateTest, TestHFlex1) {
    666  {
    667    const int char_string[] = {
    668      1, kOpPrefix, ots::kVMoveTo,
    669      1, 2, 3, 4, 5, 6, 7, 8, 9, kOpPrefix, ots::kHFlex1,
    670      kOpPrefix, ots::kEndChar,
    671    };
    672    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    673  }
    674  {
    675    const int char_string[] = {
    676      1, kOpPrefix, ots::kVMoveTo,
    677      kOpPrefix, ots::kHFlex1,  // invalid
    678      kOpPrefix, ots::kEndChar,
    679    };
    680    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    681  }
    682  {
    683    const int char_string[] = {
    684      1, kOpPrefix, ots::kVMoveTo,
    685      1, 2, 3, 4, 5, 6, 7, 8, kOpPrefix, ots::kHFlex1,  // invalid
    686      kOpPrefix, ots::kEndChar,
    687    };
    688    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    689  }
    690  {
    691    const int char_string[] = {
    692      1, 2, 3, 4, 5, 6, 7, 8, 9, kOpPrefix, ots::kHFlex1,
    693      kOpPrefix, ots::kEndChar,
    694    };
    695    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    696  }
    697 }
    698 
    699 TEST(ValidateTest, TestFlex1) {
    700  {
    701    const int char_string[] = {
    702      1, kOpPrefix, ots::kVMoveTo,
    703      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, kOpPrefix, ots::kFlex1,
    704      kOpPrefix, ots::kEndChar,
    705    };
    706    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    707  }
    708  {
    709    const int char_string[] = {
    710      1, kOpPrefix, ots::kVMoveTo,
    711      kOpPrefix, ots::kFlex1,  // invalid
    712      kOpPrefix, ots::kEndChar,
    713    };
    714    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    715  }
    716  {
    717    const int char_string[] = {
    718      1, kOpPrefix, ots::kVMoveTo,
    719      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, kOpPrefix, ots::kFlex1,  // invalid
    720      kOpPrefix, ots::kEndChar,
    721    };
    722    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    723  }
    724  {
    725    const int char_string[] = {
    726      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, kOpPrefix, ots::kFlex1,
    727      kOpPrefix, ots::kEndChar,
    728    };
    729    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    730  }
    731 }
    732 
    733 TEST(ValidateTest, TestEndChar) {
    734  {
    735    const int char_string[] = {
    736      kOpPrefix, ots::kEndChar,
    737    };
    738    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    739  }
    740  {
    741    const int char_string[] = {
    742      1, kOpPrefix, ots::kVMoveTo,
    743      kOpPrefix, ots::kEndChar,
    744    };
    745    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    746  }
    747  {
    748    const int char_string[] = {
    749      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallSubr,
    750    };
    751    const int local_subrs[] = {
    752      kOpPrefix, ots::kEndChar,
    753    };
    754    EXPECT_TRUE(Validate(char_string, ARRAYSIZE(char_string),
    755                         NULL, 0,
    756                         local_subrs, ARRAYSIZE(local_subrs)));
    757  }
    758  {
    759    const int char_string[] = {
    760      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallGSubr,
    761    };
    762    const int global_subrs[] = {
    763      kOpPrefix, ots::kEndChar,
    764    };
    765    EXPECT_TRUE(Validate(char_string, ARRAYSIZE(char_string),
    766                         global_subrs, ARRAYSIZE(global_subrs),
    767                         NULL, 0));
    768  }
    769 }
    770 
    771 TEST(ValidateTest, TestHStem) {
    772  {
    773    const int char_string[] = {
    774      1, 2, kOpPrefix, ots::kHStem,
    775      kOpPrefix, ots::kEndChar,
    776    };
    777    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    778  }
    779  {
    780    const int char_string[] = {
    781      1, 2, 3, 4, kOpPrefix, ots::kHStem,
    782      kOpPrefix, ots::kEndChar,
    783    };
    784    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    785  }
    786  {
    787    const int char_string[] = {
    788      0,  // width
    789      1, 2, kOpPrefix, ots::kHStem,
    790      kOpPrefix, ots::kEndChar,
    791    };
    792    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    793  }
    794  {
    795    const int char_string[] = {
    796      1, kOpPrefix, ots::kVMoveTo,
    797      0, 1, 2, kOpPrefix, ots::kHStem,  // invalid
    798      kOpPrefix, ots::kEndChar,
    799    };
    800    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    801  }
    802  {
    803    const int char_string[] = {
    804      1, kOpPrefix, ots::kVMoveTo,
    805      1, 2, 3, 4, 5, kOpPrefix, ots::kHStem,  // invalid
    806      kOpPrefix, ots::kEndChar,
    807    };
    808    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    809  }
    810 }
    811 
    812 TEST(ValidateTest, TestVStem) {
    813  {
    814    const int char_string[] = {
    815      1, 2, kOpPrefix, ots::kVStem,
    816      kOpPrefix, ots::kEndChar,
    817    };
    818    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    819  }
    820  {
    821    const int char_string[] = {
    822      1, 2, 3, 4, kOpPrefix, ots::kVStem,
    823      kOpPrefix, ots::kEndChar,
    824    };
    825    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    826  }
    827  {
    828    const int char_string[] = {
    829      0,  // width
    830      1, 2, kOpPrefix, ots::kVStem,
    831      kOpPrefix, ots::kEndChar,
    832    };
    833    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    834  }
    835  {
    836    const int char_string[] = {
    837      1, kOpPrefix, ots::kVMoveTo,
    838      0, 1, 2, kOpPrefix, ots::kVStem,  // invalid
    839      kOpPrefix, ots::kEndChar,
    840    };
    841    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    842  }
    843  {
    844    const int char_string[] = {
    845      1, kOpPrefix, ots::kVMoveTo,
    846      1, 2, 3, 4, 5, kOpPrefix, ots::kVStem,  // invalid
    847      kOpPrefix, ots::kEndChar,
    848    };
    849    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    850  }
    851 }
    852 
    853 TEST(ValidateTest, TestHStemHm) {
    854  {
    855    const int char_string[] = {
    856      1, 2, kOpPrefix, ots::kHStemHm,
    857      kOpPrefix, ots::kEndChar,
    858    };
    859    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    860  }
    861  {
    862    const int char_string[] = {
    863      1, 2, 3, 4, kOpPrefix, ots::kHStemHm,
    864      kOpPrefix, ots::kEndChar,
    865    };
    866    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    867  }
    868  {
    869    const int char_string[] = {
    870      0,  // width
    871      1, 2, kOpPrefix, ots::kHStemHm,
    872      kOpPrefix, ots::kEndChar,
    873    };
    874    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    875  }
    876  {
    877    const int char_string[] = {
    878      1, kOpPrefix, ots::kVMoveTo,
    879      0, 1, 2, kOpPrefix, ots::kHStemHm,  // invalid
    880      kOpPrefix, ots::kEndChar,
    881    };
    882    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    883  }
    884  {
    885    const int char_string[] = {
    886      1, kOpPrefix, ots::kVMoveTo,
    887      1, 2, 3, 4, 5, kOpPrefix, ots::kHStemHm,  // invalid
    888      kOpPrefix, ots::kEndChar,
    889    };
    890    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    891  }
    892 }
    893 
    894 TEST(ValidateTest, TestVStemHm) {
    895  {
    896    const int char_string[] = {
    897      1, 2, kOpPrefix, ots::kVStemHm,
    898      kOpPrefix, ots::kEndChar,
    899    };
    900    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    901  }
    902  {
    903    const int char_string[] = {
    904      1, 2, 3, 4, kOpPrefix, ots::kVStemHm,
    905      kOpPrefix, ots::kEndChar,
    906    };
    907    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    908  }
    909  {
    910    const int char_string[] = {
    911      0,  // width
    912      1, 2, kOpPrefix, ots::kVStemHm,
    913      kOpPrefix, ots::kEndChar,
    914    };
    915    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    916  }
    917  {
    918    const int char_string[] = {
    919      1, kOpPrefix, ots::kVMoveTo,
    920      0, 1, 2, kOpPrefix, ots::kVStemHm,  // invalid
    921      kOpPrefix, ots::kEndChar,
    922    };
    923    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    924  }
    925  {
    926    const int char_string[] = {
    927      1, kOpPrefix, ots::kVMoveTo,
    928      1, 2, 3, 4, 5, kOpPrefix, ots::kVStemHm,  // invalid
    929      kOpPrefix, ots::kEndChar,
    930    };
    931    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    932  }
    933 }
    934 
    935 TEST(ValidateTest, TestHintMask) {
    936  {
    937    const int char_string[] = {
    938      1, 2, kOpPrefix, ots::kHStem,
    939      kOpPrefix, ots::kHintMask, 0x00,
    940      kOpPrefix, ots::kEndChar,
    941    };
    942    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    943  }
    944  {
    945    const int char_string[] = {
    946      1, 2, kOpPrefix, ots::kHStem,
    947      3, 4, 5, 6, kOpPrefix, ots::kHintMask, 0x00,  // vstem
    948      kOpPrefix, ots::kEndChar,
    949    };
    950    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    951  }
    952  {
    953    const int char_string[] = {
    954      kOpPrefix, ots::kHintMask, 0x00,  // no stems to mask
    955      kOpPrefix, ots::kEndChar,
    956    };
    957    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    958  }
    959  {
    960    const int char_string[] = {
    961      1, 2, kOpPrefix, ots::kHStem,
    962      3, 4, 5, kOpPrefix, ots::kHintMask, 0x00,  // invalid vstem
    963      kOpPrefix, ots::kEndChar,
    964    };
    965    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    966  }
    967 }
    968 
    969 TEST(ValidateTest, TestCntrMask) {
    970  {
    971    const int char_string[] = {
    972      1, 2, kOpPrefix, ots::kHStem,
    973      kOpPrefix, ots::kCntrMask, 0x00,
    974      kOpPrefix, ots::kEndChar,
    975    };
    976    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    977  }
    978  {
    979    const int char_string[] = {
    980      1, 2, kOpPrefix, ots::kHStem,
    981      3, 4, 5, 6, kOpPrefix, ots::kCntrMask, 0x00,  // vstem
    982      kOpPrefix, ots::kEndChar,
    983    };
    984    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    985  }
    986  {
    987    const int char_string[] = {
    988      kOpPrefix, ots::kCntrMask, 0x00,  // no stems to mask
    989      kOpPrefix, ots::kEndChar,
    990    };
    991    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
    992  }
    993  {
    994    const int char_string[] = {
    995      1, 2, kOpPrefix, ots::kHStem,
    996      3, 4, 5, kOpPrefix, ots::kCntrMask, 0x00,  // invalid vstem
    997      kOpPrefix, ots::kEndChar,
    998    };
    999    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1000  }
   1001 }
   1002 
   1003 TEST(ValidateTest, TestAbs) {
   1004  {
   1005    const int char_string[] = {
   1006      -1, kOpPrefix, ots::kAbs,
   1007      2, kOpPrefix, ots::kHStem,
   1008      kOpPrefix, ots::kEndChar,
   1009    };
   1010    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1011  }
   1012  {
   1013    const int char_string[] = {
   1014      kOpPrefix, ots::kAbs,  // invalid
   1015      2, kOpPrefix, ots::kHStem,
   1016      kOpPrefix, ots::kEndChar,
   1017    };
   1018    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1019  }
   1020 }
   1021 
   1022 TEST(ValidateTest, TestAdd) {
   1023  {
   1024    const int char_string[] = {
   1025      0, 1, kOpPrefix, ots::kAdd,
   1026      2, kOpPrefix, ots::kHStem,
   1027      kOpPrefix, ots::kEndChar,
   1028    };
   1029    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1030  }
   1031  {
   1032    const int char_string[] = {
   1033      1, kOpPrefix, ots::kAdd,  // invalid
   1034      2, kOpPrefix, ots::kHStem,
   1035      kOpPrefix, ots::kEndChar,
   1036    };
   1037    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1038  }
   1039 }
   1040 
   1041 TEST(ValidateTest, TestSub) {
   1042  {
   1043    const int char_string[] = {
   1044      2, 1, kOpPrefix, ots::kSub,
   1045      2, kOpPrefix, ots::kHStem,
   1046      kOpPrefix, ots::kEndChar,
   1047    };
   1048    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1049  }
   1050  {
   1051    const int char_string[] = {
   1052      1, kOpPrefix, ots::kSub,  // invalid
   1053      2, kOpPrefix, ots::kHStem,
   1054      kOpPrefix, ots::kEndChar,
   1055    };
   1056    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1057  }
   1058 }
   1059 
   1060 TEST(ValidateTest, TestDiv) {
   1061  // TODO(yusukes): Test div-by-zero.
   1062  {
   1063    const int char_string[] = {
   1064      2, 1, kOpPrefix, ots::kDiv,
   1065      2, kOpPrefix, ots::kHStem,
   1066      kOpPrefix, ots::kEndChar,
   1067    };
   1068    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1069  }
   1070  {
   1071    const int char_string[] = {
   1072      1, kOpPrefix, ots::kDiv,  // invalid
   1073      2, kOpPrefix, ots::kHStem,
   1074      kOpPrefix, ots::kEndChar,
   1075    };
   1076    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1077  }
   1078 }
   1079 
   1080 TEST(ValidateTest, TestNeg) {
   1081  {
   1082    const int char_string[] = {
   1083      -1, kOpPrefix, ots::kNeg,
   1084      2, kOpPrefix, ots::kHStem,
   1085      kOpPrefix, ots::kEndChar,
   1086    };
   1087    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1088  }
   1089  {
   1090    const int char_string[] = {
   1091      kOpPrefix, ots::kNeg,  // invalid
   1092      2, kOpPrefix, ots::kHStem,
   1093      kOpPrefix, ots::kEndChar,
   1094    };
   1095    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1096  }
   1097 }
   1098 
   1099 TEST(ValidateTest, TestRandom) {
   1100  {
   1101    const int char_string[] = {
   1102      kOpPrefix, ots::kRandom,  // OTS rejects the operator.
   1103      2, kOpPrefix, ots::kHStem,
   1104      kOpPrefix, ots::kEndChar,
   1105    };
   1106    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1107  }
   1108 }
   1109 
   1110 TEST(ValidateTest, TestMul) {
   1111  {
   1112    const int char_string[] = {
   1113      2, 1, kOpPrefix, ots::kMul,
   1114      2, kOpPrefix, ots::kHStem,
   1115      kOpPrefix, ots::kEndChar,
   1116    };
   1117    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1118  }
   1119  {
   1120    const int char_string[] = {
   1121      1, kOpPrefix, ots::kMul,  // invalid
   1122      2, kOpPrefix, ots::kHStem,
   1123      kOpPrefix, ots::kEndChar,
   1124    };
   1125    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1126  }
   1127 }
   1128 
   1129 TEST(ValidateTest, TestSqrt) {
   1130  // TODO(yusukes): Test negative numbers.
   1131  {
   1132    const int char_string[] = {
   1133      4, kOpPrefix, ots::kSqrt,
   1134      2, kOpPrefix, ots::kHStem,
   1135      kOpPrefix, ots::kEndChar,
   1136    };
   1137    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1138  }
   1139  {
   1140    const int char_string[] = {
   1141      kOpPrefix, ots::kSqrt,  // invalid
   1142      2, kOpPrefix, ots::kHStem,
   1143      kOpPrefix, ots::kEndChar,
   1144    };
   1145    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1146  }
   1147 }
   1148 
   1149 TEST(ValidateTest, TestDrop) {
   1150  {
   1151    const int char_string[] = {
   1152      1, 1, kOpPrefix, ots::kAdd,
   1153      kOpPrefix, ots::kDrop,
   1154      1, 2, kOpPrefix, ots::kHStem,
   1155      kOpPrefix, ots::kEndChar,
   1156    };
   1157    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1158  }
   1159  {
   1160    const int char_string[] = {
   1161      kOpPrefix, ots::kDrop,  // invalid
   1162      1, 2, kOpPrefix, ots::kHStem,
   1163      kOpPrefix, ots::kEndChar,
   1164    };
   1165    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1166  }
   1167 }
   1168 
   1169 TEST(ValidateTest, TestExch) {
   1170  {
   1171    const int char_string[] = {
   1172      1, 1, kOpPrefix, ots::kAdd,
   1173      kOpPrefix, ots::kDup,
   1174      kOpPrefix, ots::kExch,
   1175      kOpPrefix, ots::kHStem,
   1176      kOpPrefix, ots::kEndChar,
   1177    };
   1178    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1179  }
   1180  {
   1181    const int char_string[] = {
   1182      1, 1, kOpPrefix, ots::kAdd,
   1183      kOpPrefix, ots::kExch,  // invalid
   1184      2, kOpPrefix, ots::kHStem,
   1185      kOpPrefix, ots::kEndChar,
   1186    };
   1187    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1188  }
   1189 }
   1190 
   1191 TEST(ValidateTest, TestIndex) {
   1192  {
   1193    const int char_string[] = {
   1194      1, 2, 3, -1, kOpPrefix, ots::kIndex,  // OTS rejects the operator.
   1195      kOpPrefix, ots::kHStem,
   1196      kOpPrefix, ots::kEndChar,
   1197    };
   1198    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1199  }
   1200 }
   1201 
   1202 TEST(ValidateTest, TestRoll) {
   1203  {
   1204    const int char_string[] = {
   1205      1, 2, 2, 1, kOpPrefix, ots::kRoll,  // OTS rejects the operator.
   1206      kOpPrefix, ots::kHStem,
   1207      kOpPrefix, ots::kEndChar,
   1208    };
   1209    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1210  }
   1211 }
   1212 
   1213 TEST(ValidateTest, TestDup) {
   1214  {
   1215    const int char_string[] = {
   1216      1, 1, kOpPrefix, ots::kAdd,
   1217      kOpPrefix, ots::kDup,
   1218      kOpPrefix, ots::kHStem,
   1219      kOpPrefix, ots::kEndChar,
   1220    };
   1221    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1222  }
   1223  {
   1224    const int char_string[] = {
   1225      kOpPrefix, ots::kDup,  // invalid
   1226      2, kOpPrefix, ots::kHStem,
   1227      kOpPrefix, ots::kEndChar,
   1228    };
   1229    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1230  }
   1231 }
   1232 
   1233 TEST(ValidateTest, TestPut) {
   1234  {
   1235    const int char_string[] = {
   1236      1, 10, kOpPrefix, ots::kPut,  // OTS rejects the operator.
   1237      1, 2, kOpPrefix, ots::kHStem,
   1238      kOpPrefix, ots::kEndChar,
   1239    };
   1240    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1241  }
   1242 }
   1243 
   1244 TEST(ValidateTest, TestGet) {
   1245  {
   1246    const int char_string[] = {
   1247      1, 10, kOpPrefix, ots::kGet,  // OTS rejects the operator.
   1248      1, 2, kOpPrefix, ots::kHStem,
   1249      kOpPrefix, ots::kEndChar,
   1250    };
   1251    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1252  }
   1253 }
   1254 
   1255 TEST(ValidateTest, TestAnd) {
   1256  {
   1257    const int char_string[] = {
   1258      2, 1, kOpPrefix, ots::kAnd,
   1259      2, kOpPrefix, ots::kHStem,
   1260      kOpPrefix, ots::kEndChar,
   1261    };
   1262    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1263  }
   1264  {
   1265    const int char_string[] = {
   1266      1, kOpPrefix, ots::kAnd,  // invalid
   1267      2, kOpPrefix, ots::kHStem,
   1268      kOpPrefix, ots::kEndChar,
   1269    };
   1270    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1271  }
   1272 }
   1273 
   1274 TEST(ValidateTest, TestOr) {
   1275  {
   1276    const int char_string[] = {
   1277      2, 1, kOpPrefix, ots::kOr,
   1278      2, kOpPrefix, ots::kHStem,
   1279      kOpPrefix, ots::kEndChar,
   1280    };
   1281    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1282  }
   1283  {
   1284    const int char_string[] = {
   1285      1, kOpPrefix, ots::kOr,  // invalid
   1286      2, kOpPrefix, ots::kHStem,
   1287      kOpPrefix, ots::kEndChar,
   1288    };
   1289    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1290  }
   1291 }
   1292 
   1293 TEST(ValidateTest, TestNot) {
   1294  {
   1295    const int char_string[] = {
   1296      1, kOpPrefix, ots::kNot,
   1297      2, kOpPrefix, ots::kHStem,
   1298      kOpPrefix, ots::kEndChar,
   1299    };
   1300    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1301  }
   1302  {
   1303    const int char_string[] = {
   1304      kOpPrefix, ots::kNot,  // invalid
   1305      2, kOpPrefix, ots::kHStem,
   1306      kOpPrefix, ots::kEndChar,
   1307    };
   1308    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1309  }
   1310 }
   1311 
   1312 TEST(ValidateTest, TestEq) {
   1313  {
   1314    const int char_string[] = {
   1315      2, 1, kOpPrefix, ots::kEq,
   1316      2, kOpPrefix, ots::kHStem,
   1317      kOpPrefix, ots::kEndChar,
   1318    };
   1319    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1320  }
   1321  {
   1322    const int char_string[] = {
   1323      1, kOpPrefix, ots::kEq,  // invalid
   1324      2, kOpPrefix, ots::kHStem,
   1325      kOpPrefix, ots::kEndChar,
   1326    };
   1327    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1328  }
   1329 }
   1330 
   1331 TEST(ValidateTest, TestIfElse) {
   1332  {
   1333    const int char_string[] = {
   1334      1, 2, 3, 4, kOpPrefix, ots::kIfElse,
   1335      2, kOpPrefix, ots::kHStem,
   1336      kOpPrefix, ots::kEndChar,
   1337    };
   1338    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1339  }
   1340  {
   1341    const int char_string[] = {
   1342      1, 2, 3, kOpPrefix, ots::kIfElse,  // invalid
   1343      2, kOpPrefix, ots::kHStem,
   1344      kOpPrefix, ots::kEndChar,
   1345    };
   1346    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1347  }
   1348 }
   1349 
   1350 TEST(ValidateTest, TestCallSubr) {
   1351  // Call valid subr.
   1352  {
   1353    const int char_string[] = {
   1354      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallSubr,
   1355    };
   1356    const int local_subrs[] = {
   1357      kOpPrefix, ots::kEndChar,
   1358    };
   1359    EXPECT_TRUE(Validate(char_string, ARRAYSIZE(char_string),
   1360                         NULL, 0,
   1361                         local_subrs, ARRAYSIZE(local_subrs)));
   1362  }
   1363  // Call undefined subr.
   1364  {
   1365    const int char_string[] = {
   1366      GET_SUBR_NUMBER(-1), kOpPrefix, ots::kCallSubr,
   1367    };
   1368    const int local_subrs[] = {
   1369      kOpPrefix, ots::kEndChar,
   1370    };
   1371    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1372                          NULL, 0,
   1373                          local_subrs, ARRAYSIZE(local_subrs)));
   1374  }
   1375  {
   1376    const int char_string[] = {
   1377      GET_SUBR_NUMBER(1), kOpPrefix, ots::kCallSubr,
   1378    };
   1379    const int local_subrs[] = {
   1380      kOpPrefix, ots::kEndChar,
   1381    };
   1382    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1383                          NULL, 0,
   1384                          local_subrs, ARRAYSIZE(local_subrs)));
   1385  }
   1386  {
   1387    const int char_string[] = {
   1388      GET_SUBR_NUMBER(-1), kOpPrefix, ots::kCallSubr,
   1389    };
   1390    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1391  }
   1392  {
   1393    const int char_string[] = {
   1394      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallSubr,
   1395    };
   1396    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1397  }
   1398  {
   1399    const int char_string[] = {
   1400      GET_SUBR_NUMBER(1), kOpPrefix, ots::kCallSubr,
   1401    };
   1402    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1403  }
   1404 }
   1405 
   1406 TEST(ValidateTest, TestCallGSubr) {
   1407  // Call valid subr.
   1408  {
   1409    const int char_string[] = {
   1410      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallGSubr,
   1411    };
   1412    const int global_subrs[] = {
   1413      kOpPrefix, ots::kEndChar,
   1414    };
   1415    EXPECT_TRUE(Validate(char_string, ARRAYSIZE(char_string),
   1416                         global_subrs, ARRAYSIZE(global_subrs),
   1417                         NULL, 0));
   1418  }
   1419  // Call undefined subr.
   1420  {
   1421    const int char_string[] = {
   1422      GET_SUBR_NUMBER(-1), kOpPrefix, ots::kCallGSubr,
   1423    };
   1424    const int global_subrs[] = {
   1425      kOpPrefix, ots::kEndChar,
   1426    };
   1427    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1428                          global_subrs, ARRAYSIZE(global_subrs),
   1429                          NULL, 0));
   1430  }
   1431  {
   1432    const int char_string[] = {
   1433      GET_SUBR_NUMBER(1), kOpPrefix, ots::kCallGSubr,
   1434    };
   1435    const int global_subrs[] = {
   1436      kOpPrefix, ots::kEndChar,
   1437    };
   1438    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1439                          global_subrs, ARRAYSIZE(global_subrs),
   1440                          NULL, 0));
   1441  }
   1442  {
   1443    const int char_string[] = {
   1444      GET_SUBR_NUMBER(-1), kOpPrefix, ots::kCallGSubr,
   1445    };
   1446    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1447  }
   1448  {
   1449    const int char_string[] = {
   1450      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallGSubr,
   1451    };
   1452    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1453  }
   1454  {
   1455    const int char_string[] = {
   1456      GET_SUBR_NUMBER(1), kOpPrefix, ots::kCallGSubr,
   1457    };
   1458    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1459  }
   1460 }
   1461 
   1462 TEST(ValidateTest, TestCallGSubrWithComputedValues) {
   1463  {
   1464    // OTS does not allow to call(g)subr with a subroutine number which is
   1465    // not a immediate value for safety.
   1466    const int char_string[] = {
   1467      0, 0, kOpPrefix, ots::kAdd,
   1468      kOpPrefix, ots::kCallGSubr,
   1469    };
   1470    const int global_subrs[] = {
   1471      kOpPrefix, ots::kEndChar,
   1472    };
   1473    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1474                          global_subrs, ARRAYSIZE(global_subrs),
   1475                          NULL, 0));
   1476  }
   1477 }
   1478 
   1479 TEST(ValidateTest, TestInfiniteLoop) {
   1480  {
   1481    const int char_string[] = {
   1482      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallSubr,
   1483    };
   1484    const int local_subrs[] = {
   1485      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallSubr,
   1486    };
   1487    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1488                          NULL, 0,
   1489                          local_subrs, ARRAYSIZE(local_subrs)));
   1490  }
   1491  {
   1492    const int char_string[] = {
   1493      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallGSubr,
   1494    };
   1495    const int global_subrs[] = {
   1496      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallGSubr,
   1497    };
   1498    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1499                          global_subrs, ARRAYSIZE(global_subrs),
   1500                          NULL, 0));
   1501  }
   1502  // mutual recursion which doesn't stop.
   1503  {
   1504    const int char_string[] = {
   1505      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallSubr,
   1506    };
   1507    const int global_subrs[] = {
   1508      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallSubr,
   1509    };
   1510    const int local_subrs[] = {
   1511      GET_SUBR_NUMBER(0), kOpPrefix, ots::kCallGSubr,
   1512    };
   1513    EXPECT_FALSE(Validate(char_string, ARRAYSIZE(char_string),
   1514                          global_subrs, ARRAYSIZE(global_subrs),
   1515                          local_subrs, ARRAYSIZE(local_subrs)));
   1516  }
   1517 }
   1518 
   1519 TEST(ValidateTest, TestStackOverflow) {
   1520  {
   1521    const int char_string[] = {
   1522      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1523      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1524      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1525      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1526      1, 2, 3, 4, 5, 6, 7, 8,
   1527      kOpPrefix, ots::kEndChar,
   1528    };
   1529    EXPECT_TRUE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1530  }
   1531  {
   1532    const int char_string[] = {
   1533      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1534      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1535      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1536      1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   1537      1, 2, 3, 4, 5, 6, 7, 8, 9,  // overflow
   1538      kOpPrefix, ots::kEndChar,
   1539    };
   1540    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1541  }
   1542 }
   1543 
   1544 TEST(ValidateTest, TestDeprecatedOperators) {
   1545  {
   1546    const int char_string[] = {
   1547      kOpPrefix, 16,  // 'blend'.
   1548      kOpPrefix, ots::kEndChar,
   1549    };
   1550    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1551  }
   1552  {
   1553    const int char_string[] = {
   1554      kOpPrefix, (12 << 8) + 8,  // 'store'.
   1555      kOpPrefix, ots::kEndChar,
   1556    };
   1557    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1558  }
   1559  {
   1560    const int char_string[] = {
   1561      kOpPrefix, (12 << 8) + 13,  // 'load'.
   1562      kOpPrefix, ots::kEndChar,
   1563    };
   1564    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1565  }
   1566 }
   1567 
   1568 TEST(ValidateTest, TestUnterminatedCharString) {
   1569  // No endchar operator.
   1570  {
   1571    const int char_string[] = {
   1572      123,
   1573    };
   1574    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1575  }
   1576  {
   1577    const int char_string[] = {
   1578      123, 456,
   1579    };
   1580    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1581  }
   1582  {
   1583    const int char_string[] = {
   1584      123, 456, kOpPrefix, ots::kReturn,
   1585    };
   1586    EXPECT_FALSE(ValidateCharStrings(char_string, ARRAYSIZE(char_string)));
   1587  }
   1588 }