blob: 47510371ed2591d054ae4945cebf765f98854bb3 [file] [log] [blame]
bashi@google.com78a8baa2011-02-07 06:21:25 +00001// Copyright (c) 2011 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 <cmath>
6#include <vector>
7#include <gtest/gtest.h>
8
9#include "layout.h"
10#include "ots-memory-stream.h"
11
12namespace {
13
14const uint32_t kFakeTag = 0x00000000;
15const size_t kScriptRecordSize = 6;
16const size_t kLangSysRecordSize = 6;
17
18bool 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
68const size_t kFeatureRecordSize = 6;
69
70bool 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
101bool 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
152bool 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
164bool 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
183bool 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
197bool 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
214bool 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
231class TestStream : public ots::MemoryStream {
232 public:
233 TestStream()
234 : ots::MemoryStream(data_, sizeof(data_)), size_(0) {
235 std::memset(reinterpret_cast<char*>(data_), 0, sizeof(data_));
236 }
237
238 uint8_t* data() { return data_; }
239 size_t size() const { return size_; }
240
241 virtual bool WriteRaw(const void *data, size_t length) {
242 if (Tell() + length > size_) {
243 size_ = Tell() + length;
244 }
245 return ots::MemoryStream::WriteRaw(data, length);
246 }
247
248 private:
249 size_t size_;
250 uint8_t data_[4096];
251};
252
253class ScriptListTableTest : public ::testing::Test {
254 protected:
255
256 TestStream out;
257 ots::OpenTypeFile file;
258};
259
260class FeatureListTableTest : public ::testing::Test {
261 protected:
262
263 virtual void SetUp() {
264 num_features = 0;
265 }
266
267 TestStream out;
268 ots::OpenTypeFile file;
269 uint16_t num_features;
270};
271
bashi@chromium.orgced71122011-02-17 10:23:47 +0000272bool fakeTypeParserReturnsTrue(const ots::OpenTypeFile*, const uint8_t *,
273 const size_t) {
bashi@google.com78a8baa2011-02-07 06:21:25 +0000274 return true;
275}
276
bashi@chromium.orgced71122011-02-17 10:23:47 +0000277bool fakeTypeParserReturnsFalse(const ots::OpenTypeFile*, const uint8_t *,
278 const size_t) {
279 return false;
280}
281
282const ots::LookupSubtableParser::TypeParser TypeParsersReturnTrue[] = {
283 {1, fakeTypeParserReturnsTrue},
284 {2, fakeTypeParserReturnsTrue},
285 {3, fakeTypeParserReturnsTrue},
286 {4, fakeTypeParserReturnsTrue},
287 {5, fakeTypeParserReturnsTrue}
288};
289
290// Fake lookup subtable parser which always returns true.
291const ots::LookupSubtableParser FakeLookupParserReturnsTrue = {
292 5, 5, TypeParsersReturnTrue,
293};
294
295const ots::LookupSubtableParser::TypeParser TypeParsersReturnFalse[] = {
296 {1, fakeTypeParserReturnsFalse}
297};
298
299// Fake lookup subtable parser which always returns false.
300const ots::LookupSubtableParser FakeLookupParserReturnsFalse = {
301 1, 1, TypeParsersReturnFalse
bashi@google.com78a8baa2011-02-07 06:21:25 +0000302};
303
304class LookupListTableTest : public ::testing::Test {
305 protected:
306
307 virtual void SetUp() {
308 num_lookups = 0;
309 }
310
311 bool Parse() {
bashi@chromium.orgced71122011-02-17 10:23:47 +0000312 return ots::ParseLookupListTable(&file, out.data(), out.size(),
313 &FakeLookupParserReturnsTrue,
314 &num_lookups);
bashi@google.com78a8baa2011-02-07 06:21:25 +0000315 }
316
317 TestStream out;
318 ots::OpenTypeFile file;
319 uint16_t num_lookups;
320};
321
322} // namespace
323
324TEST_F(ScriptListTableTest, TestSuccess) {
325 BuildFakeScriptListTable(&out, 1, 1, 1);
326 EXPECT_TRUE(ots::ParseScriptListTable(out.data(), out.size(), 1));
327}
328
329TEST_F(ScriptListTableTest, TestBadScriptCount) {
330 BuildFakeScriptListTable(&out, 1, 1, 1);
331 // Set too large script count.
332 out.Seek(0);
333 out.WriteU16(2);
334 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
335}
336
337TEST_F(ScriptListTableTest, TestScriptRecordOffsetUnderflow) {
338 BuildFakeScriptListTable(&out, 1, 1, 1);
339 // Set bad offset to ScriptRecord[0].
340 out.Seek(6);
341 out.WriteU16(0);
342 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
343}
344
345TEST_F(ScriptListTableTest, TestScriptRecordOffsetOverflow) {
346 BuildFakeScriptListTable(&out, 1, 1, 1);
347 // Set bad offset to ScriptRecord[0].
348 out.Seek(6);
349 out.WriteU16(out.size());
350 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
351}
352
353TEST_F(ScriptListTableTest, TestBadLangSysCount) {
354 BuildFakeScriptListTable(&out, 1, 1, 1);
355 // Set too large langsys count.
356 out.Seek(10);
357 out.WriteU16(2);
358 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
359}
360
361TEST_F(ScriptListTableTest, TestLangSysRecordOffsetUnderflow) {
362 BuildFakeScriptListTable(&out, 1, 1, 1);
363 // Set bad offset to LangSysRecord[0].
364 out.Seek(16);
365 out.WriteU16(0);
366 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
367}
368
369TEST_F(ScriptListTableTest, TestLangSysRecordOffsetOverflow) {
370 BuildFakeScriptListTable(&out, 1, 1, 1);
371 // Set bad offset to LangSysRecord[0].
372 out.Seek(16);
373 out.WriteU16(out.size());
374 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
375}
376
377TEST_F(ScriptListTableTest, TestBadReqFeatureIndex) {
378 BuildFakeScriptListTable(&out, 1, 1, 1);
379 // Set too large feature index to ReqFeatureIndex of LangSysTable[0].
380 out.Seek(20);
381 out.WriteU16(2);
382 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
383}
384
385TEST_F(ScriptListTableTest, TestBadFeatureCount) {
386 BuildFakeScriptListTable(&out, 1, 1, 1);
387 // Set too large feature count to LangSysTable[0].
388 out.Seek(22);
389 out.WriteU16(2);
390 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
391}
392
393TEST_F(ScriptListTableTest, TestBadFeatureIndex) {
394 BuildFakeScriptListTable(&out, 1, 1, 1);
395 // Set too large feature index to ReatureIndex[0] of LangSysTable[0].
396 out.Seek(24);
397 out.WriteU16(2);
398 EXPECT_FALSE(ots::ParseScriptListTable(out.data(), out.size(), 1));
399}
400
401TEST_F(FeatureListTableTest, TestSuccess) {
402 BuildFakeFeatureListTable(&out, 1, 1);
403 EXPECT_TRUE(ots::ParseFeatureListTable(out.data(), out.size(), 1,
404 &num_features));
405 EXPECT_EQ(num_features, 1);
406}
407
408TEST_F(FeatureListTableTest, TestSuccess2) {
409 BuildFakeFeatureListTable(&out, 5, 1);
410 EXPECT_TRUE(ots::ParseFeatureListTable(out.data(), out.size(), 1,
411 &num_features));
412 EXPECT_EQ(num_features, 5);
413}
414
415TEST_F(FeatureListTableTest, TestBadFeatureCount) {
416 BuildFakeFeatureListTable(&out, 1, 1);
417 // Set too large feature count.
418 out.Seek(0);
419 out.WriteU16(2);
420 EXPECT_FALSE(ots::ParseFeatureListTable(out.data(), out.size(), 1,
421 &num_features));
422}
423
424TEST_F(FeatureListTableTest, TestOffsetFeatureUnderflow) {
425 BuildFakeFeatureListTable(&out, 1, 1);
426 // Set bad offset to FeatureRecord[0].
427 out.Seek(6);
428 out.WriteU16(0);
429 EXPECT_FALSE(ots::ParseFeatureListTable(out.data(), out.size(), 1,
430 &num_features));
431}
432
433TEST_F(FeatureListTableTest, TestOffsetFeatureOverflow) {
434 BuildFakeFeatureListTable(&out, 1, 1);
435 // Set bad offset to FeatureRecord[0].
436 out.Seek(6);
437 out.WriteU16(out.size());
438 EXPECT_FALSE(ots::ParseFeatureListTable(out.data(), out.size(), 1,
439 &num_features));
440}
441
442TEST_F(FeatureListTableTest, TestBadLookupCount) {
443 BuildFakeFeatureListTable(&out, 1, 1);
444 // Set too large lookup count to FeatureTable[0].
445 out.Seek(10);
446 out.WriteU16(2);
447 EXPECT_FALSE(ots::ParseFeatureListTable(out.data(), out.size(), 1,
448 &num_features));
449}
450
451TEST_F(LookupListTableTest, TestSuccess) {
452 BuildFakeLookupListTable(&out, 1, 1);
453 EXPECT_TRUE(Parse());
454 EXPECT_EQ(num_lookups, 1);
455}
456
457TEST_F(LookupListTableTest, TestSuccess2) {
458 BuildFakeLookupListTable(&out, 5, 1);
459 EXPECT_TRUE(Parse());
460 EXPECT_EQ(num_lookups, 5);
461}
462
463TEST_F(LookupListTableTest, TestOffsetLookupTableUnderflow) {
464 BuildFakeLookupListTable(&out, 1, 1);
465 // Set bad offset to Lookup[0].
466 out.Seek(2);
467 out.WriteU16(0);
468 EXPECT_FALSE(Parse());
469}
470
471TEST_F(LookupListTableTest, TestOffsetLookupTableOverflow) {
472 BuildFakeLookupListTable(&out, 1, 1);
473 // Set bad offset to Lookup[0].
474 out.Seek(2);
475 out.WriteU16(out.size());
476 EXPECT_FALSE(Parse());
477}
478
479TEST_F(LookupListTableTest, TestOffsetSubtableUnderflow) {
480 BuildFakeLookupListTable(&out, 1, 1);
481 // Set bad offset to SubTable[0] of LookupTable[0].
482 out.Seek(10);
483 out.WriteU16(0);
484 EXPECT_FALSE(Parse());
485}
486
487TEST_F(LookupListTableTest, TestOffsetSubtableOverflow) {
488 BuildFakeLookupListTable(&out, 1, 1);
489 // Set bad offset to SubTable[0] of LookupTable[0].
490 out.Seek(10);
491 out.WriteU16(out.size());
492 EXPECT_FALSE(Parse());
493}
494
495TEST_F(LookupListTableTest, TesBadLookupCount) {
496 BuildFakeLookupListTable(&out, 1, 1);
497 // Set too large lookup count of LookupTable[0].
498 out.Seek(0);
499 out.WriteU16(2);
500 EXPECT_FALSE(Parse());
501}
502
503TEST_F(LookupListTableTest, TesBadLookupType) {
504 BuildFakeLookupListTable(&out, 1, 1);
505 // Set too large lookup type of LookupTable[0].
506 out.Seek(4);
507 out.WriteU16(6);
508 EXPECT_FALSE(Parse());
509}
510
bashi@chromium.orgdf5b76f2011-03-22 19:02:34 +0000511TEST_F(LookupListTableTest, TesBadLookupFlag) {
512 BuildFakeLookupListTable(&out, 1, 1);
513 // Set IgnoreBaseGlyphs(0x0002) to the lookup flag of LookupTable[0].
514 out.Seek(6);
515 out.WriteU16(0x0002);
516 EXPECT_FALSE(Parse());
517}
518
bashi@google.com78a8baa2011-02-07 06:21:25 +0000519TEST_F(LookupListTableTest, TesBadSubtableCount) {
520 BuildFakeLookupListTable(&out, 1, 1);
521 // Set too large sutable count of LookupTable[0].
522 out.Seek(8);
523 out.WriteU16(2);
524 EXPECT_FALSE(Parse());
525}
526
527TEST(CoverageTableTest, TestSuccessFormat1) {
528 TestStream out;
529 BuildFakeCoverageFormat1(&out, 1);
530 EXPECT_TRUE(ots::ParseCoverageTable(out.data(), out.size(), 1));
531}
532
533TEST(CoverageTableTest, TestSuccessFormat2) {
534 TestStream out;
535 BuildFakeCoverageFormat2(&out, 1);
536 EXPECT_TRUE(ots::ParseCoverageTable(out.data(), out.size(), 1));
537}
538
539TEST(CoverageTableTest, TestBadFormat) {
540 TestStream out;
541 BuildFakeCoverageFormat1(&out, 1);
542 // Set bad format.
543 out.Seek(0);
544 out.WriteU16(3);
545 EXPECT_FALSE(ots::ParseCoverageTable(out.data(), out.size(), 1));
546}
547
548TEST(CoverageFormat1Test, TestBadGlyphCount) {
549 TestStream out;
550 BuildFakeCoverageFormat1(&out, 1);
551 // Set too large glyph count.
552 out.Seek(2);
553 out.WriteU16(2);
554 EXPECT_FALSE(ots::ParseCoverageTable(out.data(), out.size(), 1));
555}
556
557TEST(CoverageFormat1Test, TestBadGlyphId) {
558 TestStream out;
559 BuildFakeCoverageFormat1(&out, 1);
560 // Set too large glyph id.
561 out.Seek(4);
562 out.WriteU16(2);
563 EXPECT_FALSE(ots::ParseCoverageTable(out.data(), out.size(), 1));
564}
565
566TEST(CoverageFormat2Test, TestBadRangeCount) {
567 TestStream out;
568 BuildFakeCoverageFormat2(&out, 1);
569 // Set too large range count.
570 out.Seek(2);
571 out.WriteU16(2);
572 EXPECT_FALSE(ots::ParseCoverageTable(out.data(), out.size(), 1));
573}
574
575TEST(CoverageFormat2Test, TestBadRange) {
576 TestStream out;
577 BuildFakeCoverageFormat2(&out, 1);
578 // Set reverse order glyph id to start/end fields.
579 out.Seek(4);
580 out.WriteU16(2);
581 out.WriteU16(1);
582 EXPECT_FALSE(ots::ParseCoverageTable(out.data(), out.size(), 1));
583}
584
585TEST(CoverageFormat2Test, TestRangeOverlap) {
586 TestStream out;
587 BuildFakeCoverageFormat2(&out, 2);
588 // Set overlapping glyph id to an end field.
589 out.Seek(12);
590 out.WriteU16(1);
591 EXPECT_FALSE(ots::ParseCoverageTable(out.data(), out.size(), 2));
592}
593
594TEST(CoverageFormat2Test, TestRangeOverlap2) {
595 TestStream out;
596 BuildFakeCoverageFormat2(&out, 2);
597 // Set overlapping range.
598 out.Seek(10);
599 out.WriteU16(1);
600 out.WriteU16(2);
601 EXPECT_FALSE(ots::ParseCoverageTable(out.data(), out.size(), 2));
602}
603
604TEST(ClassDefTableTest, TestSuccessFormat1) {
605 TestStream out;
606 BuildFakeClassDefFormat1(&out, 1);
607 EXPECT_TRUE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
608}
609
610TEST(ClassDefTableTest, TestSuccessFormat2) {
611 TestStream out;
612 BuildFakeClassDefFormat2(&out, 1);
613 EXPECT_TRUE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
614}
615
616TEST(ClassDefTableTest, TestBadFormat) {
617 TestStream out;
618 BuildFakeClassDefFormat1(&out, 1);
619 // Set bad format.
620 out.Seek(0);
621 out.WriteU16(3);
622 EXPECT_FALSE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
623}
624
625TEST(ClassDefFormat1Test, TestBadStartGlyph) {
626 TestStream out;
627 BuildFakeClassDefFormat1(&out, 1);
628 // Set too large start glyph id.
629 out.Seek(2);
630 out.WriteU16(2);
631 EXPECT_FALSE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
632}
633
634TEST(ClassDefFormat1Test, TestBadGlyphCount) {
635 TestStream out;
636 BuildFakeClassDefFormat1(&out, 1);
637 // Set too large glyph count.
638 out.Seek(4);
639 out.WriteU16(2);
640 EXPECT_FALSE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
641}
642
643TEST(ClassDefFormat1Test, TestBadClassValue) {
644 TestStream out;
645 BuildFakeClassDefFormat1(&out, 1);
646 // Set too large class value.
647 out.Seek(6);
648 out.WriteU16(2);
649 EXPECT_FALSE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
650}
651
652TEST(ClassDefFormat2Test, TestBadRangeCount) {
653 TestStream out;
654 BuildFakeClassDefFormat2(&out, 1);
655 // Set too large range count.
656 out.Seek(2);
657 out.WriteU16(2);
658 EXPECT_FALSE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
659}
660
661TEST(ClassDefFormat2Test, TestRangeOverlap) {
662 TestStream out;
663 BuildFakeClassDefFormat2(&out, 2);
664 // Set overlapping glyph id to an end field.
665 out.Seek(12);
666 out.WriteU16(1);
667 EXPECT_FALSE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
668}
669
670TEST(ClassDefFormat2Test, TestRangeOverlap2) {
671 TestStream out;
672 BuildFakeClassDefFormat2(&out, 2);
673 // Set overlapping range.
674 out.Seek(10);
675 out.WriteU16(1);
676 out.WriteU16(2);
677 EXPECT_FALSE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1));
678}
679
680TEST(DeviceTableTest, TestDeltaFormat1Success) {
681 {
682 TestStream out;
683 BuildFakeDeviceTable(&out, 1, 8, 1);
684 EXPECT_TRUE(ots::ParseDeviceTable(out.data(), out.size()));
685 }
686 {
687 TestStream out;
688 BuildFakeDeviceTable(&out, 1, 9, 1);
689 EXPECT_TRUE(ots::ParseDeviceTable(out.data(), out.size()));
690 }
691}
692
693TEST(DeviceTableTest, TestDeltaFormat1Fail) {
694 // Pass shorter length than expected.
695 {
696 TestStream out;
697 BuildFakeDeviceTable(&out, 1, 8, 1);
698 EXPECT_FALSE(ots::ParseDeviceTable(out.data(), out.size() - 1));
699 }
700 {
701 TestStream out;
702 BuildFakeDeviceTable(&out, 1, 9, 1);
703 EXPECT_FALSE(ots::ParseDeviceTable(out.data(), out.size() - 1));
704 }
705}
706
707TEST(DeviceTableTest, TestDeltaFormat2Success) {
708 {
709 TestStream out;
710 BuildFakeDeviceTable(&out, 1, 1, 2);
711 EXPECT_TRUE(ots::ParseDeviceTable(out.data(), out.size()));
712 }
713 {
714 TestStream out;
715 BuildFakeDeviceTable(&out, 1, 8, 2);
716 EXPECT_TRUE(ots::ParseDeviceTable(out.data(), out.size()));
717 }
718}
719
720TEST(DeviceTableTest, TestDeltaFormat2Fail) {
721 // Pass shorter length than expected.
722 {
723 TestStream out;
724 BuildFakeDeviceTable(&out, 1, 8, 2);
725 EXPECT_FALSE(ots::ParseDeviceTable(out.data(), out.size() - 1));
726 }
727 {
728 TestStream out;
729 BuildFakeDeviceTable(&out, 1, 9, 2);
730 EXPECT_FALSE(ots::ParseDeviceTable(out.data(), out.size() - 1));
731 }
732}
733
734TEST(DeviceTableTest, TestDeltaFormat3Success) {
735 {
736 TestStream out;
737 BuildFakeDeviceTable(&out, 1, 1, 3);
738 EXPECT_TRUE(ots::ParseDeviceTable(out.data(), out.size()));
739 }
740 {
741 TestStream out;
742 BuildFakeDeviceTable(&out, 1, 8, 3);
743 EXPECT_TRUE(ots::ParseDeviceTable(out.data(), out.size()));
744 }
745}
746
747TEST(DeviceTableTest, TestDeltaFormat3Fail) {
748 // Pass shorter length than expected.
749 {
750 TestStream out;
751 BuildFakeDeviceTable(&out, 1, 8, 3);
752 EXPECT_FALSE(ots::ParseDeviceTable(out.data(), out.size() - 1));
753 }
754 {
755 TestStream out;
756 BuildFakeDeviceTable(&out, 1, 9, 3);
757 EXPECT_FALSE(ots::ParseDeviceTable(out.data(), out.size() - 1));
758 }
759}
760
bashi@chromium.orgced71122011-02-17 10:23:47 +0000761TEST(LookupSubtableParserTest, TestSuccess) {
762 {
763 ots::OpenTypeFile file;
764 EXPECT_TRUE(FakeLookupParserReturnsTrue.Parse(&file, 0, 0, 1));
765 }
766 {
767 ots::OpenTypeFile file;
768 EXPECT_TRUE(FakeLookupParserReturnsTrue.Parse(&file, 0, 0, 5));
769 }
770}
771
772TEST(LookupSubtableParserTest, TestFail) {
773 {
774 ots::OpenTypeFile file;
775 // Pass bad lookup type which less than the smallest type.
776 EXPECT_FALSE(FakeLookupParserReturnsTrue.Parse(&file, 0, 0, 0));
777 }
778 {
779 ots::OpenTypeFile file;
780 // Pass bad lookup type which greater than the maximum type.
781 EXPECT_FALSE(FakeLookupParserReturnsTrue.Parse(&file, 0, 0, 6));
782 }
783 {
784 ots::OpenTypeFile file;
785 // Check the type parser failure.
786 EXPECT_FALSE(FakeLookupParserReturnsFalse.Parse(&file, 0, 0, 1));
787 }
788}