зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1382750 - Import and run gtests from upstream OTS. r=milan
This commit is contained in:
Родитель
d2b7ec5d78
Коммит
154df58572
|
@ -4,7 +4,7 @@ Our reference repository is https://github.com/khaledhosny/ots/.
|
|||
|
||||
Current revision: ba8417620956a920ed1f05a2f666fb6317fb10cb (5.1.0)
|
||||
|
||||
Upstream files included: LICENSE, src/, include/
|
||||
Upstream files included: LICENSE, src/, include/, tests/*.cc
|
||||
|
||||
Additional files: README.mozilla, src/moz.build
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@ echo "Updating include..."
|
|||
rm -rf include/
|
||||
cp -r $1/include .
|
||||
|
||||
echo "Updating tests..."
|
||||
rm -rf tests/*
|
||||
mkdir -p tests
|
||||
cp -r $1/tests/*.cc tests
|
||||
|
||||
echo "Updating README.mozilla..."
|
||||
REVISION=`cd $1; git log | head -1 | sed "s/commit //"`
|
||||
VERSION=`cd $1; git describe | cut -d '-' -f 1 | sed 's/v//'`
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,764 @@
|
|||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "layout.h"
|
||||
#include "ots-memory-stream.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const uint32_t kFakeTag = 0x00000000;
|
||||
const size_t kScriptRecordSize = 6;
|
||||
const size_t kLangSysRecordSize = 6;
|
||||
|
||||
bool BuildFakeScriptListTable(ots::OTSStream *out, const uint16_t script_count,
|
||||
const uint16_t langsys_count,
|
||||
const uint16_t feature_count) {
|
||||
if (!out->WriteU16(script_count)) {
|
||||
return false;
|
||||
}
|
||||
const off_t script_record_end = out->Tell() +
|
||||
kScriptRecordSize * script_count;
|
||||
const size_t script_table_size = 4 + kLangSysRecordSize * langsys_count;
|
||||
for (unsigned i = 0; i < script_count; ++i) {
|
||||
if (!out->WriteU32(kFakeTag) ||
|
||||
!out->WriteU16(script_record_end + i * script_table_size)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Offsets to LangSys tables are measured from the beginning of each
|
||||
// script table.
|
||||
const off_t langsys_record_end = 4 + kLangSysRecordSize * langsys_count;
|
||||
const size_t langsys_table_size = 6 + 2 * feature_count;
|
||||
// Write Fake Script tables.
|
||||
for (unsigned i = 0; i < script_count; ++i) {
|
||||
if (!out->WriteU16(0x0000) ||
|
||||
!out->WriteU16(langsys_count)) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned j = 0; j < langsys_count; ++j) {
|
||||
if (!out->WriteU32(kFakeTag) ||
|
||||
!out->WriteU16(langsys_record_end + j * langsys_table_size)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write Fake LangSys tables.
|
||||
for (unsigned i = 0; i < langsys_count; ++i) {
|
||||
if (!out->WriteU16(0x0000) ||
|
||||
!out->WriteU16(0xFFFF) ||
|
||||
!out->WriteU16(feature_count)) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned j = 0; j < feature_count; ++j) {
|
||||
if (!out->WriteU16(j)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t kFeatureRecordSize = 6;
|
||||
|
||||
bool BuildFakeFeatureListTable(ots::OTSStream *out,
|
||||
const uint16_t feature_count,
|
||||
const uint16_t lookup_count) {
|
||||
if (!out->WriteU16(feature_count)) {
|
||||
return false;
|
||||
}
|
||||
const off_t feature_record_end = out->Tell() +
|
||||
kFeatureRecordSize * feature_count;
|
||||
const size_t feature_table_size = 4 + 2 * lookup_count;
|
||||
for (unsigned i = 0; i < feature_count; ++i) {
|
||||
if (!out->WriteU32(kFakeTag) ||
|
||||
!out->WriteU16(feature_record_end + i * feature_table_size)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Write FeatureTable
|
||||
for (unsigned i = 0; i < feature_count; ++i) {
|
||||
if (!out->WriteU16(0x0000) ||
|
||||
!out->WriteU16(lookup_count)) {
|
||||
return false;
|
||||
}
|
||||
for (uint16_t j = 0; j < lookup_count; ++j) {
|
||||
if (!out->WriteU16(j)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildFakeLookupListTable(ots::OTSStream *out, const uint16_t lookup_count,
|
||||
const uint16_t subtable_count) {
|
||||
if (!out->WriteU16(lookup_count)) {
|
||||
return false;
|
||||
}
|
||||
const off_t base_offset_lookup = out->Tell();
|
||||
if (!out->Pad(2 * lookup_count)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<off_t> offsets_lookup(lookup_count, 0);
|
||||
for (uint16_t i = 0; i < lookup_count; ++i) {
|
||||
offsets_lookup[i] = out->Tell();
|
||||
if (!out->WriteU16(i + 1) ||
|
||||
!out->WriteU16(0) ||
|
||||
!out->WriteU16(subtable_count) ||
|
||||
!out->Pad(2 * subtable_count) ||
|
||||
!out->WriteU16(0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const off_t offset_lookup_table_end = out->Tell();
|
||||
// Allocate 256 bytes for each subtable.
|
||||
if (!out->Pad(256 * lookup_count * subtable_count)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!out->Seek(base_offset_lookup)) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned i = 0; i < lookup_count; ++i) {
|
||||
if (!out->WriteU16(offsets_lookup[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < lookup_count; ++i) {
|
||||
if (!out->Seek(offsets_lookup[i] + 6)) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned j = 0; j < subtable_count; ++j) {
|
||||
if (!out->WriteU16(offset_lookup_table_end +
|
||||
256*i*subtable_count + 256*j)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildFakeCoverageFormat1(ots::OTSStream *out, const uint16_t glyph_count) {
|
||||
if (!out->WriteU16(1) || !out->WriteU16(glyph_count)) {
|
||||
return false;
|
||||
}
|
||||
for (uint16_t glyph_id = 1; glyph_id <= glyph_count; ++glyph_id) {
|
||||
if (!out->WriteU16(glyph_id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildFakeCoverageFormat2(ots::OTSStream *out, const uint16_t range_count) {
|
||||
if (!out->WriteU16(2) || !out->WriteU16(range_count)) {
|
||||
return false;
|
||||
}
|
||||
uint16_t glyph_id = 1;
|
||||
uint16_t start_coverage_index = 0;
|
||||
for (unsigned i = 0; i < range_count; ++i) {
|
||||
// Write consecutive ranges in which each range consists of two glyph id.
|
||||
if (!out->WriteU16(glyph_id) ||
|
||||
!out->WriteU16(glyph_id + 1) ||
|
||||
!out->WriteU16(start_coverage_index)) {
|
||||
return false;
|
||||
}
|
||||
glyph_id += 2;
|
||||
start_coverage_index += 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildFakeClassDefFormat1(ots::OTSStream *out, const uint16_t glyph_count) {
|
||||
if (!out->WriteU16(1) ||
|
||||
!out->WriteU16(1) ||
|
||||
!out->WriteU16(glyph_count)) {
|
||||
return false;
|
||||
}
|
||||
for (uint16_t class_value = 1; class_value <= glyph_count; ++class_value) {
|
||||
if (!out->WriteU16(class_value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildFakeClassDefFormat2(ots::OTSStream *out, const uint16_t range_count) {
|
||||
if (!out->WriteU16(2) || !out->WriteU16(range_count)) {
|
||||
return false;
|
||||
}
|
||||
uint16_t glyph_id = 1;
|
||||
for (uint16_t class_value = 1; class_value <= range_count; ++class_value) {
|
||||
// Write consecutive ranges in which each range consists of one glyph id.
|
||||
if (!out->WriteU16(glyph_id) ||
|
||||
!out->WriteU16(glyph_id + 1) ||
|
||||
!out->WriteU16(class_value)) {
|
||||
return false;
|
||||
}
|
||||
glyph_id += 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildFakeDeviceTable(ots::OTSStream *out, const uint16_t start_size,
|
||||
const uint16_t end_size, const uint16_t format) {
|
||||
if (!out->WriteU16(start_size) ||
|
||||
!out->WriteU16(end_size) ||
|
||||
!out->WriteU16(format)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const unsigned num_values = std::abs(end_size - start_size) + 1;
|
||||
const unsigned num_bits = (1 << format) * num_values;
|
||||
const unsigned num_units = (num_bits - 1) / 16 + 1;
|
||||
if (!out->Pad(num_units * 2)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class TestStream : public ots::MemoryStream {
|
||||
public:
|
||||
TestStream()
|
||||
: ots::MemoryStream(data_, sizeof(data_)), size_(0) {
|
||||
std::memset(reinterpret_cast<char*>(data_), 0, sizeof(data_));
|
||||
}
|
||||
|
||||
uint8_t* data() { return data_; }
|
||||
size_t size() const { return size_; }
|
||||
|
||||
virtual bool WriteRaw(const void *d, size_t length) {
|
||||
if (Tell() + length > size_) {
|
||||
size_ = Tell() + length;
|
||||
}
|
||||
return ots::MemoryStream::WriteRaw(d, length);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t size_;
|
||||
uint8_t data_[4096];
|
||||
};
|
||||
|
||||
class TableTest : public ::testing::Test {
|
||||
protected:
|
||||
|
||||
virtual void SetUp() {
|
||||
ots::OpenTypeFile *file = new ots::OpenTypeFile();
|
||||
file->context = new ots::OTSContext();
|
||||
font = new ots::Font(file);
|
||||
}
|
||||
|
||||
TestStream out;
|
||||
ots::Font *font;
|
||||
};
|
||||
|
||||
class ScriptListTableTest : public TableTest { };
|
||||
class DeviceTableTest : public TableTest { };
|
||||
class CoverageTableTest : public TableTest { };
|
||||
class CoverageFormat1Test : public TableTest { };
|
||||
class CoverageFormat2Test : public TableTest { };
|
||||
class ClassDefTableTest : public TableTest { };
|
||||
class ClassDefFormat1Test : public TableTest { };
|
||||
class ClassDefFormat2Test : public TableTest { };
|
||||
class LookupSubtableParserTest : public TableTest { };
|
||||
|
||||
class FeatureListTableTest : public TableTest {
|
||||
protected:
|
||||
|
||||
virtual void SetUp() {
|
||||
TableTest::SetUp();
|
||||
num_features = 0;
|
||||
}
|
||||
|
||||
uint16_t num_features;
|
||||
};
|
||||
|
||||
bool fakeTypeParserReturnsTrue(const ots::Font*, const uint8_t *,
|
||||
const size_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fakeTypeParserReturnsFalse(const ots::Font*, const uint8_t *,
|
||||
const size_t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ots::LookupSubtableParser::TypeParser TypeParsersReturnTrue[] = {
|
||||
{1, fakeTypeParserReturnsTrue},
|
||||
{2, fakeTypeParserReturnsTrue},
|
||||
{3, fakeTypeParserReturnsTrue},
|
||||
{4, fakeTypeParserReturnsTrue},
|
||||
{5, fakeTypeParserReturnsTrue}
|
||||
};
|
||||
|
||||
// Fake lookup subtable parser which always returns true.
|
||||
const ots::LookupSubtableParser FakeLookupParserReturnsTrue = {
|
||||
5, 5, TypeParsersReturnTrue,
|
||||
};
|
||||
|
||||
const ots::LookupSubtableParser::TypeParser TypeParsersReturnFalse[] = {
|
||||
{1, fakeTypeParserReturnsFalse}
|
||||
};
|
||||
|
||||
// Fake lookup subtable parser which always returns false.
|
||||
const ots::LookupSubtableParser FakeLookupParserReturnsFalse = {
|
||||
1, 1, TypeParsersReturnFalse
|
||||
};
|
||||
|
||||
class LookupListTableTest : public TableTest {
|
||||
protected:
|
||||
|
||||
virtual void SetUp() {
|
||||
TableTest::SetUp();
|
||||
num_lookups = 0;
|
||||
}
|
||||
|
||||
bool Parse() {
|
||||
return ots::ParseLookupListTable(font, out.data(), out.size(),
|
||||
&FakeLookupParserReturnsTrue,
|
||||
&num_lookups);
|
||||
}
|
||||
|
||||
uint16_t num_lookups;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(ScriptListTableTest, TestSuccess) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
EXPECT_TRUE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestBadScriptCount) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set too large script count.
|
||||
out.Seek(0);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestScriptRecordOffsetUnderflow) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set bad offset to ScriptRecord[0].
|
||||
out.Seek(6);
|
||||
out.WriteU16(0);
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestScriptRecordOffsetOverflow) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set bad offset to ScriptRecord[0].
|
||||
out.Seek(6);
|
||||
out.WriteU16(out.size());
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestBadLangSysCount) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set too large langsys count.
|
||||
out.Seek(10);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestLangSysRecordOffsetUnderflow) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set bad offset to LangSysRecord[0].
|
||||
out.Seek(16);
|
||||
out.WriteU16(0);
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestLangSysRecordOffsetOverflow) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set bad offset to LangSysRecord[0].
|
||||
out.Seek(16);
|
||||
out.WriteU16(out.size());
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestBadReqFeatureIndex) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set too large feature index to ReqFeatureIndex of LangSysTable[0].
|
||||
out.Seek(20);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestBadFeatureCount) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set too large feature count to LangSysTable[0].
|
||||
out.Seek(22);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(ScriptListTableTest, TestBadFeatureIndex) {
|
||||
BuildFakeScriptListTable(&out, 1, 1, 1);
|
||||
// Set too large feature index to ReatureIndex[0] of LangSysTable[0].
|
||||
out.Seek(24);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseScriptListTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(FeatureListTableTest, TestSuccess) {
|
||||
BuildFakeFeatureListTable(&out, 1, 1);
|
||||
EXPECT_TRUE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
|
||||
&num_features));
|
||||
EXPECT_EQ(num_features, 1);
|
||||
}
|
||||
|
||||
TEST_F(FeatureListTableTest, TestSuccess2) {
|
||||
BuildFakeFeatureListTable(&out, 5, 1);
|
||||
EXPECT_TRUE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
|
||||
&num_features));
|
||||
EXPECT_EQ(num_features, 5);
|
||||
}
|
||||
|
||||
TEST_F(FeatureListTableTest, TestBadFeatureCount) {
|
||||
BuildFakeFeatureListTable(&out, 1, 1);
|
||||
// Set too large feature count.
|
||||
out.Seek(0);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
|
||||
&num_features));
|
||||
}
|
||||
|
||||
TEST_F(FeatureListTableTest, TestOffsetFeatureUnderflow) {
|
||||
BuildFakeFeatureListTable(&out, 1, 1);
|
||||
// Set bad offset to FeatureRecord[0].
|
||||
out.Seek(6);
|
||||
out.WriteU16(0);
|
||||
EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
|
||||
&num_features));
|
||||
}
|
||||
|
||||
TEST_F(FeatureListTableTest, TestOffsetFeatureOverflow) {
|
||||
BuildFakeFeatureListTable(&out, 1, 1);
|
||||
// Set bad offset to FeatureRecord[0].
|
||||
out.Seek(6);
|
||||
out.WriteU16(out.size());
|
||||
EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
|
||||
&num_features));
|
||||
}
|
||||
|
||||
TEST_F(FeatureListTableTest, TestBadLookupCount) {
|
||||
BuildFakeFeatureListTable(&out, 1, 1);
|
||||
// Set too large lookup count to FeatureTable[0].
|
||||
out.Seek(10);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseFeatureListTable(font, out.data(), out.size(), 1,
|
||||
&num_features));
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TestSuccess) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
EXPECT_TRUE(Parse());
|
||||
EXPECT_EQ(num_lookups, 1);
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TestSuccess2) {
|
||||
BuildFakeLookupListTable(&out, 5, 1);
|
||||
EXPECT_TRUE(Parse());
|
||||
EXPECT_EQ(num_lookups, 5);
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TestOffsetLookupTableUnderflow) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set bad offset to Lookup[0].
|
||||
out.Seek(2);
|
||||
out.WriteU16(0);
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TestOffsetLookupTableOverflow) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set bad offset to Lookup[0].
|
||||
out.Seek(2);
|
||||
out.WriteU16(out.size());
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TestOffsetSubtableUnderflow) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set bad offset to SubTable[0] of LookupTable[0].
|
||||
out.Seek(10);
|
||||
out.WriteU16(0);
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TestOffsetSubtableOverflow) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set bad offset to SubTable[0] of LookupTable[0].
|
||||
out.Seek(10);
|
||||
out.WriteU16(out.size());
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TesBadLookupCount) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set too large lookup count of LookupTable[0].
|
||||
out.Seek(0);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TesBadLookupType) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set too large lookup type of LookupTable[0].
|
||||
out.Seek(4);
|
||||
out.WriteU16(6);
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TesBadLookupFlag) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set IgnoreBaseGlyphs(0x0002) to the lookup flag of LookupTable[0].
|
||||
out.Seek(6);
|
||||
out.WriteU16(0x0002);
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(LookupListTableTest, TesBadSubtableCount) {
|
||||
BuildFakeLookupListTable(&out, 1, 1);
|
||||
// Set too large sutable count of LookupTable[0].
|
||||
out.Seek(8);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(Parse());
|
||||
}
|
||||
|
||||
TEST_F(CoverageTableTest, TestSuccessFormat1) {
|
||||
BuildFakeCoverageFormat1(&out, 1);
|
||||
EXPECT_TRUE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(CoverageTableTest, TestSuccessFormat2) {
|
||||
BuildFakeCoverageFormat2(&out, 1);
|
||||
EXPECT_TRUE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(CoverageTableTest, TestBadFormat) {
|
||||
BuildFakeCoverageFormat1(&out, 1);
|
||||
// Set bad format.
|
||||
out.Seek(0);
|
||||
out.WriteU16(3);
|
||||
EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(CoverageFormat1Test, TestBadGlyphCount) {
|
||||
BuildFakeCoverageFormat1(&out, 1);
|
||||
// Set too large glyph count.
|
||||
out.Seek(2);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(CoverageFormat1Test, TestBadGlyphId) {
|
||||
BuildFakeCoverageFormat1(&out, 1);
|
||||
// Set too large glyph id.
|
||||
out.Seek(4);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(CoverageFormat2Test, TestBadRangeCount) {
|
||||
BuildFakeCoverageFormat2(&out, 1);
|
||||
// Set too large range count.
|
||||
out.Seek(2);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(CoverageFormat2Test, TestBadRange) {
|
||||
BuildFakeCoverageFormat2(&out, 1);
|
||||
// Set reverse order glyph id to start/end fields.
|
||||
out.Seek(4);
|
||||
out.WriteU16(2);
|
||||
out.WriteU16(1);
|
||||
EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 1));
|
||||
}
|
||||
|
||||
TEST_F(CoverageFormat2Test, TestRangeOverlap) {
|
||||
BuildFakeCoverageFormat2(&out, 2);
|
||||
// Set overlapping glyph id to an end field.
|
||||
out.Seek(12);
|
||||
out.WriteU16(1);
|
||||
EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 2));
|
||||
}
|
||||
|
||||
TEST_F(CoverageFormat2Test, TestRangeOverlap2) {
|
||||
BuildFakeCoverageFormat2(&out, 2);
|
||||
// Set overlapping range.
|
||||
out.Seek(10);
|
||||
out.WriteU16(1);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseCoverageTable(font, out.data(), out.size(), 2));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefTableTest, TestSuccessFormat1) {
|
||||
BuildFakeClassDefFormat1(&out, 1);
|
||||
EXPECT_TRUE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefTableTest, TestSuccessFormat2) {
|
||||
BuildFakeClassDefFormat2(&out, 1);
|
||||
EXPECT_TRUE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefTableTest, TestBadFormat) {
|
||||
BuildFakeClassDefFormat1(&out, 1);
|
||||
// Set bad format.
|
||||
out.Seek(0);
|
||||
out.WriteU16(3);
|
||||
EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefFormat1Test, TestBadStartGlyph) {
|
||||
BuildFakeClassDefFormat1(&out, 1);
|
||||
// Set too large start glyph id.
|
||||
out.Seek(2);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefFormat1Test, TestBadGlyphCount) {
|
||||
BuildFakeClassDefFormat1(&out, 1);
|
||||
// Set too large glyph count.
|
||||
out.Seek(4);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefFormat1Test, TestBadClassValue) {
|
||||
BuildFakeClassDefFormat1(&out, 1);
|
||||
// Set too large class value.
|
||||
out.Seek(6);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefFormat2Test, TestBadRangeCount) {
|
||||
BuildFakeClassDefFormat2(&out, 1);
|
||||
// Set too large range count.
|
||||
out.Seek(2);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefFormat2Test, TestRangeOverlap) {
|
||||
BuildFakeClassDefFormat2(&out, 2);
|
||||
// Set overlapping glyph id to an end field.
|
||||
out.Seek(12);
|
||||
out.WriteU16(1);
|
||||
EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(ClassDefFormat2Test, TestRangeOverlap2) {
|
||||
BuildFakeClassDefFormat2(&out, 2);
|
||||
// Set overlapping range.
|
||||
out.Seek(10);
|
||||
out.WriteU16(1);
|
||||
out.WriteU16(2);
|
||||
EXPECT_FALSE(ots::ParseClassDefTable(font, out.data(), out.size(), 1, 1));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat1Success) {
|
||||
BuildFakeDeviceTable(&out, 1, 8, 1);
|
||||
EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat1Success2) {
|
||||
BuildFakeDeviceTable(&out, 1, 9, 1);
|
||||
EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat1Fail) {
|
||||
// Pass shorter length than expected.
|
||||
BuildFakeDeviceTable(&out, 1, 8, 1);
|
||||
EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat1Fail2) {
|
||||
// Pass shorter length than expected.
|
||||
BuildFakeDeviceTable(&out, 1, 9, 1);
|
||||
EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat2Success) {
|
||||
BuildFakeDeviceTable(&out, 1, 1, 2);
|
||||
EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat2Success2) {
|
||||
BuildFakeDeviceTable(&out, 1, 8, 2);
|
||||
EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat2Fail) {
|
||||
// Pass shorter length than expected.
|
||||
BuildFakeDeviceTable(&out, 1, 8, 2);
|
||||
EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat2Fail2) {
|
||||
// Pass shorter length than expected.
|
||||
BuildFakeDeviceTable(&out, 1, 9, 2);
|
||||
EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat3Success) {
|
||||
BuildFakeDeviceTable(&out, 1, 1, 3);
|
||||
EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat3Success2) {
|
||||
BuildFakeDeviceTable(&out, 1, 8, 3);
|
||||
EXPECT_TRUE(ots::ParseDeviceTable(font, out.data(), out.size()));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat3Fail) {
|
||||
// Pass shorter length than expected.
|
||||
BuildFakeDeviceTable(&out, 1, 8, 3);
|
||||
EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
|
||||
}
|
||||
|
||||
TEST_F(DeviceTableTest, TestDeltaFormat3Fail2) {
|
||||
// Pass shorter length than expected.
|
||||
BuildFakeDeviceTable(&out, 1, 9, 3);
|
||||
EXPECT_FALSE(ots::ParseDeviceTable(font, out.data(), out.size() - 1));
|
||||
}
|
||||
|
||||
TEST_F(LookupSubtableParserTest, TestSuccess) {
|
||||
{
|
||||
EXPECT_TRUE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 1));
|
||||
}
|
||||
{
|
||||
EXPECT_TRUE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 5));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(LookupSubtableParserTest, TestFail) {
|
||||
{
|
||||
// Pass bad lookup type which less than the smallest type.
|
||||
EXPECT_FALSE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 0));
|
||||
}
|
||||
{
|
||||
// Pass bad lookup type which greater than the maximum type.
|
||||
EXPECT_FALSE(FakeLookupParserReturnsTrue.Parse(font, 0, 0, 6));
|
||||
}
|
||||
{
|
||||
// Check the type parser failure.
|
||||
EXPECT_FALSE(FakeLookupParserReturnsFalse.Parse(font, 0, 0, 1));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "gsub.h"
|
||||
#include "ots.h"
|
||||
#include "ots-memory-stream.h"
|
||||
#include "vhea.h"
|
||||
#include "vmtx.h"
|
||||
|
||||
#define SET_TABLE(name, capname) \
|
||||
do { font->name = new ots::OpenType##capname; } while (0)
|
||||
#define SET_LAYOUT_TABLE(name, capname) \
|
||||
do { \
|
||||
if (!font->name) { \
|
||||
SET_TABLE(name, capname); \
|
||||
} \
|
||||
font->name->data = reinterpret_cast<const uint8_t*>(1); \
|
||||
font->name->length = 1; \
|
||||
} while (0)
|
||||
#define DROP_TABLE(name) \
|
||||
do { delete font->name; font->name = NULL; } while (0)
|
||||
#define DROP_LAYOUT_TABLE(name) \
|
||||
do { font->name->data = NULL; font->name->length = 0; } while (0)
|
||||
|
||||
namespace {
|
||||
|
||||
class TableDependenciesTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
font = new ots::Font(new ots::OpenTypeFile);
|
||||
SET_LAYOUT_TABLE(gsub, GSUB);
|
||||
SET_TABLE(vhea, VHEA);
|
||||
SET_TABLE(vmtx, VMTX);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
DROP_TABLE(gsub);
|
||||
DROP_TABLE(vhea);
|
||||
DROP_TABLE(vmtx);
|
||||
}
|
||||
ots::Font *font;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_F(TableDependenciesTest, TestVhea) {
|
||||
EXPECT_TRUE(ots::ots_vhea_should_serialise(font));
|
||||
}
|
||||
|
||||
TEST_F(TableDependenciesTest, TestVmtx) {
|
||||
EXPECT_TRUE(ots::ots_vmtx_should_serialise(font));
|
||||
}
|
||||
|
||||
TEST_F(TableDependenciesTest, TestVheaVmtx) {
|
||||
DROP_TABLE(vmtx);
|
||||
EXPECT_FALSE(ots::ots_vhea_should_serialise(font));
|
||||
}
|
||||
|
||||
TEST_F(TableDependenciesTest, TestVmtxVhea) {
|
||||
DROP_TABLE(vhea);
|
||||
EXPECT_FALSE(ots::ots_vmtx_should_serialise(font));
|
||||
}
|
||||
|
|
@ -39,6 +39,17 @@ UNIFIED_SOURCES += [ '/gfx/2d/unittest/%s' % p for p in [
|
|||
'TestScaling.cpp',
|
||||
]]
|
||||
|
||||
# not UNIFIED_SOURCES because layout_common_table_test.cc has classes
|
||||
# in an anonymous namespace which result in a GCC error when used in
|
||||
# tests (e g. "error: 'ScriptListTableTest_TestSuccess_Test' has a field
|
||||
# 'ScriptListTableTest_TestSuccess_Test::<anonymous>' whose type uses
|
||||
# the anonymous namespace").
|
||||
SOURCES += [ '/gfx/ots/tests/%s' % p for p in [
|
||||
'cff_type2_charstring_test.cc',
|
||||
'layout_common_table_test.cc',
|
||||
'table_dependencies_test.cc',
|
||||
]]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
@ -46,6 +57,7 @@ LOCAL_INCLUDES += [
|
|||
'/gfx/2d/unittest',
|
||||
'/gfx/config',
|
||||
'/gfx/layers',
|
||||
'/gfx/ots/src',
|
||||
'/gfx/qcms',
|
||||
]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче