OLD | NEW |
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/parser/cpdf_array.h" | 5 #include "core/fpdfapi/parser/cpdf_array.h" |
6 #include "core/fpdfapi/parser/cpdf_boolean.h" | 6 #include "core/fpdfapi/parser/cpdf_boolean.h" |
7 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 7 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
8 #include "core/fpdfapi/parser/cpdf_name.h" | 8 #include "core/fpdfapi/parser/cpdf_name.h" |
9 #include "core/fpdfapi/parser/cpdf_null.h" | 9 #include "core/fpdfapi/parser/cpdf_null.h" |
10 #include "core/fpdfapi/parser/cpdf_number.h" | 10 #include "core/fpdfapi/parser/cpdf_number.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 m_DirectObjTypes = { | 84 m_DirectObjTypes = { |
85 CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER, | 85 CPDF_Object::BOOLEAN, CPDF_Object::BOOLEAN, CPDF_Object::NUMBER, |
86 CPDF_Object::NUMBER, CPDF_Object::STRING, CPDF_Object::STRING, | 86 CPDF_Object::NUMBER, CPDF_Object::STRING, CPDF_Object::STRING, |
87 CPDF_Object::NAME, CPDF_Object::ARRAY, CPDF_Object::DICTIONARY, | 87 CPDF_Object::NAME, CPDF_Object::ARRAY, CPDF_Object::DICTIONARY, |
88 CPDF_Object::STREAM, CPDF_Object::NULLOBJ}; | 88 CPDF_Object::STREAM, CPDF_Object::NULLOBJ}; |
89 for (size_t i = 0; i < FX_ArraySize(objs); ++i) | 89 for (size_t i = 0; i < FX_ArraySize(objs); ++i) |
90 m_DirectObjs.emplace_back(objs[i]); | 90 m_DirectObjs.emplace_back(objs[i]); |
91 | 91 |
92 // Indirect references to indirect objects. | 92 // Indirect references to indirect objects. |
93 m_ObjHolder.reset(new CPDF_IndirectObjectHolder()); | 93 m_ObjHolder.reset(new CPDF_IndirectObjectHolder()); |
94 m_IndirectObjs = {boolean_true_obj->Clone(), number_int_obj->Clone(), | 94 m_IndirectObjs = { |
95 str_spec_obj->Clone(), name_obj->Clone(), | 95 boolean_true_obj->Clone().release(), number_int_obj->Clone().release(), |
96 m_ArrayObj->Clone(), m_DictObj->Clone(), | 96 str_spec_obj->Clone().release(), name_obj->Clone().release(), |
97 stream_obj->Clone()}; | 97 m_ArrayObj->Clone().release(), m_DictObj->Clone().release(), |
| 98 stream_obj->Clone().release()}; |
98 for (size_t i = 0; i < m_IndirectObjs.size(); ++i) { | 99 for (size_t i = 0; i < m_IndirectObjs.size(); ++i) { |
99 m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]); | 100 m_ObjHolder->AddIndirectObject(m_IndirectObjs[i]); |
100 m_RefObjs.emplace_back(new CPDF_Reference( | 101 m_RefObjs.emplace_back(new CPDF_Reference( |
101 m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum())); | 102 m_ObjHolder.get(), m_IndirectObjs[i]->GetObjNum())); |
102 } | 103 } |
103 } | 104 } |
104 | 105 |
105 bool Equal(const CPDF_Object* obj1, const CPDF_Object* obj2) { | 106 bool Equal(const CPDF_Object* obj1, const CPDF_Object* obj2) { |
106 if (obj1 == obj2) | 107 if (obj1 == obj2) |
107 return true; | 108 return true; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->AsArray()); | 262 EXPECT_EQ(direct_obj_results[i], m_DirectObjs[i]->AsArray()); |
262 | 263 |
263 // Check indirect references. | 264 // Check indirect references. |
264 for (const auto& it : m_RefObjs) | 265 for (const auto& it : m_RefObjs) |
265 EXPECT_EQ(nullptr, it->AsArray()); | 266 EXPECT_EQ(nullptr, it->AsArray()); |
266 } | 267 } |
267 | 268 |
268 TEST_F(PDFObjectsTest, Clone) { | 269 TEST_F(PDFObjectsTest, Clone) { |
269 // Check for direct objects. | 270 // Check for direct objects. |
270 for (size_t i = 0; i < m_DirectObjs.size(); ++i) { | 271 for (size_t i = 0; i < m_DirectObjs.size(); ++i) { |
271 std::unique_ptr<CPDF_Object> obj(m_DirectObjs[i]->Clone()); | 272 std::unique_ptr<CPDF_Object> obj = m_DirectObjs[i]->Clone(); |
272 EXPECT_TRUE(Equal(m_DirectObjs[i].get(), obj.get())); | 273 EXPECT_TRUE(Equal(m_DirectObjs[i].get(), obj.get())); |
273 } | 274 } |
274 | 275 |
275 // Check indirect references. | 276 // Check indirect references. |
276 for (const auto& it : m_RefObjs) { | 277 for (const auto& it : m_RefObjs) { |
277 std::unique_ptr<CPDF_Object> obj(it->Clone()); | 278 std::unique_ptr<CPDF_Object> obj = it->Clone(); |
278 EXPECT_TRUE(Equal(it.get(), obj.get())); | 279 EXPECT_TRUE(Equal(it.get(), obj.get())); |
279 } | 280 } |
280 } | 281 } |
281 | 282 |
282 TEST_F(PDFObjectsTest, GetType) { | 283 TEST_F(PDFObjectsTest, GetType) { |
283 // Check for direct objects. | 284 // Check for direct objects. |
284 for (size_t i = 0; i < m_DirectObjs.size(); ++i) | 285 for (size_t i = 0; i < m_DirectObjs.size(); ++i) |
285 EXPECT_EQ(m_DirectObjTypes[i], m_DirectObjs[i]->GetType()); | 286 EXPECT_EQ(m_DirectObjTypes[i], m_DirectObjs[i]->GetType()); |
286 | 287 |
287 // Check indirect references. | 288 // Check indirect references. |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 | 745 |
745 TEST(PDFArrayTest, CloneDirectObject) { | 746 TEST(PDFArrayTest, CloneDirectObject) { |
746 CPDF_IndirectObjectHolder objects_holder; | 747 CPDF_IndirectObjectHolder objects_holder; |
747 std::unique_ptr<CPDF_Array> array(new CPDF_Array); | 748 std::unique_ptr<CPDF_Array> array(new CPDF_Array); |
748 array->AddReference(&objects_holder, 1234); | 749 array->AddReference(&objects_holder, 1234); |
749 ASSERT_EQ(1U, array->GetCount()); | 750 ASSERT_EQ(1U, array->GetCount()); |
750 CPDF_Object* obj = array->GetObjectAt(0); | 751 CPDF_Object* obj = array->GetObjectAt(0); |
751 ASSERT_TRUE(obj); | 752 ASSERT_TRUE(obj); |
752 EXPECT_TRUE(obj->IsReference()); | 753 EXPECT_TRUE(obj->IsReference()); |
753 | 754 |
754 CPDF_Object* cloned_array_object = array->CloneDirectObject(); | 755 std::unique_ptr<CPDF_Object> cloned_array_object = array->CloneDirectObject(); |
755 ASSERT_TRUE(cloned_array_object); | 756 ASSERT_TRUE(cloned_array_object); |
756 ASSERT_TRUE(cloned_array_object->IsArray()); | 757 ASSERT_TRUE(cloned_array_object->IsArray()); |
757 | 758 |
758 std::unique_ptr<CPDF_Array> cloned_array(cloned_array_object->AsArray()); | 759 std::unique_ptr<CPDF_Array> cloned_array = |
| 760 ToArray(std::move(cloned_array_object)); |
759 ASSERT_EQ(1U, cloned_array->GetCount()); | 761 ASSERT_EQ(1U, cloned_array->GetCount()); |
760 CPDF_Object* cloned_obj = cloned_array->GetObjectAt(0); | 762 CPDF_Object* cloned_obj = cloned_array->GetObjectAt(0); |
761 EXPECT_FALSE(cloned_obj); | 763 EXPECT_FALSE(cloned_obj); |
762 } | 764 } |
763 | 765 |
764 TEST(PDFArrayTest, ConvertIndirect) { | 766 TEST(PDFArrayTest, ConvertIndirect) { |
765 CPDF_IndirectObjectHolder objects_holder; | 767 CPDF_IndirectObjectHolder objects_holder; |
766 std::unique_ptr<CPDF_Array> array(new CPDF_Array); | 768 std::unique_ptr<CPDF_Array> array(new CPDF_Array); |
767 CPDF_Object* pObj = new CPDF_Number(42); | 769 CPDF_Object* pObj = new CPDF_Number(42); |
768 array->Add(pObj); | 770 array->Add(pObj); |
769 array->ConvertToIndirectObjectAt(0, &objects_holder); | 771 array->ConvertToIndirectObjectAt(0, &objects_holder); |
770 CPDF_Object* pRef = array->GetObjectAt(0); | 772 CPDF_Object* pRef = array->GetObjectAt(0); |
771 CPDF_Object* pNum = array->GetDirectObjectAt(0); | 773 CPDF_Object* pNum = array->GetDirectObjectAt(0); |
772 EXPECT_TRUE(pRef->IsReference()); | 774 EXPECT_TRUE(pRef->IsReference()); |
773 EXPECT_TRUE(pNum->IsNumber()); | 775 EXPECT_TRUE(pNum->IsNumber()); |
774 EXPECT_NE(pObj, pRef); | 776 EXPECT_NE(pObj, pRef); |
775 EXPECT_EQ(pObj, pNum); | 777 EXPECT_EQ(pObj, pNum); |
776 EXPECT_EQ(42, array->GetIntegerAt(0)); | 778 EXPECT_EQ(42, array->GetIntegerAt(0)); |
777 } | 779 } |
778 | 780 |
779 TEST(PDFDictionaryTest, CloneDirectObject) { | 781 TEST(PDFDictionaryTest, CloneDirectObject) { |
780 CPDF_IndirectObjectHolder objects_holder; | 782 CPDF_IndirectObjectHolder objects_holder; |
781 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary()); | 783 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary()); |
782 dict->SetReferenceFor("foo", &objects_holder, 1234); | 784 dict->SetReferenceFor("foo", &objects_holder, 1234); |
783 ASSERT_EQ(1U, dict->GetCount()); | 785 ASSERT_EQ(1U, dict->GetCount()); |
784 CPDF_Object* obj = dict->GetObjectFor("foo"); | 786 CPDF_Object* obj = dict->GetObjectFor("foo"); |
785 ASSERT_TRUE(obj); | 787 ASSERT_TRUE(obj); |
786 EXPECT_TRUE(obj->IsReference()); | 788 EXPECT_TRUE(obj->IsReference()); |
787 | 789 |
788 CPDF_Object* cloned_dict_object = dict->CloneDirectObject(); | 790 std::unique_ptr<CPDF_Object> cloned_dict_object = dict->CloneDirectObject(); |
789 ASSERT_TRUE(cloned_dict_object); | 791 ASSERT_TRUE(cloned_dict_object); |
790 ASSERT_TRUE(cloned_dict_object->IsDictionary()); | 792 ASSERT_TRUE(cloned_dict_object->IsDictionary()); |
791 | 793 |
792 std::unique_ptr<CPDF_Dictionary> cloned_dict( | 794 std::unique_ptr<CPDF_Dictionary> cloned_dict = |
793 cloned_dict_object->AsDictionary()); | 795 ToDictionary(std::move(cloned_dict_object)); |
794 ASSERT_EQ(1U, cloned_dict->GetCount()); | 796 ASSERT_EQ(1U, cloned_dict->GetCount()); |
795 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); | 797 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); |
796 EXPECT_FALSE(cloned_obj); | 798 EXPECT_FALSE(cloned_obj); |
797 } | 799 } |
798 | 800 |
799 TEST(PDFObjectTest, CloneCheckLoop) { | 801 TEST(PDFObjectTest, CloneCheckLoop) { |
800 { | 802 { |
801 // Create a dictionary/array pair with a reference loop. | 803 // Create a dictionary/array pair with a reference loop. |
802 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); | 804 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); |
803 std::unique_ptr<CPDF_Array> arr_obj(new CPDF_Array); | 805 std::unique_ptr<CPDF_Array> arr_obj(new CPDF_Array); |
804 dict_obj->SetFor("arr", arr_obj.get()); | 806 dict_obj->SetFor("arr", arr_obj.get()); |
805 arr_obj->InsertAt(0, dict_obj); | 807 arr_obj->InsertAt(0, dict_obj); |
806 | 808 |
807 // Clone this object to see whether stack overflow will be triggered. | 809 // Clone this object to see whether stack overflow will be triggered. |
808 std::unique_ptr<CPDF_Array> cloned_array(arr_obj->Clone()->AsArray()); | 810 std::unique_ptr<CPDF_Array> cloned_array = ToArray(arr_obj->Clone()); |
809 // Cloned object should be the same as the original. | 811 // Cloned object should be the same as the original. |
810 ASSERT_TRUE(cloned_array); | 812 ASSERT_TRUE(cloned_array); |
811 EXPECT_EQ(1u, cloned_array->GetCount()); | 813 EXPECT_EQ(1u, cloned_array->GetCount()); |
812 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); | 814 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); |
813 ASSERT_TRUE(cloned_dict); | 815 ASSERT_TRUE(cloned_dict); |
814 ASSERT_TRUE(cloned_dict->IsDictionary()); | 816 ASSERT_TRUE(cloned_dict->IsDictionary()); |
815 // Recursively referenced object is not cloned. | 817 // Recursively referenced object is not cloned. |
816 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); | 818 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); |
817 } | 819 } |
818 { | 820 { |
819 // Create a dictionary/stream pair with a reference loop. | 821 // Create a dictionary/stream pair with a reference loop. |
820 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); | 822 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); |
821 std::unique_ptr<CPDF_Stream> stream_obj( | 823 std::unique_ptr<CPDF_Stream> stream_obj( |
822 new CPDF_Stream(nullptr, 0, dict_obj)); | 824 new CPDF_Stream(nullptr, 0, dict_obj)); |
823 dict_obj->SetFor("stream", stream_obj.get()); | 825 dict_obj->SetFor("stream", stream_obj.get()); |
824 | 826 |
825 // Clone this object to see whether stack overflow will be triggered. | 827 // Clone this object to see whether stack overflow will be triggered. |
826 std::unique_ptr<CPDF_Stream> cloned_stream(stream_obj->Clone()->AsStream()); | 828 std::unique_ptr<CPDF_Stream> cloned_stream = ToStream(stream_obj->Clone()); |
827 // Cloned object should be the same as the original. | 829 // Cloned object should be the same as the original. |
828 ASSERT_TRUE(cloned_stream); | 830 ASSERT_TRUE(cloned_stream); |
829 CPDF_Object* cloned_dict = cloned_stream->GetDict(); | 831 CPDF_Object* cloned_dict = cloned_stream->GetDict(); |
830 ASSERT_TRUE(cloned_dict); | 832 ASSERT_TRUE(cloned_dict); |
831 ASSERT_TRUE(cloned_dict->IsDictionary()); | 833 ASSERT_TRUE(cloned_dict->IsDictionary()); |
832 // Recursively referenced object is not cloned. | 834 // Recursively referenced object is not cloned. |
833 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream")); | 835 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream")); |
834 } | 836 } |
835 { | 837 { |
836 CPDF_IndirectObjectHolder objects_holder; | 838 CPDF_IndirectObjectHolder objects_holder; |
837 // Create an object with a reference loop. | 839 // Create an object with a reference loop. |
838 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); | 840 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); |
839 CPDF_Array* arr_obj = new CPDF_Array; | 841 CPDF_Array* arr_obj = new CPDF_Array; |
840 objects_holder.AddIndirectObject(dict_obj); | 842 objects_holder.AddIndirectObject(dict_obj); |
841 EXPECT_EQ(1u, dict_obj->GetObjNum()); | 843 EXPECT_EQ(1u, dict_obj->GetObjNum()); |
842 dict_obj->SetFor("arr", arr_obj); | 844 dict_obj->SetFor("arr", arr_obj); |
843 arr_obj->InsertAt( | 845 arr_obj->InsertAt( |
844 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum())); | 846 0, new CPDF_Reference(&objects_holder, dict_obj->GetObjNum())); |
845 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); | 847 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); |
846 ASSERT_TRUE(elem0); | 848 ASSERT_TRUE(elem0); |
847 ASSERT_TRUE(elem0->IsReference()); | 849 ASSERT_TRUE(elem0->IsReference()); |
848 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); | 850 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); |
849 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); | 851 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); |
850 | 852 |
851 // Clone this object to see whether stack overflow will be triggered. | 853 // Clone this object to see whether stack overflow will be triggered. |
852 std::unique_ptr<CPDF_Dictionary> cloned_dict( | 854 std::unique_ptr<CPDF_Dictionary> cloned_dict = |
853 ToDictionary(dict_obj->CloneDirectObject())); | 855 ToDictionary(dict_obj->CloneDirectObject()); |
854 // Cloned object should be the same as the original. | 856 // Cloned object should be the same as the original. |
855 ASSERT_TRUE(cloned_dict); | 857 ASSERT_TRUE(cloned_dict); |
856 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); | 858 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); |
857 ASSERT_TRUE(cloned_arr); | 859 ASSERT_TRUE(cloned_arr); |
858 ASSERT_TRUE(cloned_arr->IsArray()); | 860 ASSERT_TRUE(cloned_arr->IsArray()); |
859 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); | 861 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); |
860 // Recursively referenced object is not cloned. | 862 // Recursively referenced object is not cloned. |
861 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); | 863 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); |
862 } | 864 } |
863 } | 865 } |
864 | 866 |
865 TEST(PDFDictionaryTest, ConvertIndirect) { | 867 TEST(PDFDictionaryTest, ConvertIndirect) { |
866 CPDF_IndirectObjectHolder objects_holder; | 868 CPDF_IndirectObjectHolder objects_holder; |
867 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary); | 869 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary); |
868 CPDF_Object* pObj = new CPDF_Number(42); | 870 CPDF_Object* pObj = new CPDF_Number(42); |
869 dict->SetFor("clams", pObj); | 871 dict->SetFor("clams", pObj); |
870 dict->ConvertToIndirectObjectFor("clams", &objects_holder); | 872 dict->ConvertToIndirectObjectFor("clams", &objects_holder); |
871 CPDF_Object* pRef = dict->GetObjectFor("clams"); | 873 CPDF_Object* pRef = dict->GetObjectFor("clams"); |
872 CPDF_Object* pNum = dict->GetDirectObjectFor("clams"); | 874 CPDF_Object* pNum = dict->GetDirectObjectFor("clams"); |
873 EXPECT_TRUE(pRef->IsReference()); | 875 EXPECT_TRUE(pRef->IsReference()); |
874 EXPECT_TRUE(pNum->IsNumber()); | 876 EXPECT_TRUE(pNum->IsNumber()); |
875 EXPECT_NE(pObj, pRef); | 877 EXPECT_NE(pObj, pRef); |
876 EXPECT_EQ(pObj, pNum); | 878 EXPECT_EQ(pObj, pNum); |
877 EXPECT_EQ(42, dict->GetIntegerFor("clams")); | 879 EXPECT_EQ(42, dict->GetIntegerFor("clams")); |
878 } | 880 } |
OLD | NEW |