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