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