summaryrefslogtreecommitdiff
path: root/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp')
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp263
1 files changed, 239 insertions, 24 deletions
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp
index 3965399254..9de31c8673 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_objects_unittest.cpp
@@ -26,9 +26,9 @@ class PDFObjectsTest : public testing::Test {
// Name object.
CPDF_Name* name_obj = new CPDF_Name("space");
// Array object.
- CPDF_Array* array_obj = new CPDF_Array;
- array_obj->InsertAt(0, new CPDF_Number(8902));
- array_obj->InsertAt(1, new CPDF_Name("address"));
+ m_ArrayObj = new CPDF_Array;
+ m_ArrayObj->InsertAt(0, new CPDF_Number(8902));
+ m_ArrayObj->InsertAt(1, new CPDF_Name("address"));
// Dictionary object.
m_DictObj = new CPDF_Dictionary;
m_DictObj->SetAt("bool", new CPDF_Boolean(false));
@@ -47,23 +47,92 @@ class PDFObjectsTest : public testing::Test {
// All direct objects.
CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj,
number_float_obj, str_reg_obj, str_spec_obj,
- name_obj, array_obj, m_DictObj,
+ name_obj, m_ArrayObj, m_DictObj,
stream_obj, null_obj};
- for (int i = 0; i < FX_ArraySize(objs); ++i)
+ m_DirectObjTypes = {
+ CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER,
+ CPDF_Object::NUMBER, CPDF_Object::STRING, CPDF_Object::STRING,
+ CPDF_Object::NAME, CPDF_Object::ARRAY, CPDF_Object::DICTIONARY,
+ CPDF_Object::STREAM, CPDF_Object::NULLOBJ};
+ for (size_t i = 0; i < FX_ArraySize(objs); ++i)
m_DirectObjs.emplace_back(objs[i]);
// Indirect references to indirect objects.
m_ObjHolder.reset(new CPDF_IndirectObjectHolder(nullptr));
- CPDF_Object* referred_objs[] = {
- boolean_true_obj, number_int_obj, str_spec_obj, name_obj,
- array_obj, m_DictObj, stream_obj};
- for (int i = 0; i < FX_ArraySize(referred_objs); ++i) {
- m_ObjHolder->AddIndirectObject(referred_objs[i]);
- m_RefObjs.emplace_back(
- new CPDF_Reference(m_ObjHolder.get(), referred_objs[i]->GetObjNum()));
+ m_IndirectObjs = {boolean_true_obj, number_int_obj, str_spec_obj, name_obj,
+ m_ArrayObj, m_DictObj, stream_obj};
+ for (size_t i = 0; i < m_IndirectObjs.size(); ++i) {
+ m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]);
+ m_RefObjs.emplace_back(new CPDF_Reference(
+ m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum()));
}
}
+ bool Equal(CPDF_Object* obj1, CPDF_Object* obj2) {
+ if (obj1 == obj2)
+ return true;
+ if (!obj1 || !obj2 || obj1->GetType() != obj2->GetType())
+ return false;
+ switch (obj1->GetType()) {
+ case CPDF_Object::BOOLEAN:
+ return obj1->GetInteger() == obj2->GetInteger();
+ case CPDF_Object::NUMBER:
+ return obj1->AsNumber()->IsInteger() == obj2->AsNumber()->IsInteger() &&
+ obj1->GetInteger() == obj2->GetInteger();
+ case CPDF_Object::STRING:
+ case CPDF_Object::NAME:
+ return obj1->GetString() == obj2->GetString();
+ case CPDF_Object::ARRAY: {
+ const CPDF_Array* array1 = obj1->AsArray();
+ const CPDF_Array* array2 = obj2->AsArray();
+ if (array1->GetCount() != array2->GetCount())
+ return false;
+ for (size_t i = 0; i < array1->GetCount(); ++i) {
+ if (!Equal(array1->GetElement(i), array2->GetElement(i)))
+ return false;
+ }
+ return true;
+ }
+ case CPDF_Object::DICTIONARY: {
+ const CPDF_Dictionary* dict1 = obj1->AsDictionary();
+ const CPDF_Dictionary* dict2 = obj2->AsDictionary();
+ if (dict1->GetCount() != dict2->GetCount())
+ return false;
+ for (CPDF_Dictionary::const_iterator it = dict1->begin();
+ it != dict1->end(); ++it) {
+ if (!Equal(it->second, dict2->GetElement(it->first)))
+ return false;
+ }
+ return true;
+ }
+ case CPDF_Object::NULLOBJ:
+ return true;
+ case CPDF_Object::STREAM: {
+ const CPDF_Stream* stream1 = obj1->AsStream();
+ const CPDF_Stream* stream2 = obj2->AsStream();
+ if (!stream1->GetDict() && !stream2->GetDict())
+ return true;
+ // Compare dictionaries.
+ if (!Equal(stream1->GetDict(), stream2->GetDict()))
+ return false;
+ // Compare sizes.
+ if (stream1->GetRawSize() != stream2->GetRawSize())
+ return false;
+ // Compare contents.
+ // Since this function is used for testing Clone(), only memory based
+ // streams need to be handled.
+ if (!stream1->IsMemoryBased() || !stream2->IsMemoryBased())
+ return false;
+ return FXSYS_memcmp(stream1->GetRawData(), stream2->GetRawData(),
+ stream1->GetRawSize()) == 0;
+ }
+ case CPDF_Object::REFERENCE:
+ return obj1->AsReference()->GetRefObjNum() ==
+ obj2->AsReference()->GetRefObjNum();
+ }
+ return false;
+ }
+
protected:
using ScopedObj = std::unique_ptr<CPDF_Object, ReleaseDeleter<CPDF_Object>>;
@@ -71,9 +140,12 @@ class PDFObjectsTest : public testing::Test {
// refers to some objects in m_DirectObjs.
std::unique_ptr<CPDF_IndirectObjectHolder> m_ObjHolder;
std::vector<ScopedObj> m_DirectObjs;
+ std::vector<int> m_DirectObjTypes;
std::vector<ScopedObj> m_RefObjs;
CPDF_Dictionary* m_DictObj;
CPDF_Dictionary* m_StreamDictObj;
+ CPDF_Array* m_ArrayObj;
+ std::vector<CPDF_Object*> m_IndirectObjs;
};
TEST_F(PDFObjectsTest, GetString) {
@@ -81,13 +153,13 @@ TEST_F(PDFObjectsTest, GetString) {
"false", "true", "1245", "9.00345", "A simple test", "\t\n", "space",
"", "", "", ""};
// Check for direct objects.
- for (int i = 0; i < m_DirectObjs.size(); ++i)
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
EXPECT_STREQ(m_DirectObjs[i]->GetString().c_str(), direct_obj_results[i]);
// Check indirect references.
const char* indirect_obj_results[] = {"true", "1245", "\t\n", "space",
"", "", ""};
- for (int i = 0; i < m_RefObjs.size(); ++i) {
+ for (size_t i = 0; i < m_RefObjs.size(); ++i) {
EXPECT_STREQ(m_RefObjs[i]->GetString().c_str(), indirect_obj_results[i]);
}
}
@@ -97,7 +169,7 @@ TEST_F(PDFObjectsTest, GetConstString) {
nullptr, nullptr, nullptr, nullptr, "A simple test", "\t\n",
"space", nullptr, nullptr, nullptr, nullptr};
// Check for direct objects.
- for (int i = 0; i < m_DirectObjs.size(); ++i) {
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i) {
if (!direct_obj_results[i]) {
EXPECT_EQ(m_DirectObjs[i]->GetConstString().GetCStr(),
direct_obj_results[i]);
@@ -109,38 +181,53 @@ TEST_F(PDFObjectsTest, GetConstString) {
// Check indirect references.
const char* indirect_obj_results[] = {nullptr, nullptr, "\t\n", "space",
nullptr, nullptr, nullptr};
- for (int i = 0; i < m_RefObjs.size(); ++i) {
- if (!indirect_obj_results[i])
+ for (size_t i = 0; i < m_RefObjs.size(); ++i) {
+ if (!indirect_obj_results[i]) {
EXPECT_EQ(m_RefObjs[i]->GetConstString().GetCStr(), nullptr);
- else {
+ } else {
EXPECT_STREQ(m_RefObjs[i]->GetConstString().GetCStr(),
indirect_obj_results[i]);
}
}
}
+TEST_F(PDFObjectsTest, GetUnicodeText) {
+ const wchar_t* direct_obj_results[] = {
+ L"", L"", L"", L"", L"A simple test",
+ L"\t\n", L"space", L"", L"", L"abcdefghijklmnopqrstuvwxyz",
+ L""};
+ // Check for direct objects.
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
+ EXPECT_STREQ(m_DirectObjs[i]->GetUnicodeText().c_str(),
+ direct_obj_results[i]);
+
+ // Check indirect references.
+ for (const auto& it : m_RefObjs)
+ EXPECT_STREQ(it->GetUnicodeText().c_str(), L"");
+}
+
TEST_F(PDFObjectsTest, GetNumber) {
const FX_FLOAT direct_obj_results[] = {0, 0, 1245, 9.00345f, 0, 0,
0, 0, 0, 0, 0};
// Check for direct objects.
- for (int i = 0; i < m_DirectObjs.size(); ++i)
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
EXPECT_EQ(m_DirectObjs[i]->GetNumber(), direct_obj_results[i]);
// Check indirect references.
const FX_FLOAT indirect_obj_results[] = {0, 1245, 0, 0, 0, 0, 0};
- for (int i = 0; i < m_RefObjs.size(); ++i)
+ for (size_t i = 0; i < m_RefObjs.size(); ++i)
EXPECT_EQ(m_RefObjs[i]->GetNumber(), indirect_obj_results[i]);
}
TEST_F(PDFObjectsTest, GetInteger) {
const int direct_obj_results[] = {0, 1, 1245, 9, 0, 0, 0, 0, 0, 0, 0};
// Check for direct objects.
- for (int i = 0; i < m_DirectObjs.size(); ++i)
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
EXPECT_EQ(m_DirectObjs[i]->GetInteger(), direct_obj_results[i]);
// Check indirect references.
const int indirect_obj_results[] = {1, 1245, 0, 0, 0, 0, 0};
- for (int i = 0; i < m_RefObjs.size(); ++i)
+ for (size_t i = 0; i < m_RefObjs.size(); ++i)
EXPECT_EQ(m_RefObjs[i]->GetInteger(), indirect_obj_results[i]);
}
@@ -149,12 +236,140 @@ TEST_F(PDFObjectsTest, GetDict) {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, m_DictObj, m_StreamDictObj, nullptr};
// Check for direct objects.
- for (int i = 0; i < m_DirectObjs.size(); ++i)
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
EXPECT_EQ(m_DirectObjs[i]->GetDict(), direct_obj_results[i]);
// Check indirect references.
const CPDF_Dictionary* indirect_obj_results[] = {
nullptr, nullptr, nullptr, nullptr, nullptr, m_DictObj, m_StreamDictObj};
- for (int i = 0; i < m_RefObjs.size(); ++i)
+ for (size_t i = 0; i < m_RefObjs.size(); ++i)
EXPECT_EQ(m_RefObjs[i]->GetDict(), indirect_obj_results[i]);
}
+
+TEST_F(PDFObjectsTest, GetArray) {
+ const CPDF_Array* direct_obj_results[] = {
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, m_ArrayObj, nullptr, nullptr, nullptr};
+ // Check for direct objects.
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
+ EXPECT_EQ(m_DirectObjs[i]->GetArray(), direct_obj_results[i]);
+
+ // Check indirect references.
+ for (const auto& it : m_RefObjs)
+ EXPECT_EQ(it->GetArray(), nullptr);
+}
+
+TEST_F(PDFObjectsTest, Clone) {
+ // Check for direct objects.
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i) {
+ ScopedObj obj(m_DirectObjs[i]->Clone());
+ EXPECT_TRUE(Equal(m_DirectObjs[i].get(), obj.get()));
+ }
+
+ // Check indirect references.
+ for (const auto& it : m_RefObjs) {
+ ScopedObj obj(it->Clone());
+ EXPECT_TRUE(Equal(it.get(), obj.get()));
+ }
+}
+
+TEST_F(PDFObjectsTest, GetType) {
+ // Check for direct objects.
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
+ EXPECT_EQ(m_DirectObjs[i]->GetType(), m_DirectObjTypes[i]);
+
+ // Check indirect references.
+ for (const auto& it : m_RefObjs)
+ EXPECT_EQ(it->GetType(), CPDF_Object::REFERENCE);
+}
+
+TEST_F(PDFObjectsTest, GetDirect) {
+ // Check for direct objects.
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i)
+ EXPECT_EQ(m_DirectObjs[i]->GetDirect(), m_DirectObjs[i].get());
+
+ // Check indirect references.
+ for (size_t i = 0; i < m_RefObjs.size(); ++i)
+ EXPECT_EQ(m_RefObjs[i]->GetDirect(), m_IndirectObjs[i]);
+}
+
+TEST_F(PDFObjectsTest, SetString) {
+ // Check for direct objects.
+ const char* const set_values[] = {"true", "fake", "3.125f", "097",
+ "changed", "", "NewName"};
+ const char* expected[] = {"true", "false", "3.125", "97",
+ "changed", "", "NewName"};
+ for (size_t i = 0; i < FX_ArraySize(set_values); ++i) {
+ m_DirectObjs[i]->SetString(set_values[i]);
+ EXPECT_STREQ(m_DirectObjs[i]->GetString().c_str(), expected[i]);
+ }
+}
+
+TEST_F(PDFObjectsTest, IsTypeAndAsType) {
+ // Check for direct objects.
+ for (size_t i = 0; i < m_DirectObjs.size(); ++i) {
+ if (m_DirectObjTypes[i] == CPDF_Object::ARRAY) {
+ EXPECT_TRUE(m_DirectObjs[i]->IsArray());
+ EXPECT_EQ(m_DirectObjs[i]->AsArray(), m_DirectObjs[i].get());
+ } else {
+ EXPECT_FALSE(m_DirectObjs[i]->IsArray());
+ EXPECT_EQ(m_DirectObjs[i]->AsArray(), nullptr);
+ }
+
+ if (m_DirectObjTypes[i] == CPDF_Object::BOOLEAN) {
+ EXPECT_TRUE(m_DirectObjs[i]->IsBoolean());
+ EXPECT_EQ(m_DirectObjs[i]->AsBoolean(), m_DirectObjs[i].get());
+ } else {
+ EXPECT_FALSE(m_DirectObjs[i]->IsBoolean());
+ EXPECT_EQ(m_DirectObjs[i]->AsBoolean(), nullptr);
+ }
+
+ if (m_DirectObjTypes[i] == CPDF_Object::NAME) {
+ EXPECT_TRUE(m_DirectObjs[i]->IsName());
+ EXPECT_EQ(m_DirectObjs[i]->AsName(), m_DirectObjs[i].get());
+ } else {
+ EXPECT_FALSE(m_DirectObjs[i]->IsName());
+ EXPECT_EQ(m_DirectObjs[i]->AsName(), nullptr);
+ }
+
+ if (m_DirectObjTypes[i] == CPDF_Object::NUMBER) {
+ EXPECT_TRUE(m_DirectObjs[i]->IsNumber());
+ EXPECT_EQ(m_DirectObjs[i]->AsNumber(), m_DirectObjs[i].get());
+ } else {
+ EXPECT_FALSE(m_DirectObjs[i]->IsNumber());
+ EXPECT_EQ(m_DirectObjs[i]->AsNumber(), nullptr);
+ }
+
+ if (m_DirectObjTypes[i] == CPDF_Object::STRING) {
+ EXPECT_TRUE(m_DirectObjs[i]->IsString());
+ EXPECT_EQ(m_DirectObjs[i]->AsString(), m_DirectObjs[i].get());
+ } else {
+ EXPECT_FALSE(m_DirectObjs[i]->IsString());
+ EXPECT_EQ(m_DirectObjs[i]->AsString(), nullptr);
+ }
+
+ if (m_DirectObjTypes[i] == CPDF_Object::DICTIONARY) {
+ EXPECT_TRUE(m_DirectObjs[i]->IsDictionary());
+ EXPECT_EQ(m_DirectObjs[i]->AsDictionary(), m_DirectObjs[i].get());
+ } else {
+ EXPECT_FALSE(m_DirectObjs[i]->IsDictionary());
+ EXPECT_EQ(m_DirectObjs[i]->AsDictionary(), nullptr);
+ }
+
+ if (m_DirectObjTypes[i] == CPDF_Object::STREAM) {
+ EXPECT_TRUE(m_DirectObjs[i]->IsStream());
+ EXPECT_EQ(m_DirectObjs[i]->AsStream(), m_DirectObjs[i].get());
+ } else {
+ EXPECT_FALSE(m_DirectObjs[i]->IsStream());
+ EXPECT_EQ(m_DirectObjs[i]->AsStream(), nullptr);
+ }
+
+ EXPECT_FALSE(m_DirectObjs[i]->IsReference());
+ EXPECT_EQ(m_DirectObjs[i]->AsReference(), nullptr);
+ }
+ // Check indirect references.
+ for (size_t i = 0; i < m_RefObjs.size(); ++i) {
+ EXPECT_TRUE(m_RefObjs[i]->IsReference());
+ EXPECT_EQ(m_RefObjs[i]->AsReference(), m_RefObjs[i].get());
+ }
+}