Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp

Issue 2387193003: Revert of Assert that only 0-numbered objects are Released() (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/fpdf_parser/cpdf_object.cpp ('k') | core/fpdfapi/fpdf_parser/cpdf_parser.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 PDFium Authors. All rights reserved. 1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/fpdfapi/fpdf_parser/cpdf_array.h" 5 #include "core/fpdfapi/fpdf_parser/cpdf_array.h"
6 #include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" 6 #include "core/fpdfapi/fpdf_parser/cpdf_boolean.h"
7 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" 7 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
8 #include "core/fpdfapi/fpdf_parser/cpdf_name.h" 8 #include "core/fpdfapi/fpdf_parser/cpdf_name.h"
9 #include "core/fpdfapi/fpdf_parser/cpdf_null.h" 9 #include "core/fpdfapi/fpdf_parser/cpdf_null.h"
10 #include "core/fpdfapi/fpdf_parser/cpdf_number.h" 10 #include "core/fpdfapi/fpdf_parser/cpdf_number.h"
11 #include "core/fpdfapi/fpdf_parser/cpdf_reference.h" 11 #include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
12 #include "core/fpdfapi/fpdf_parser/cpdf_stream.h" 12 #include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
13 #include "core/fpdfapi/fpdf_parser/cpdf_string.h" 13 #include "core/fpdfapi/fpdf_parser/cpdf_string.h"
14 14
15 #include <memory> 15 #include <memory>
16 #include <string> 16 #include <string>
17 #include <vector> 17 #include <vector>
18 18
19 #include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h" 19 #include "core/fpdfapi/fpdf_parser/cpdf_indirect_object_holder.h"
20 #include "core/fxcrt/fx_basic.h" 20 #include "core/fxcrt/fx_basic.h"
21 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
22 22
23 namespace { 23 namespace {
24 24
25 using ScopedArray = std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>>; 25 using ScopedArray = std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>>;
26 using ScopedDict = 26 using ScopedDict =
27 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>>; 27 std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>>;
28 using ScopedStream = std::unique_ptr<CPDF_Stream, ReleaseDeleter<CPDF_Stream>>;
29 28
30 void TestArrayAccessors(const CPDF_Array* arr, 29 void TestArrayAccessors(const CPDF_Array* arr,
31 size_t index, 30 size_t index,
32 const char* str_val, 31 const char* str_val,
33 const char* const_str_val, 32 const char* const_str_val,
34 int int_val, 33 int int_val,
35 float float_val, 34 float float_val,
36 CPDF_Array* arr_val, 35 CPDF_Array* arr_val,
37 CPDF_Dictionary* dict_val, 36 CPDF_Dictionary* dict_val,
38 CPDF_Stream* stream_val) { 37 CPDF_Stream* stream_val) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 m_DirectObjTypes = { 88 m_DirectObjTypes = {
90 CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER, 89 CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER,
91 CPDF_Object::NUMBER, CPDF_Object::STRING, CPDF_Object::STRING, 90 CPDF_Object::NUMBER, CPDF_Object::STRING, CPDF_Object::STRING,
92 CPDF_Object::NAME, CPDF_Object::ARRAY, CPDF_Object::DICTIONARY, 91 CPDF_Object::NAME, CPDF_Object::ARRAY, CPDF_Object::DICTIONARY,
93 CPDF_Object::STREAM, CPDF_Object::NULLOBJ}; 92 CPDF_Object::STREAM, CPDF_Object::NULLOBJ};
94 for (size_t i = 0; i < FX_ArraySize(objs); ++i) 93 for (size_t i = 0; i < FX_ArraySize(objs); ++i)
95 m_DirectObjs.emplace_back(objs[i]); 94 m_DirectObjs.emplace_back(objs[i]);
96 95
97 // Indirect references to indirect objects. 96 // Indirect references to indirect objects.
98 m_ObjHolder.reset(new CPDF_IndirectObjectHolder()); 97 m_ObjHolder.reset(new CPDF_IndirectObjectHolder());
99 m_IndirectObjs = {boolean_true_obj->Clone(), number_int_obj->Clone(), 98 m_IndirectObjs = {boolean_true_obj, number_int_obj, str_spec_obj, name_obj,
100 str_spec_obj->Clone(), name_obj->Clone(), 99 m_ArrayObj, m_DictObj, stream_obj};
101 m_ArrayObj->Clone(), m_DictObj->Clone(),
102 stream_obj->Clone()};
103 for (size_t i = 0; i < m_IndirectObjs.size(); ++i) { 100 for (size_t i = 0; i < m_IndirectObjs.size(); ++i) {
104 m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]); 101 m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]);
105 m_RefObjs.emplace_back(new CPDF_Reference( 102 m_RefObjs.emplace_back(new CPDF_Reference(
106 m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum())); 103 m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum()));
107 } 104 }
108 } 105 }
109 106
110 bool Equal(const CPDF_Object* obj1, const CPDF_Object* obj2) { 107 bool Equal(CPDF_Object* obj1, CPDF_Object* obj2) {
111 if (obj1 == obj2) 108 if (obj1 == obj2)
112 return true; 109 return true;
113 if (!obj1 || !obj2 || obj1->GetType() != obj2->GetType()) 110 if (!obj1 || !obj2 || obj1->GetType() != obj2->GetType())
114 return false; 111 return false;
115 switch (obj1->GetType()) { 112 switch (obj1->GetType()) {
116 case CPDF_Object::BOOLEAN: 113 case CPDF_Object::BOOLEAN:
117 return obj1->GetInteger() == obj2->GetInteger(); 114 return obj1->GetInteger() == obj2->GetInteger();
118 case CPDF_Object::NUMBER: 115 case CPDF_Object::NUMBER:
119 return obj1->AsNumber()->IsInteger() == obj2->AsNumber()->IsInteger() && 116 return obj1->AsNumber()->IsInteger() == obj2->AsNumber()->IsInteger() &&
120 obj1->GetInteger() == obj2->GetInteger(); 117 obj1->GetInteger() == obj2->GetInteger();
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 246 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
250 nullptr, nullptr, m_DictObj, m_StreamDictObj, nullptr}; 247 nullptr, nullptr, m_DictObj, m_StreamDictObj, nullptr};
251 // Check for direct objects. 248 // Check for direct objects.
252 for (size_t i = 0; i < m_DirectObjs.size(); ++i) 249 for (size_t i = 0; i < m_DirectObjs.size(); ++i)
253 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->GetDict()); 250 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->GetDict());
254 251
255 // Check indirect references. 252 // Check indirect references.
256 const CPDF_Dictionary* const indirect_obj_results[] = { 253 const CPDF_Dictionary* const indirect_obj_results[] = {
257 nullptr, nullptr, nullptr, nullptr, nullptr, m_DictObj, m_StreamDictObj}; 254 nullptr, nullptr, nullptr, nullptr, nullptr, m_DictObj, m_StreamDictObj};
258 for (size_t i = 0; i < m_RefObjs.size(); ++i) 255 for (size_t i = 0; i < m_RefObjs.size(); ++i)
259 EXPECT_TRUE(Equal(indirect_obj_results[i], m_RefObjs[i]->GetDict())); 256 EXPECT_EQ(indirect_obj_results[i], m_RefObjs[i]->GetDict());
260 } 257 }
261 258
262 TEST_F(PDFObjectsTest, GetArray) { 259 TEST_F(PDFObjectsTest, GetArray) {
263 const CPDF_Array* const direct_obj_results[] = { 260 const CPDF_Array* const direct_obj_results[] = {
264 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 261 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
265 nullptr, m_ArrayObj, nullptr, nullptr, nullptr}; 262 nullptr, m_ArrayObj, nullptr, nullptr, nullptr};
266 // Check for direct objects. 263 // Check for direct objects.
267 for (size_t i = 0; i < m_DirectObjs.size(); ++i) 264 for (size_t i = 0; i < m_DirectObjs.size(); ++i)
268 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->AsArray()); 265 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->AsArray());
269 266
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 ASSERT_TRUE(cloned_dict_object->IsDictionary()); 780 ASSERT_TRUE(cloned_dict_object->IsDictionary());
784 781
785 ScopedDict cloned_dict(cloned_dict_object->AsDictionary()); 782 ScopedDict cloned_dict(cloned_dict_object->AsDictionary());
786 ASSERT_EQ(1U, cloned_dict->GetCount()); 783 ASSERT_EQ(1U, cloned_dict->GetCount());
787 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); 784 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo");
788 EXPECT_FALSE(cloned_obj); 785 EXPECT_FALSE(cloned_obj);
789 } 786 }
790 787
791 TEST(PDFObjectTest, CloneCheckLoop) { 788 TEST(PDFObjectTest, CloneCheckLoop) {
792 { 789 {
793 // Create a dictionary/array pair with a reference loop. 790 // Create an object with a reference loop.
791 ScopedArray arr_obj(new CPDF_Array);
792 // Dictionary object.
794 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); 793 CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
795 ScopedArray arr_obj(new CPDF_Array);
796 dict_obj->SetFor("arr", arr_obj.get()); 794 dict_obj->SetFor("arr", arr_obj.get());
797 arr_obj->InsertAt(0, dict_obj); 795 arr_obj->InsertAt(0, dict_obj);
798 796
799 // Clone this object to see whether stack overflow will be triggered. 797 // Clone this object to see whether stack overflow will be triggered.
800 ScopedArray cloned_array(arr_obj->Clone()->AsArray()); 798 ScopedArray cloned_array(arr_obj->Clone()->AsArray());
801 // Cloned object should be the same as the original. 799 // Cloned object should be the same as the original.
802 ASSERT_TRUE(cloned_array); 800 ASSERT_TRUE(cloned_array);
803 EXPECT_EQ(1u, cloned_array->GetCount()); 801 EXPECT_EQ(1u, cloned_array->GetCount());
804 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); 802 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0);
805 ASSERT_TRUE(cloned_dict); 803 ASSERT_TRUE(cloned_dict);
806 ASSERT_TRUE(cloned_dict->IsDictionary()); 804 ASSERT_TRUE(cloned_dict->IsDictionary());
807 // Recursively referenced object is not cloned. 805 // Recursively referenced object is not cloned.
808 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); 806 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr"));
809 } 807 }
810 { 808 {
811 // Create a dictionary/stream pair with a reference loop.
812 CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
813 ScopedStream stream_obj(new CPDF_Stream(nullptr, 0, dict_obj));
814 dict_obj->SetFor("stream", stream_obj.get());
815
816 // Clone this object to see whether stack overflow will be triggered.
817 ScopedStream cloned_stream(stream_obj->Clone()->AsStream());
818 // Cloned object should be the same as the original.
819 ASSERT_TRUE(cloned_stream);
820 CPDF_Object* cloned_dict = cloned_stream->GetDict();
821 ASSERT_TRUE(cloned_dict);
822 ASSERT_TRUE(cloned_dict->IsDictionary());
823 // Recursively referenced object is not cloned.
824 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream"));
825 }
826 {
827 CPDF_IndirectObjectHolder objects_holder; 809 CPDF_IndirectObjectHolder objects_holder;
828 // Create an object with a reference loop. 810 // Create an object with a reference loop.
829 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); 811 CPDF_Dictionary* dict_obj = new CPDF_Dictionary();
830 CPDF_Array* arr_obj = new CPDF_Array; 812 CPDF_Array* arr_obj = new CPDF_Array;
831 objects_holder.AddIndirectObject(dict_obj); 813 objects_holder.AddIndirectObject(dict_obj);
832 EXPECT_EQ(1u, dict_obj->GetObjNum()); 814 EXPECT_EQ(1u, dict_obj->GetObjNum());
833 dict_obj->SetFor("arr", arr_obj); 815 dict_obj->SetFor("arr", arr_obj);
834 arr_obj->InsertAt( 816 arr_obj->InsertAt(
835 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum())); 817 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum()));
836 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); 818 CPDF_Object* elem0 = arr_obj->GetObjectAt(0);
837 ASSERT_TRUE(elem0); 819 ASSERT_TRUE(elem0);
838 ASSERT_TRUE(elem0->IsReference()); 820 ASSERT_TRUE(elem0->IsReference());
839 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); 821 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum());
840 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); 822 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect());
841 823
842 // Clone this object to see whether stack overflow will be triggered. 824 // Clone this object to see whether stack overflow will be triggered.
843 ScopedDict cloned_dict(ToDictionary(dict_obj->CloneDirectObject())); 825 ScopedDict cloned_dict(ToDictionary(dict_obj->CloneDirectObject()));
844 // Cloned object should be the same as the original. 826 // Cloned object should be the same as the original.
845 ASSERT_TRUE(cloned_dict); 827 ASSERT_TRUE(cloned_dict);
846 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); 828 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr");
847 ASSERT_TRUE(cloned_arr); 829 ASSERT_TRUE(cloned_arr);
848 ASSERT_TRUE(cloned_arr->IsArray()); 830 ASSERT_TRUE(cloned_arr->IsArray());
849 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); 831 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount());
850 // Recursively referenced object is not cloned. 832 // Recursively referenced object is not cloned.
851 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); 833 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0));
852 } 834 }
853 } 835 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_parser/cpdf_object.cpp ('k') | core/fpdfapi/fpdf_parser/cpdf_parser.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698