summaryrefslogtreecommitdiff
path: root/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-10-03 15:40:36 -0700
committerCommit bot <commit-bot@chromium.org>2016-10-03 15:40:36 -0700
commitaba528a362248a54b27a7e9e046e2b65ab83f624 (patch)
tree41e642d7316dd947f63e3dd246eb0cd8a345f74c /core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp
parent36eb4bdcae719cf33c536ff72ac000482aed8382 (diff)
downloadpdfium-aba528a362248a54b27a7e9e046e2b65ab83f624.tar.xz
Assert that only 0-numbered objects are Released()
This condition holds because numbered objects are brute-force deleted by the indirect object holder, rather than being released. Be careful about recursive deletion, check before advancing, since we no longer count on Release() doing this for us. Fix a few tests where the test was violating ownership rules. This should be the last step before completely removing Release() in favor of direct delete everywhere. Review-Url: https://codereview.chromium.org/2375343004
Diffstat (limited to 'core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp')
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp32
1 files changed, 25 insertions, 7 deletions
diff --git a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp
index 9b702099bb..6181571229 100644
--- a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp
+++ b/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp
@@ -25,6 +25,7 @@ namespace {
using ScopedArray = std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>>;
using ScopedDict =
std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>>;
+using ScopedStream = std::unique_ptr<CPDF_Stream, ReleaseDeleter<CPDF_Stream>>;
void TestArrayAccessors(const CPDF_Array* arr,
size_t index,
@@ -95,8 +96,10 @@ class PDFObjectsTest : public testing::Test {
// Indirect references to indirect objects.
m_ObjHolder.reset(new CPDF_IndirectObjectHolder());
- m_IndirectObjs = {boolean_true_obj, number_int_obj, str_spec_obj, name_obj,
- m_ArrayObj, m_DictObj, stream_obj};
+ m_IndirectObjs = {boolean_true_obj->Clone(), number_int_obj->Clone(),
+ str_spec_obj->Clone(), name_obj->Clone(),
+ m_ArrayObj->Clone(), m_DictObj->Clone(),
+ stream_obj->Clone()};
for (size_t i = 0; i < m_IndirectObjs.size(); ++i) {
m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]);
m_RefObjs.emplace_back(new CPDF_Reference(
@@ -104,7 +107,7 @@ class PDFObjectsTest : public testing::Test {
}
}
- bool Equal(CPDF_Object* obj1, CPDF_Object* obj2) {
+ bool Equal(const CPDF_Object* obj1, const CPDF_Object* obj2) {
if (obj1 == obj2)
return true;
if (!obj1 || !obj2 || obj1->GetType() != obj2->GetType())
@@ -253,7 +256,7 @@ TEST_F(PDFObjectsTest, GetDict) {
const CPDF_Dictionary* const indirect_obj_results[] = {
nullptr, nullptr, nullptr, nullptr, nullptr, m_DictObj, m_StreamDictObj};
for (size_t i = 0; i < m_RefObjs.size(); ++i)
- EXPECT_EQ(indirect_obj_results[i], m_RefObjs[i]->GetDict());
+ EXPECT_TRUE(Equal(indirect_obj_results[i], m_RefObjs[i]->GetDict()));
}
TEST_F(PDFObjectsTest, GetArray) {
@@ -787,10 +790,9 @@ TEST(PDFDictionaryTest, CloneDirectObject) {
TEST(PDFObjectTest, CloneCheckLoop) {
{
- // Create an object with a reference loop.
- ScopedArray arr_obj(new CPDF_Array);
- // Dictionary object.
+ // Create a dictionary/array pair with a reference loop.
CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
+ ScopedArray arr_obj(new CPDF_Array);
dict_obj->SetFor("arr", arr_obj.get());
arr_obj->InsertAt(0, dict_obj);
@@ -806,6 +808,22 @@ TEST(PDFObjectTest, CloneCheckLoop) {
EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr"));
}
{
+ // Create a dictionary/stream pair with a reference loop.
+ CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
+ ScopedStream stream_obj(new CPDF_Stream(nullptr, 0, dict_obj));
+ dict_obj->SetFor("stream", stream_obj.get());
+
+ // Clone this object to see whether stack overflow will be triggered.
+ ScopedStream cloned_stream(stream_obj->Clone()->AsStream());
+ // Cloned object should be the same as the original.
+ ASSERT_TRUE(cloned_stream);
+ CPDF_Object* cloned_dict = cloned_stream->GetDict();
+ ASSERT_TRUE(cloned_dict);
+ ASSERT_TRUE(cloned_dict->IsDictionary());
+ // Recursively referenced object is not cloned.
+ EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream"));
+ }
+ {
CPDF_IndirectObjectHolder objects_holder;
// Create an object with a reference loop.
CPDF_Dictionary* dict_obj = new CPDF_Dictionary();