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.
EncodeOperator(int op,std::vector<uint8_t> * out_bytes)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.
EncodeNumber(int num,std::vector<uint8_t> * out_bytes)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.
AddSubr(const int * subr,size_t subr_len,std::vector<uint8_t> * out_buffer,ots::CFFIndex * out_subr)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.
Validate(const int * char_string,size_t char_string_len,const int * global_subrs,size_t global_subrs_len,const int * local_subrs,size_t local_subrs_len)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.
ValidateCharStrings(const int * char_string,size_t char_string_len)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 
TEST(ValidateTest,TestRMoveTo)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 
TEST(ValidateTest,TestHMoveTo)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 
TEST(ValidateTest,TestVMoveTo)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 
TEST(ValidateTest,TestRLineTo)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 
TEST(ValidateTest,TestHLineTo)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 
TEST(ValidateTest,TestVLineTo)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 
TEST(ValidateTest,TestRRCurveTo)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 
TEST(ValidateTest,TestHHCurveTo)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 
TEST(ValidateTest,TestHVCurveTo)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 
TEST(ValidateTest,TestRCurveLine)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 
TEST(ValidateTest,TestRLineCurve)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 
TEST(ValidateTest,TestVHCurveTo)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 
TEST(ValidateTest,TestVVCurveTo)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 
TEST(ValidateTest,TestFlex)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 
TEST(ValidateTest,TestHFlex)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 
TEST(ValidateTest,TestHFlex1)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 
TEST(ValidateTest,TestFlex1)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 
TEST(ValidateTest,TestEndChar)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 
TEST(ValidateTest,TestHStem)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 
TEST(ValidateTest,TestVStem)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 
TEST(ValidateTest,TestHStemHm)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 
TEST(ValidateTest,TestVStemHm)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 
TEST(ValidateTest,TestHintMask)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 
TEST(ValidateTest,TestCntrMask)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 
TEST(ValidateTest,TestAbs)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 
TEST(ValidateTest,TestAdd)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 
TEST(ValidateTest,TestSub)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 
TEST(ValidateTest,TestDiv)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 
TEST(ValidateTest,TestNeg)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 
TEST(ValidateTest,TestRandom)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 
TEST(ValidateTest,TestMul)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 
TEST(ValidateTest,TestSqrt)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 
TEST(ValidateTest,TestDrop)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 
TEST(ValidateTest,TestExch)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 
TEST(ValidateTest,TestIndex)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 
TEST(ValidateTest,TestRoll)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 
TEST(ValidateTest,TestDup)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 
TEST(ValidateTest,TestPut)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 
TEST(ValidateTest,TestGet)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 
TEST(ValidateTest,TestAnd)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 
TEST(ValidateTest,TestOr)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 
TEST(ValidateTest,TestNot)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 
TEST(ValidateTest,TestEq)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 
TEST(ValidateTest,TestIfElse)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 
TEST(ValidateTest,TestCallSubr)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 
TEST(ValidateTest,TestCallGSubr)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 
TEST(ValidateTest,TestCallGSubrWithComputedValues)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 
TEST(ValidateTest,TestInfiniteLoop)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 
TEST(ValidateTest,TestStackOverflow)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 
TEST(ValidateTest,TestDeprecatedOperators)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 
TEST(ValidateTest,TestUnterminatedCharString)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