diff options
author | tsepez <tsepez@chromium.org> | 2016-10-03 15:40:36 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-10-03 15:40:36 -0700 |
commit | aba528a362248a54b27a7e9e046e2b65ab83f624 (patch) | |
tree | 41e642d7316dd947f63e3dd246eb0cd8a345f74c /core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp | |
parent | 36eb4bdcae719cf33c536ff72ac000482aed8382 (diff) | |
download | pdfium-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.cpp | 32 |
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(); |