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 *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 253 class ScriptListTableTest : public ::testing::Test { 254 protected: 255 256 TestStream out; 257 ots::OpenTypeFile file; 258 }; 259 260 class 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 272 bool fakeTypeParserReturnsTrue(const ots::OpenTypeFile*, const uint8_t *, 273 const size_t) { 274 return true; 275 } 276 277 bool fakeTypeParserReturnsFalse(const ots::OpenTypeFile*, const uint8_t *, 278 const size_t) { 279 return false; 280 } 281 282 const 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. 291 const ots::LookupSubtableParser FakeLookupParserReturnsTrue = { 292 5, 5, TypeParsersReturnTrue, 293 }; 294 295 const ots::LookupSubtableParser::TypeParser TypeParsersReturnFalse[] = { 296 {1, fakeTypeParserReturnsFalse} 297 }; 298 299 // Fake lookup subtable parser which always returns false. 300 const ots::LookupSubtableParser FakeLookupParserReturnsFalse = { 301 1, 1, TypeParsersReturnFalse 302 }; 303 304 class LookupListTableTest : public ::testing::Test { 305 protected: 306 307 virtual void SetUp() { 308 num_lookups = 0; 309 } 310 311 bool Parse() { 312 return ots::ParseLookupListTable(&file, out.data(), out.size(), 313 &FakeLookupParserReturnsTrue, 314 &num_lookups); 315 } 316 317 TestStream out; 318 ots::OpenTypeFile file; 319 uint16_t num_lookups; 320 }; 321 322 } // namespace 323 324 TEST_F(ScriptListTableTest, TestSuccess) { 325 BuildFakeScriptListTable(&out, 1, 1, 1); 326 EXPECT_TRUE(ots::ParseScriptListTable(out.data(), out.size(), 1)); 327 } 328 329 TEST_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 337 TEST_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 345 TEST_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 353 TEST_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 361 TEST_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 369 TEST_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 377 TEST_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 385 TEST_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 393 TEST_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 401 TEST_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 408 TEST_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 415 TEST_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 424 TEST_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 433 TEST_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 442 TEST_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 451 TEST_F(LookupListTableTest, TestSuccess) { 452 BuildFakeLookupListTable(&out, 1, 1); 453 EXPECT_TRUE(Parse()); 454 EXPECT_EQ(num_lookups, 1); 455 } 456 457 TEST_F(LookupListTableTest, TestSuccess2) { 458 BuildFakeLookupListTable(&out, 5, 1); 459 EXPECT_TRUE(Parse()); 460 EXPECT_EQ(num_lookups, 5); 461 } 462 463 TEST_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 471 TEST_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 479 TEST_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 487 TEST_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 495 TEST_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 503 TEST_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 511 TEST_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 519 TEST_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 527 TEST(CoverageTableTest, TestSuccessFormat1) { 528 TestStream out; 529 BuildFakeCoverageFormat1(&out, 1); 530 EXPECT_TRUE(ots::ParseCoverageTable(out.data(), out.size(), 1)); 531 } 532 533 TEST(CoverageTableTest, TestSuccessFormat2) { 534 TestStream out; 535 BuildFakeCoverageFormat2(&out, 1); 536 EXPECT_TRUE(ots::ParseCoverageTable(out.data(), out.size(), 1)); 537 } 538 539 TEST(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 548 TEST(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 557 TEST(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 566 TEST(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 575 TEST(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 585 TEST(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 594 TEST(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 604 TEST(ClassDefTableTest, TestSuccessFormat1) { 605 TestStream out; 606 BuildFakeClassDefFormat1(&out, 1); 607 EXPECT_TRUE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1)); 608 } 609 610 TEST(ClassDefTableTest, TestSuccessFormat2) { 611 TestStream out; 612 BuildFakeClassDefFormat2(&out, 1); 613 EXPECT_TRUE(ots::ParseClassDefTable(out.data(), out.size(), 1, 1)); 614 } 615 616 TEST(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 625 TEST(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 634 TEST(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 643 TEST(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 652 TEST(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 661 TEST(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 670 TEST(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 680 TEST(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 693 TEST(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 707 TEST(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 720 TEST(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 734 TEST(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 747 TEST(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 761 TEST(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 772 TEST(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 } 789