1 // Copyright (c) 2011-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 <cmath>
6 #include <vector>
7 #include <gtest/gtest.h>
8
9 #include "layout.h"
10 #include "ots-memory-stream.h"
11
12 namespace {
13
14 const uint32_t kFakeTag = 0x00000000;
15 const size_t kScriptRecordSize = 6;
16 const size_t kLangSysRecordSize = 6;
17
BuildFakeScriptListTable(ots::OTSStream * out,const uint16_t script_count,const uint16_t langsys_count,const uint16_t feature_count)18 bool BuildFakeScriptListTable(ots::OTSStream *out, const uint16_t script_count,
19 const uint16_t langsys_count,
20 const uint16_t feature_count) {
21 if (!out->WriteU16(script_count)) {
22 return false;
23 }
24 const off_t script_record_end = out->Tell() +
25 kScriptRecordSize * script_count;
26 const size_t script_table_size = 4 + kLangSysRecordSize * langsys_count;
27 for (unsigned i = 0; i < script_count; ++i) {
28 if (!out->WriteU32(kFakeTag) ||
29 !out->WriteU16(script_record_end + i * script_table_size)) {
30 return false;
31 }
32 }
33
34 // Offsets to LangSys tables are measured from the beginning of each
35 // script table.
36 const off_t langsys_record_end = 4 + kLangSysRecordSize * langsys_count;
37 const size_t langsys_table_size = 6 + 2 * feature_count;
38 // Write Fake Script tables.
39 for (unsigned i = 0; i < script_count; ++i) {
40 if (!out->WriteU16(0x0000) ||
41 !out->WriteU16(langsys_count)) {
42 return false;
43 }
44 for (unsigned j = 0; j < langsys_count; ++j) {
45 if (!out->WriteU32(kFakeTag) ||
46 !out->WriteU16(langsys_record_end + j * langsys_table_size)) {
47 return false;
48 }
49 }
50 }
51
52 // Write Fake LangSys tables.
53 for (unsigned i = 0; i < langsys_count; ++i) {
54 if (!out->WriteU16(0x0000) ||
55 !out->WriteU16(0xFFFF) ||
56 !out->WriteU16(feature_count)) {
57 return false;
58 }
59 for (unsigned j = 0; j < feature_count; ++j) {
60 if (!out->WriteU16(j)) {
61 return false;
62 }
63 }
64 }
65 return true;
66 }
67
68 const size_t kFeatureRecordSize = 6;
69
BuildFakeFeatureListTable(ots::OTSStream * out,const uint16_t feature_count,const uint16_t lookup_count)70 bool BuildFakeFeatureListTable(ots::OTSStream *out,
71 const uint16_t feature_count,
72 const uint16_t lookup_count) {
73 if (!out->WriteU16(feature_count)) {
74 return false;
75 }
76 const off_t feature_record_end = out->Tell() +
77 kFeatureRecordSize * feature_count;
78 const size_t feature_table_size = 4 + 2 * lookup_count;
79 for (unsigned i = 0; i < feature_count; ++i) {
80 if (!out->WriteU32(kFakeTag) ||
81 !out->WriteU16(feature_record_end + i * feature_table_size)) {
82 return false;
83 }
84 }
85
86 // Write FeatureTable
87 for (unsigned i = 0; i < feature_count; ++i) {
88 if (!out->WriteU16(0x0000) ||
89 !out->WriteU16(lookup_count)) {
90 return false;
91 }
92 for (uint16_t j = 0; j < lookup_count; ++j) {
93 if (!out->WriteU16(j)) {
94 return false;
95 }
96 }
97 }
98 return true;
99 }
100
BuildFakeLookupListTable(ots::OTSStream * out,const uint16_t lookup_count,const uint16_t subtable_count)101 bool BuildFakeLookupListTable(ots::OTSStream *out, const uint16_t lookup_count,
102 const uint16_t subtable_count) {
103 if (!out->WriteU16(lookup_count)) {
104 return false;
105 }
106 const off_t base_offset_lookup = out->Tell();
107 if (!out->Pad(2 * lookup_count)) {
108 return false;
109 }
110
111 std::vector<off_t> offsets_lookup(lookup_count, 0);
112 for (uint16_t i = 0; i < lookup_count; ++i) {
113 offsets_lookup[i] = out->Tell();
114 if (!out->WriteU16(i + 1) ||
115 !out->WriteU16(0) ||
116 !out->WriteU16(subtable_count) ||
117 !out->Pad(2 * subtable_count) ||
118 !out->WriteU16(0)) {
119 return false;
120 }
121 }
122
123 const off_t offset_lookup_table_end = out->Tell();
124 // Allocate 256 bytes for each subtable.
125 if (!out->Pad(256 * lookup_count * subtable_count)) {
126 return false;
127 }
128
129 if (!out->Seek(base_offset_lookup)) {
130 return false;
131 }
132 for (unsigned i = 0; i < lookup_count; ++i) {
133 if (!out->WriteU16(offsets_lookup[i])) {
134 return false;
135 }
136 }
137
138 for (unsigned i = 0; i < lookup_count; ++i) {
139 if (!out->Seek(offsets_lookup[i] + 6)) {
140 return false;
141 }
142 for (unsigned j = 0; j < subtable_count; ++j) {
143 if (!out->WriteU16(offset_lookup_table_end +
144 256*i*subtable_count + 256*j)) {
145 return false;
146 }
147 }
148 }
149 return true;
150 }
151
BuildFakeCoverageFormat1(ots::OTSStream * out,const uint16_t glyph_count)152 bool BuildFakeCoverageFormat1(ots::OTSStream *out, const uint16_t glyph_count) {
153 if (!out->WriteU16(1) || !out->WriteU16(glyph_count)) {
154 return false;
155 }
156 for (uint16_t glyph_id = 1; glyph_id <= glyph_count; ++glyph_id) {
157 if (!out->WriteU16(glyph_id)) {
158 return false;
159 }
160 }
161 return true;
162 }
163
BuildFakeCoverageFormat2(ots::OTSStream * out,const uint16_t range_count)164 bool BuildFakeCoverageFormat2(ots::OTSStream *out, const uint16_t range_count) {
165 if (!out->WriteU16(2) || !out->WriteU16(range_count)) {
166 return false;
167 }
168 uint16_t glyph_id = 1;
169 uint16_t start_coverage_index = 0;
170 for (unsigned i = 0; i < range_count; ++i) {
171 // Write consecutive ranges in which each range consists of two glyph id.
172 if (!out->WriteU16(glyph_id) ||
173 !out->WriteU16(glyph_id + 1) ||
174 !out->WriteU16(start_coverage_index)) {
175 return false;
176 }
177 glyph_id += 2;
178 start_coverage_index += 2;
179 }
180 return true;
181 }
182
BuildFakeClassDefFormat1(ots::OTSStream * out,const uint16_t glyph_count)183 bool BuildFakeClassDefFormat1(ots::OTSStream *out, const uint16_t glyph_count) {
184 if (!out->WriteU16(1) ||
185 !out->WriteU16(1) ||
186 !out->WriteU16(glyph_count)) {
187 return false;
188 }
189 for (uint16_t class_value = 1; class_value <= glyph_count; ++class_value) {
190 if (!out->WriteU16(class_value)) {
191 return false;
192 }
193 }
194 return true;
195 }
196
BuildFakeClassDefFormat2(ots::OTSStream * out,const uint16_t range_count)197 bool BuildFakeClassDefFormat2(ots::OTSStream *out, const uint16_t range_count) {
198 if (!out->WriteU16(2) || !out->WriteU16(range_count)) {
199 return false;
200 }
201 uint16_t glyph_id = 1;
202 for (uint16_t class_value = 1; class_value <= range_count; ++class_value) {
203 // Write consecutive ranges in which each range consists of one glyph id.
204 if (!out->WriteU16(glyph_id) ||
205 !out->WriteU16(glyph_id + 1) ||
206 !out->WriteU16(class_value)) {
207 return false;
208 }
209 glyph_id += 2;
210 }
211 return true;
212 }
213
BuildFakeDeviceTable(ots::OTSStream * out,const uint16_t start_size,const uint16_t end_size,const uint16_t format)214 bool BuildFakeDeviceTable(ots::OTSStream *out, const uint16_t start_size,
215 const uint16_t end_size, const uint16_t format) {
216 if (!out->WriteU16(start_size) ||
217 !out->WriteU16(end_size) ||
218 !out->WriteU16(format)) {
219 return false;
220 }
221
222 const unsigned num_values = std::abs(end_size - start_size) + 1;
223 const unsigned num_bits = (1 << format) * num_values;
224 const unsigned num_units = (num_bits - 1) / 16 + 1;
225 if (!out->Pad(num_units * 2)) {
226 return false;
227 }
228 return true;
229 }
230
231 class TestStream : public ots::MemoryStream {
232 public:
TestStream()233 TestStream()
234 : ots::MemoryStream(data_, sizeof(data_)), size_(0) {
235 std::memset(reinterpret_cast<char*>(data_), 0, sizeof(data_));
236 }
237
data()238 uint8_t* data() { return data_; }
size() const239 size_t size() const { return size_; }
240
WriteRaw(const void * d,size_t length)241 virtual bool WriteRaw(const void *d, size_t length) {
242 if (Tell() + length > size_) {
243 size_ = Tell() + length;
244 }
245 return ots::MemoryStream::WriteRaw(d, length);
246 }
247
248 private:
249 size_t size_;
250 uint8_t data_[4096];
251 };
252
253 class TableTest : public ::testing::Test {
254 protected:
255
SetUp()256 virtual void SetUp() {
257 ots::FontFile *file = new ots::FontFile();
258 file->context = new ots::OTSContext();
259 font = new ots::Font(file);
260 }
261
TearDown()262 virtual void TearDown() {
263 delete font->file->context;
264 delete font->file;
265 delete font;
266 }
267
268 TestStream out;
269 ots::Font *font;
270 };
271
272 class ScriptListTableTest : public TableTest { };
273 class DeviceTableTest : public TableTest { };
274 class CoverageTableTest : public TableTest { };
275 class CoverageFormat1Test : public TableTest { };
276 class CoverageFormat2Test : public TableTest { };
277 class ClassDefTableTest : public TableTest { };
278 class ClassDefFormat1Test : public TableTest { };
279 class ClassDefFormat2Test : public TableTest { };
280 class LookupSubtableParserTest : public TableTest { };
281
282 class FeatureListTableTest : public TableTest {
283 protected:
284
SetUp()285 virtual void SetUp() {
286 TableTest::SetUp();
287 num_features = 0;
288 }
289
290 uint16_t num_features;
291 };
292
fakeTypeParserReturnsTrue(const ots::Font *,const uint8_t *,const size_t)293 bool fakeTypeParserReturnsTrue(const ots::Font*, const uint8_t *,
294 const size_t) {
295 return true;
296 }
297
fakeTypeParserReturnsFalse(const ots::Font *,const uint8_t *,const size_t)298 bool fakeTypeParserReturnsFalse(const ots::Font*, const uint8_t *,
299 const size_t) {
300 return false;
301 }
302
303 const ots::LookupSubtableParser::TypeParser TypeParsersReturnTrue[] = {
304 {1, fakeTypeParserReturnsTrue},
305 {2, fakeTypeParserReturnsTrue},
306 {3, fakeTypeParserReturnsTrue},
307 {4, fakeTypeParserReturnsTrue},
308 {5, fakeTypeParserReturnsTrue}
309 };
310
311 // Fake lookup subtable parser which always returns true.
312 const ots::LookupSubtableParser FakeLookupParserReturnsTrue = {
313 5, 5, TypeParsersReturnTrue,
314 };
315
316 const ots::LookupSubtableParser::TypeParser TypeParsersReturnFalse[] = {
317 {1, fakeTypeParserReturnsFalse}
318 };
319
320 // Fake lookup subtable parser which always returns false.
321 const ots::LookupSubtableParser FakeLookupParserReturnsFalse = {
322 1, 1, TypeParsersReturnFalse
323 };
324
325 class LookupListTableTest : public TableTest {
326 protected:
327
SetUp()328 virtual void SetUp() {
329 TableTest::SetUp();
330 num_lookups = 0;
331 }
332
Parse()333 bool Parse() {
334 return ots::ParseLookupListTable(font, out.data(), out.size(),
335 &FakeLookupParserReturnsTrue,
336 &num_lookups);
337 }
338
339 uint16_t num_lookups;
340 };
341
342 } // namespace
343
TEST_F(ScriptListTableTest,TestSuccess)344 TEST_F(ScriptListTableTest, TestSuccess) {
345 BuildFakeScriptListTable(&out, 1, 1, 1);
346 EXPECT_TRUE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
347 }
348
TEST_F(ScriptListTableTest,TestBadScriptCount)349 TEST_F(ScriptListTableTest, TestBadScriptCount) {
350 BuildFakeScriptListTable(&out, 1, 1, 1);
351 // Set too large script count.
352 out.Seek(0);
353 out.WriteU16(2);
354 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
355 }
356
TEST_F(ScriptListTableTest,TestScriptRecordOffsetUnderflow)357 TEST_F(ScriptListTableTest, TestScriptRecordOffsetUnderflow) {
358 BuildFakeScriptListTable(&out, 1, 1, 1);
359 // Set bad offset to ScriptRecord[0].
360 out.Seek(6);
361 out.WriteU16(0);
362 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
363 }
364
TEST_F(ScriptListTableTest,TestScriptRecordOffsetOverflow)365 TEST_F(ScriptListTableTest, TestScriptRecordOffsetOverflow) {
366 BuildFakeScriptListTable(&out, 1, 1, 1);
367 // Set bad offset to ScriptRecord[0].
368 out.Seek(6);
369 out.WriteU16(out.size());
370 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
371 }
372
TEST_F(ScriptListTableTest,TestBadLangSysCount)373 TEST_F(ScriptListTableTest, TestBadLangSysCount) {
374 BuildFakeScriptListTable(&out, 1, 1, 1);
375 // Set too large langsys count.
376 out.Seek(10);
377 out.WriteU16(2);
378 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
379 }
380
TEST_F(ScriptListTableTest,TestLangSysRecordOffsetUnderflow)381 TEST_F(ScriptListTableTest, TestLangSysRecordOffsetUnderflow) {
382 BuildFakeScriptListTable(&out, 1, 1, 1);
383 // Set bad offset to LangSysRecord[0].
384 out.Seek(16);
385 out.WriteU16(0);
386 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
387 }
388
TEST_F(ScriptListTableTest,TestLangSysRecordOffsetOverflow)389 TEST_F(ScriptListTableTest, TestLangSysRecordOffsetOverflow) {
390 BuildFakeScriptListTable(&out, 1, 1, 1);
391 // Set bad offset to LangSysRecord[0].
392 out.Seek(16);
393 out.WriteU16(out.size());
394 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
395 }
396
TEST_F(ScriptListTableTest,TestBadReqFeatureIndex)397 TEST_F(ScriptListTableTest, TestBadReqFeatureIndex) {
398 BuildFakeScriptListTable(&out, 1, 1, 1);
399 // Set too large feature index to ReqFeatureIndex of LangSysTable[0].
400 out.Seek(20);
401 out.WriteU16(2);
402 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
403 }
404
TEST_F(ScriptListTableTest,TestBadFeatureCount)405 TEST_F(ScriptListTableTest, TestBadFeatureCount) {
406 BuildFakeScriptListTable(&out, 1, 1, 1);
407 // Set too large feature count to LangSysTable[0].
408 out.Seek(22);
409 out.WriteU16(2);
410 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
411 }
412
TEST_F(ScriptListTableTest,TestBadFeatureIndex)413 TEST_F(ScriptListTableTest, TestBadFeatureIndex) {
414 BuildFakeScriptListTable(&out, 1, 1, 1);
415 // Set too large feature index to ReatureIndex[0] of LangSysTable[0].
416 out.Seek(24);
417 out.WriteU16(2);
418 EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
419 }
420
TEST_F(FeatureListTableTest,TestSuccess)421 TEST_F(FeatureListTableTest, TestSuccess) {
422 BuildFakeFeatureListTable(&out, 1, 1);
423 EXPECT_TRUE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
424 &num_features));
425 EXPECT_EQ(num_features, 1);
426 }
427
TEST_F(FeatureListTableTest,TestSuccess2)428 TEST_F(FeatureListTableTest, TestSuccess2) {
429 BuildFakeFeatureListTable(&out, 5, 1);
430 EXPECT_TRUE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
431 &num_features));
432 EXPECT_EQ(num_features, 5);
433 }
434
TEST_F(FeatureListTableTest,TestBadFeatureCount)435 TEST_F(FeatureListTableTest, TestBadFeatureCount) {
436 BuildFakeFeatureListTable(&out, 1, 1);
437 // Set too large feature count.
438 out.Seek(0);
439 out.WriteU16(2);
440 EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
441 &num_features));
442 }
443
TEST_F(FeatureListTableTest,TestOffsetFeatureUnderflow)444 TEST_F(FeatureListTableTest, TestOffsetFeatureUnderflow) {
445 BuildFakeFeatureListTable(&out, 1, 1);
446 // Set bad offset to FeatureRecord[0].
447 out.Seek(6);
448 out.WriteU16(0);
449 EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
450 &num_features));
451 }
452
TEST_F(FeatureListTableTest,TestOffsetFeatureOverflow)453 TEST_F(FeatureListTableTest, TestOffsetFeatureOverflow) {
454 BuildFakeFeatureListTable(&out, 1, 1);
455 // Set bad offset to FeatureRecord[0].
456 out.Seek(6);
457 out.WriteU16(out.size());
458 EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
459 &num_features));
460 }
461
TEST_F(FeatureListTableTest,TestBadLookupCount)462 TEST_F(FeatureListTableTest, TestBadLookupCount) {
463 BuildFakeFeatureListTable(&out, 1, 1);
464 // Set too large lookup count to FeatureTable[0].
465 out.Seek(10);
466 out.WriteU16(2);
467 EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
468 &num_features));
469 }
470
TEST_F(LookupListTableTest,TestSuccess)471 TEST_F(LookupListTableTest, TestSuccess) {
472 BuildFakeLookupListTable(&out, 1, 1);
473 EXPECT_TRUE(Parse());
474 EXPECT_EQ(num_lookups, 1);
475 }
476
TEST_F(LookupListTableTest,TestSuccess2)477 TEST_F(LookupListTableTest, TestSuccess2) {
478 BuildFakeLookupListTable(&out, 5, 1);
479 EXPECT_TRUE(Parse());
480 EXPECT_EQ(num_lookups, 5);
481 }
482
TEST_F(LookupListTableTest,TestOffsetLookupTableUnderflow)483 TEST_F(LookupListTableTest, TestOffsetLookupTableUnderflow) {
484 BuildFakeLookupListTable(&out, 1, 1);
485 // Set bad offset to Lookup[0].
486 out.Seek(2);
487 out.WriteU16(0);
488 EXPECT_FALSE(Parse());
489 }
490
TEST_F(LookupListTableTest,TestOffsetLookupTableOverflow)491 TEST_F(LookupListTableTest, TestOffsetLookupTableOverflow) {
492 BuildFakeLookupListTable(&out, 1, 1);
493 // Set bad offset to Lookup[0].
494 out.Seek(2);
495 out.WriteU16(out.size());
496 EXPECT_FALSE(Parse());
497 }
498
TEST_F(LookupListTableTest,TestOffsetSubtableUnderflow)499 TEST_F(LookupListTableTest, TestOffsetSubtableUnderflow) {
500 BuildFakeLookupListTable(&out, 1, 1);
501 // Set bad offset to SubTable[0] of LookupTable[0].
502 out.Seek(10);
503 out.WriteU16(0);
504 EXPECT_FALSE(Parse());
505 }
506
TEST_F(LookupListTableTest,TestOffsetSubtableOverflow)507 TEST_F(LookupListTableTest, TestOffsetSubtableOverflow) {
508 BuildFakeLookupListTable(&out, 1, 1);
509 // Set bad offset to SubTable[0] of LookupTable[0].
510 out.Seek(10);
511 out.WriteU16(out.size());
512 EXPECT_FALSE(Parse());
513 }
514
TEST_F(LookupListTableTest,TesBadLookupCount)515 TEST_F(LookupListTableTest, TesBadLookupCount) {
516 BuildFakeLookupListTable(&out, 1, 1);
517 // Set too large lookup count of LookupTable[0].
518 out.Seek(0);
519 out.WriteU16(2);
520 EXPECT_FALSE(Parse());
521 }
522
TEST_F(LookupListTableTest,TesBadLookupType)523 TEST_F(LookupListTableTest, TesBadLookupType) {
524 BuildFakeLookupListTable(&out, 1, 1);
525 // Set too large lookup type of LookupTable[0].
526 out.Seek(4);
527 out.WriteU16(6);
528 EXPECT_FALSE(Parse());
529 }
530
TEST_F(LookupListTableTest,TesBadLookupFlag)531 TEST_F(LookupListTableTest, TesBadLookupFlag) {
532 BuildFakeLookupListTable(&out, 1, 1);
533 // Set IgnoreBaseGlyphs(0x0002) to the lookup flag of LookupTable[0].
534 out.Seek(6);
535 out.WriteU16(0x0002);
536 EXPECT_TRUE(Parse());
537 }
538
TEST_F(LookupListTableTest,TesBadSubtableCount)539 TEST_F(LookupListTableTest, TesBadSubtableCount) {
540 BuildFakeLookupListTable(&out, 1, 1);
541 // Set too large sutable count of LookupTable[0].
542 out.Seek(8);
543 out.WriteU16(2);
544 EXPECT_FALSE(Parse());
545 }
546
TEST_F(CoverageTableTest,TestSuccessFormat1)547 TEST_F(CoverageTableTest, TestSuccessFormat1) {
548 BuildFakeCoverageFormat1(&out, 1);
549 EXPECT_TRUE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
550 }
551
TEST_F(CoverageTableTest,TestSuccessFormat2)552 TEST_F(CoverageTableTest, TestSuccessFormat2) {
553 BuildFakeCoverageFormat2(&out, 1);
554 EXPECT_TRUE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
555 }
556
TEST_F(CoverageTableTest,TestBadFormat)557 TEST_F(CoverageTableTest, TestBadFormat) {
558 BuildFakeCoverageFormat1(&out, 1);
559 // Set bad format.
560 out.Seek(0);
561 out.WriteU16(3);
562 EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
563 }
564
TEST_F(CoverageFormat1Test,TestBadGlyphCount)565 TEST_F(CoverageFormat1Test, TestBadGlyphCount) {
566 BuildFakeCoverageFormat1(&out, 1);
567 // Set too large glyph count.
568 out.Seek(2);
569 out.WriteU16(2);
570 EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
571 }
572
TEST_F(CoverageFormat1Test,TestBadGlyphId)573 TEST_F(CoverageFormat1Test, TestBadGlyphId) {
574 BuildFakeCoverageFormat1(&out, 1);
575 // Set too large glyph id.
576 out.Seek(4);
577 out.WriteU16(2);
578 EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
579 }
580
TEST_F(CoverageFormat2Test,TestBadRangeCount)581 TEST_F(CoverageFormat2Test, TestBadRangeCount) {
582 BuildFakeCoverageFormat2(&out, 1);
583 // Set too large range count.
584 out.Seek(2);
585 out.WriteU16(2);
586 EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
587 }
588
TEST_F(CoverageFormat2Test,TestBadRange)589 TEST_F(CoverageFormat2Test, TestBadRange) {
590 BuildFakeCoverageFormat2(&out, 1);
591 // Set reverse order glyph id to start/end fields.
592 out.Seek(4);
593 out.WriteU16(2);
594 out.WriteU16(1);
595 EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
596 }
597
TEST_F(CoverageFormat2Test,TestRangeOverlap)598 TEST_F(CoverageFormat2Test, TestRangeOverlap) {
599 BuildFakeCoverageFormat2(&out, 2);
600 // Set overlapping glyph id to an end field.
601 out.Seek(12);
602 out.WriteU16(1);
603 EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 2));
604 }
605
TEST_F(CoverageFormat2Test,TestRangeOverlap2)606 TEST_F(CoverageFormat2Test, TestRangeOverlap2) {
607 BuildFakeCoverageFormat2(&out, 2);
608 // Set overlapping range.
609 out.Seek(10);
610 out.WriteU16(1);
611 out.WriteU16(2);
612 EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 2));
613 }
614
TEST_F(ClassDefTableTest,TestSuccessFormat1)615 TEST_F(ClassDefTableTest, TestSuccessFormat1) {
616 BuildFakeClassDefFormat1(&out, 1);
617 EXPECT_TRUE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
618 }
619
TEST_F(ClassDefTableTest,TestSuccessFormat2)620 TEST_F(ClassDefTableTest, TestSuccessFormat2) {
621 BuildFakeClassDefFormat2(&out, 1);
622 EXPECT_TRUE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
623 }
624
TEST_F(ClassDefTableTest,TestBadFormat)625 TEST_F(ClassDefTableTest, TestBadFormat) {
626 BuildFakeClassDefFormat1(&out, 1);
627 // Set bad format.
628 out.Seek(0);
629 out.WriteU16(3);
630 EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
631 }
632
TEST_F(ClassDefFormat1Test,TestBadStartGlyph)633 TEST_F(ClassDefFormat1Test, TestBadStartGlyph) {
634 BuildFakeClassDefFormat1(&out, 1);
635 // Set too large start glyph id.
636 out.Seek(2);
637 out.WriteU16(2);
638 EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
639 }
640
TEST_F(ClassDefFormat1Test,TestBadGlyphCount)641 TEST_F(ClassDefFormat1Test, TestBadGlyphCount) {
642 BuildFakeClassDefFormat1(&out, 1);
643 // Set too large glyph count.
644 out.Seek(4);
645 out.WriteU16(2);
646 EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
647 }
648
TEST_F(ClassDefFormat1Test,TestBadClassValue)649 TEST_F(ClassDefFormat1Test, TestBadClassValue) {
650 BuildFakeClassDefFormat1(&out, 1);
651 // Set too large class value.
652 out.Seek(6);
653 out.WriteU16(2);
654 EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
655 }
656
TEST_F(ClassDefFormat2Test,TestBadRangeCount)657 TEST_F(ClassDefFormat2Test, TestBadRangeCount) {
658 BuildFakeClassDefFormat2(&out, 1);
659 // Set too large range count.
660 out.Seek(2);
661 out.WriteU16(2);
662 EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
663 }
664
TEST_F(ClassDefFormat2Test,TestRangeOverlap)665 TEST_F(ClassDefFormat2Test, TestRangeOverlap) {
666 BuildFakeClassDefFormat2(&out, 2);
667 // Set overlapping glyph id to an end field.
668 out.Seek(12);
669 out.WriteU16(1);
670 EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
671 }
672
TEST_F(ClassDefFormat2Test,TestRangeOverlap2)673 TEST_F(ClassDefFormat2Test, TestRangeOverlap2) {
674 BuildFakeClassDefFormat2(&out, 2);
675 // Set overlapping range.
676 out.Seek(10);
677 out.WriteU16(1);
678 out.WriteU16(2);
679 EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
680 }
681
TEST_F(DeviceTableTest,TestDeltaFormat1Success)682 TEST_F(DeviceTableTest, TestDeltaFormat1Success) {
683 BuildFakeDeviceTable(&out, 1, 8, 1);
684 EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
685 }
686
TEST_F(DeviceTableTest,TestDeltaFormat1Success2)687 TEST_F(DeviceTableTest, TestDeltaFormat1Success2) {
688 BuildFakeDeviceTable(&out, 1, 9, 1);
689 EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
690 }
691
TEST_F(DeviceTableTest,TestDeltaFormat1Fail)692 TEST_F(DeviceTableTest, TestDeltaFormat1Fail) {
693 // Pass shorter length than expected.
694 BuildFakeDeviceTable(&out, 1, 8, 1);
695 EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
696 }
697
TEST_F(DeviceTableTest,TestDeltaFormat1Fail2)698 TEST_F(DeviceTableTest, TestDeltaFormat1Fail2) {
699 // Pass shorter length than expected.
700 BuildFakeDeviceTable(&out, 1, 9, 1);
701 EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
702 }
703
TEST_F(DeviceTableTest,TestDeltaFormat2Success)704 TEST_F(DeviceTableTest, TestDeltaFormat2Success) {
705 BuildFakeDeviceTable(&out, 1, 1, 2);
706 EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
707 }
708
TEST_F(DeviceTableTest,TestDeltaFormat2Success2)709 TEST_F(DeviceTableTest, TestDeltaFormat2Success2) {
710 BuildFakeDeviceTable(&out, 1, 8, 2);
711 EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
712 }
713
TEST_F(DeviceTableTest,TestDeltaFormat2Fail)714 TEST_F(DeviceTableTest, TestDeltaFormat2Fail) {
715 // Pass shorter length than expected.
716 BuildFakeDeviceTable(&out, 1, 8, 2);
717 EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
718 }
719
TEST_F(DeviceTableTest,TestDeltaFormat2Fail2)720 TEST_F(DeviceTableTest, TestDeltaFormat2Fail2) {
721 // Pass shorter length than expected.
722 BuildFakeDeviceTable(&out, 1, 9, 2);
723 EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
724 }
725
TEST_F(DeviceTableTest,TestDeltaFormat3Success)726 TEST_F(DeviceTableTest, TestDeltaFormat3Success) {
727 BuildFakeDeviceTable(&out, 1, 1, 3);
728 EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
729 }
730
TEST_F(DeviceTableTest,TestDeltaFormat3Success2)731 TEST_F(DeviceTableTest, TestDeltaFormat3Success2) {
732 BuildFakeDeviceTable(&out, 1, 8, 3);
733 EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
734 }
735
TEST_F(DeviceTableTest,TestDeltaFormat3Fail)736 TEST_F(DeviceTableTest, TestDeltaFormat3Fail) {
737 // Pass shorter length than expected.
738 BuildFakeDeviceTable(&out, 1, 8, 3);
739 EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
740 }
741
TEST_F(DeviceTableTest,TestDeltaFormat3Fail2)742 TEST_F(DeviceTableTest, TestDeltaFormat3Fail2) {
743 // Pass shorter length than expected.
744 BuildFakeDeviceTable(&out, 1, 9, 3);
745 EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
746 }
747
TEST_F(LookupSubtableParserTest,TestSuccess)748 TEST_F(LookupSubtableParserTest, TestSuccess) {
749 {
750 EXPECT_TRUE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 1));
751 }
752 {
753 EXPECT_TRUE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 5));
754 }
755 }
756
TEST_F(LookupSubtableParserTest,TestFail)757 TEST_F(LookupSubtableParserTest, TestFail) {
758 {
759 // Pass bad lookup type which less than the smallest type.
760 EXPECT_FALSE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 0));
761 }
762 {
763 // Pass bad lookup type which greater than the maximum type.
764 EXPECT_FALSE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 6));
765 }
766 {
767 // Check the type parser failure.
768 EXPECT_FALSE(FakeLookupParserReturnsFalse.Parse(font, 0, 0, 1));
769 }
770 }
771