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

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

Issue 2510223002: Make CPDF_Dictionary use unique pointers. (Closed)
Patch Set: Plug leaks Created 4 years, 1 month 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
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/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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 public: 46 public:
47 void SetUp() override { 47 void SetUp() override {
48 // Initialize different kinds of objects. 48 // Initialize different kinds of objects.
49 // Boolean objects. 49 // Boolean objects.
50 CPDF_Boolean* boolean_false_obj = new CPDF_Boolean(false); 50 CPDF_Boolean* boolean_false_obj = new CPDF_Boolean(false);
51 CPDF_Boolean* boolean_true_obj = new CPDF_Boolean(true); 51 CPDF_Boolean* boolean_true_obj = new CPDF_Boolean(true);
52 // Number objects. 52 // Number objects.
53 CPDF_Number* number_int_obj = new CPDF_Number(1245); 53 CPDF_Number* number_int_obj = new CPDF_Number(1245);
54 CPDF_Number* number_float_obj = new CPDF_Number(9.00345f); 54 CPDF_Number* number_float_obj = new CPDF_Number(9.00345f);
55 // String objects. 55 // String objects.
56 CPDF_String* str_reg_obj = new CPDF_String(L"A simple test"); 56 CPDF_String* str_reg_obj = new CPDF_String(nullptr, L"A simple test");
57 CPDF_String* str_spec_obj = new CPDF_String(L"\t\n"); 57 CPDF_String* str_spec_obj = new CPDF_String(nullptr, L"\t\n");
58 // Name object. 58 // Name object.
59 CPDF_Name* name_obj = new CPDF_Name(nullptr, "space"); 59 CPDF_Name* name_obj = new CPDF_Name(nullptr, "space");
60 // Array object. 60 // Array object.
61 m_ArrayObj = new CPDF_Array; 61 m_ArrayObj = new CPDF_Array;
62 m_ArrayObj->InsertNewAt<CPDF_Number>(0, 8902); 62 m_ArrayObj->InsertNewAt<CPDF_Number>(0, 8902);
63 m_ArrayObj->InsertNewAt<CPDF_Name>(1, "address"); 63 m_ArrayObj->InsertNewAt<CPDF_Name>(1, "address");
64 // Dictionary object. 64 // Dictionary object.
65 m_DictObj = new CPDF_Dictionary(); 65 m_DictObj = new CPDF_Dictionary();
66 m_DictObj->SetFor("bool", new CPDF_Boolean(false)); 66 m_DictObj->SetNewFor<CPDF_Boolean>("bool", false);
67 m_DictObj->SetFor("num", new CPDF_Number(0.23f)); 67 m_DictObj->SetNewFor<CPDF_Number>("num", 0.23f);
68 // Stream object. 68 // Stream object.
69 const char content[] = "abcdefghijklmnopqrstuvwxyz"; 69 const char content[] = "abcdefghijklmnopqrstuvwxyz";
70 size_t buf_len = FX_ArraySize(content); 70 size_t buf_len = FX_ArraySize(content);
71 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len)); 71 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_len));
72 memcpy(buf, content, buf_len); 72 memcpy(buf, content, buf_len);
73 m_StreamDictObj = new CPDF_Dictionary(); 73 m_StreamDictObj = new CPDF_Dictionary();
74 m_StreamDictObj->SetFor("key1", new CPDF_String(L" test dict")); 74 m_StreamDictObj->SetNewFor<CPDF_String>("key1", L" test dict");
75 m_StreamDictObj->SetFor("key2", new CPDF_Number(-1)); 75 m_StreamDictObj->SetNewFor<CPDF_Number>("key2", -1);
76 CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); 76 CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj);
77 // Null Object. 77 // Null Object.
78 CPDF_Null* null_obj = new CPDF_Null; 78 CPDF_Null* null_obj = new CPDF_Null;
79 // All direct objects. 79 // All direct objects.
80 CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj, 80 CPDF_Object* objs[] = {boolean_false_obj, boolean_true_obj, number_int_obj,
81 number_float_obj, str_reg_obj, str_spec_obj, 81 number_float_obj, str_reg_obj, str_spec_obj,
82 name_obj, m_ArrayObj, m_DictObj, 82 name_obj, m_ArrayObj, m_DictObj,
83 stream_obj, null_obj}; 83 stream_obj, null_obj};
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,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 } 129 }
130 return true; 130 return true;
131 } 131 }
132 case CPDF_Object::DICTIONARY: { 132 case CPDF_Object::DICTIONARY: {
133 const CPDF_Dictionary* dict1 = obj1->AsDictionary(); 133 const CPDF_Dictionary* dict1 = obj1->AsDictionary();
134 const CPDF_Dictionary* dict2 = obj2->AsDictionary(); 134 const CPDF_Dictionary* dict2 = obj2->AsDictionary();
135 if (dict1->GetCount() != dict2->GetCount()) 135 if (dict1->GetCount() != dict2->GetCount())
136 return false; 136 return false;
137 for (CPDF_Dictionary::const_iterator it = dict1->begin(); 137 for (CPDF_Dictionary::const_iterator it = dict1->begin();
138 it != dict1->end(); ++it) { 138 it != dict1->end(); ++it) {
139 if (!Equal(it->second, dict2->GetObjectFor(it->first))) 139 if (!Equal(it->second.get(), dict2->GetObjectFor(it->first)))
140 return false; 140 return false;
141 } 141 }
142 return true; 142 return true;
143 } 143 }
144 case CPDF_Object::NULLOBJ: 144 case CPDF_Object::NULLOBJ:
145 return true; 145 return true;
146 case CPDF_Object::STREAM: { 146 case CPDF_Object::STREAM: {
147 const CPDF_Stream* stream1 = obj1->AsStream(); 147 const CPDF_Stream* stream1 = obj1->AsStream();
148 const CPDF_Stream* stream2 = obj2->AsStream(); 148 const CPDF_Stream* stream2 = obj2->AsStream();
149 if (!stream1->GetDict() && !stream2->GetDict()) 149 if (!stream1->GetDict() && !stream2->GetDict())
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 // Dictionary array. 548 // Dictionary array.
549 CPDF_Dictionary* vals[3]; 549 CPDF_Dictionary* vals[3];
550 auto arr = pdfium::MakeUnique<CPDF_Array>(); 550 auto arr = pdfium::MakeUnique<CPDF_Array>();
551 for (size_t i = 0; i < 3; ++i) { 551 for (size_t i = 0; i < 3; ++i) {
552 vals[i] = arr->AddNew<CPDF_Dictionary>(); 552 vals[i] = arr->AddNew<CPDF_Dictionary>();
553 for (size_t j = 0; j < 3; ++j) { 553 for (size_t j = 0; j < 3; ++j) {
554 std::string key("key"); 554 std::string key("key");
555 char buf[33]; 555 char buf[33];
556 key.append(FXSYS_itoa(j, buf, 10)); 556 key.append(FXSYS_itoa(j, buf, 10));
557 int value = j + 200; 557 int value = j + 200;
558 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); 558 vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value);
559 } 559 }
560 } 560 }
561 for (size_t i = 0; i < 3; ++i) { 561 for (size_t i = 0; i < 3; ++i) {
562 TestArrayAccessors(arr.get(), i, // Array and index. 562 TestArrayAccessors(arr.get(), i, // Array and index.
563 "", // String value. 563 "", // String value.
564 nullptr, // Const string value. 564 nullptr, // Const string value.
565 0, // Integer value. 565 0, // Integer value.
566 0, // Float value. 566 0, // Float value.
567 nullptr, // Array value. 567 nullptr, // Array value.
568 vals[i], // Dictionary value. 568 vals[i], // Dictionary value.
569 nullptr); // Stream value. 569 nullptr); // Stream value.
570 } 570 }
571 } 571 }
572 { 572 {
573 // Stream array. 573 // Stream array.
574 CPDF_Dictionary* vals[3]; 574 CPDF_Dictionary* vals[3];
575 CPDF_Stream* stream_vals[3]; 575 CPDF_Stream* stream_vals[3];
576 auto arr = pdfium::MakeUnique<CPDF_Array>(); 576 auto arr = pdfium::MakeUnique<CPDF_Array>();
577 for (size_t i = 0; i < 3; ++i) { 577 for (size_t i = 0; i < 3; ++i) {
578 vals[i] = new CPDF_Dictionary(); 578 vals[i] = new CPDF_Dictionary();
579 for (size_t j = 0; j < 3; ++j) { 579 for (size_t j = 0; j < 3; ++j) {
580 std::string key("key"); 580 std::string key("key");
581 char buf[33]; 581 char buf[33];
582 key.append(FXSYS_itoa(j, buf, 10)); 582 key.append(FXSYS_itoa(j, buf, 10));
583 int value = j + 200; 583 int value = j + 200;
584 vals[i]->SetFor(key.c_str(), new CPDF_Number(value)); 584 vals[i]->SetNewFor<CPDF_Number>(key.c_str(), value);
585 } 585 }
586 uint8_t content[] = "content: this is a stream"; 586 uint8_t content[] = "content: this is a stream";
587 size_t data_size = FX_ArraySize(content); 587 size_t data_size = FX_ArraySize(content);
588 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size)); 588 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(data_size));
589 memcpy(data, content, data_size); 589 memcpy(data, content, data_size);
590 stream_vals[i] = arr->AddNew<CPDF_Stream>(data, data_size, vals[i]); 590 stream_vals[i] = arr->AddNew<CPDF_Stream>(data, data_size, vals[i]);
591 } 591 }
592 for (size_t i = 0; i < 3; ++i) { 592 for (size_t i = 0; i < 3; ++i) {
593 TestArrayAccessors(arr.get(), i, // Array and index. 593 TestArrayAccessors(arr.get(), i, // Array and index.
594 "", // String value. 594 "", // String value.
(...skipping 18 matching lines...) Expand all
613 arr->InsertNewAt<CPDF_String>(7, "It is a test!", false); 613 arr->InsertNewAt<CPDF_String>(7, "It is a test!", false);
614 arr->InsertNewAt<CPDF_Name>(8, "NAME"); 614 arr->InsertNewAt<CPDF_Name>(8, "NAME");
615 arr->InsertNewAt<CPDF_Name>(9, "test"); 615 arr->InsertNewAt<CPDF_Name>(9, "test");
616 arr->InsertNewAt<CPDF_Null>(10); 616 arr->InsertNewAt<CPDF_Null>(10);
617 617
618 CPDF_Array* arr_val = arr->InsertNewAt<CPDF_Array>(11); 618 CPDF_Array* arr_val = arr->InsertNewAt<CPDF_Array>(11);
619 arr_val->AddNew<CPDF_Number>(1); 619 arr_val->AddNew<CPDF_Number>(1);
620 arr_val->AddNew<CPDF_Number>(2); 620 arr_val->AddNew<CPDF_Number>(2);
621 621
622 CPDF_Dictionary* dict_val = arr->InsertNewAt<CPDF_Dictionary>(12); 622 CPDF_Dictionary* dict_val = arr->InsertNewAt<CPDF_Dictionary>(12);
623 dict_val->SetFor("key1", new CPDF_String(nullptr, "Linda", false)); 623 dict_val->SetNewFor<CPDF_String>("key1", "Linda", false);
624 dict_val->SetFor("key2", new CPDF_String(nullptr, "Zoe", false)); 624 dict_val->SetNewFor<CPDF_String>("key2", "Zoe", false);
625 625
626 CPDF_Dictionary* stream_dict = new CPDF_Dictionary(); 626 CPDF_Dictionary* stream_dict = new CPDF_Dictionary();
627 stream_dict->SetFor("key1", new CPDF_String(nullptr, "John", false)); 627 stream_dict->SetNewFor<CPDF_String>("key1", "John", false);
628 stream_dict->SetFor("key2", new CPDF_String(nullptr, "King", false)); 628 stream_dict->SetNewFor<CPDF_String>("key2", "King", false);
629 uint8_t data[] = "A stream for test"; 629 uint8_t data[] = "A stream for test";
630 // The data buffer will be owned by stream object, so it needs to be 630 // The data buffer will be owned by stream object, so it needs to be
631 // dynamically allocated. 631 // dynamically allocated.
632 size_t buf_size = sizeof(data); 632 size_t buf_size = sizeof(data);
633 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size)); 633 uint8_t* buf = reinterpret_cast<uint8_t*>(malloc(buf_size));
634 memcpy(buf, data, buf_size); 634 memcpy(buf, data, buf_size);
635 CPDF_Stream* stream_val = 635 CPDF_Stream* stream_val =
636 arr->InsertNewAt<CPDF_Stream>(13, buf, buf_size, stream_dict); 636 arr->InsertNewAt<CPDF_Stream>(13, buf, buf_size, stream_dict);
637 const char* const expected_str[] = { 637 const char* const expected_str[] = {
638 "true", "false", "0", "-1234", "2345", "0.05", "", 638 "true", "false", "0", "-1234", "2345", "0.05", "",
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 EXPECT_TRUE(pRef->IsReference()); 771 EXPECT_TRUE(pRef->IsReference());
772 EXPECT_TRUE(pNum->IsNumber()); 772 EXPECT_TRUE(pNum->IsNumber());
773 EXPECT_NE(pObj, pRef); 773 EXPECT_NE(pObj, pRef);
774 EXPECT_EQ(pObj, pNum); 774 EXPECT_EQ(pObj, pNum);
775 EXPECT_EQ(42, array->GetIntegerAt(0)); 775 EXPECT_EQ(42, array->GetIntegerAt(0));
776 } 776 }
777 777
778 TEST(PDFDictionaryTest, CloneDirectObject) { 778 TEST(PDFDictionaryTest, CloneDirectObject) {
779 CPDF_IndirectObjectHolder objects_holder; 779 CPDF_IndirectObjectHolder objects_holder;
780 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary()); 780 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary());
781 dict->SetReferenceFor("foo", &objects_holder, 1234); 781 dict->SetNewFor<CPDF_Reference>("foo", &objects_holder, 1234);
782 ASSERT_EQ(1U, dict->GetCount()); 782 ASSERT_EQ(1U, dict->GetCount());
783 CPDF_Object* obj = dict->GetObjectFor("foo"); 783 CPDF_Object* obj = dict->GetObjectFor("foo");
784 ASSERT_TRUE(obj); 784 ASSERT_TRUE(obj);
785 EXPECT_TRUE(obj->IsReference()); 785 EXPECT_TRUE(obj->IsReference());
786 786
787 std::unique_ptr<CPDF_Object> cloned_dict_object = dict->CloneDirectObject(); 787 std::unique_ptr<CPDF_Object> cloned_dict_object = dict->CloneDirectObject();
788 ASSERT_TRUE(cloned_dict_object); 788 ASSERT_TRUE(cloned_dict_object);
789 ASSERT_TRUE(cloned_dict_object->IsDictionary()); 789 ASSERT_TRUE(cloned_dict_object->IsDictionary());
790 790
791 std::unique_ptr<CPDF_Dictionary> cloned_dict = 791 std::unique_ptr<CPDF_Dictionary> cloned_dict =
792 ToDictionary(std::move(cloned_dict_object)); 792 ToDictionary(std::move(cloned_dict_object));
793 ASSERT_EQ(1U, cloned_dict->GetCount()); 793 ASSERT_EQ(1U, cloned_dict->GetCount());
794 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo"); 794 CPDF_Object* cloned_obj = cloned_dict->GetObjectFor("foo");
795 EXPECT_FALSE(cloned_obj); 795 EXPECT_FALSE(cloned_obj);
796 } 796 }
797 797
798 TEST(PDFObjectTest, CloneCheckLoop) { 798 TEST(PDFObjectTest, CloneCheckLoop) {
799 { 799 {
800 // Create a dictionary/array pair with a reference loop. 800 // Create a dictionary/array pair with a reference loop. It takes
801 // some work to do this nowadays, in particular we need the
802 // anti-pattern pdfium::WrapUnique(arr.get()).
801 auto arr_obj = pdfium::MakeUnique<CPDF_Array>(); 803 auto arr_obj = pdfium::MakeUnique<CPDF_Array>();
802 CPDF_Dictionary* dict_obj = arr_obj->InsertNewAt<CPDF_Dictionary>(0); 804 CPDF_Dictionary* dict_obj = arr_obj->InsertNewAt<CPDF_Dictionary>(0);
803 dict_obj->SetFor("arr", arr_obj.get()); 805 dict_obj->SetFor("arr", pdfium::WrapUnique(arr_obj.get()));
804 // Clone this object to see whether stack overflow will be triggered. 806 // Clone this object to see whether stack overflow will be triggered.
805 std::unique_ptr<CPDF_Array> cloned_array = ToArray(arr_obj->Clone()); 807 std::unique_ptr<CPDF_Array> cloned_array = ToArray(arr_obj->Clone());
806 // Cloned object should be the same as the original. 808 // Cloned object should be the same as the original.
807 ASSERT_TRUE(cloned_array); 809 ASSERT_TRUE(cloned_array);
808 EXPECT_EQ(1u, cloned_array->GetCount()); 810 EXPECT_EQ(1u, cloned_array->GetCount());
809 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0); 811 CPDF_Object* cloned_dict = cloned_array->GetObjectAt(0);
810 ASSERT_TRUE(cloned_dict); 812 ASSERT_TRUE(cloned_dict);
811 ASSERT_TRUE(cloned_dict->IsDictionary()); 813 ASSERT_TRUE(cloned_dict->IsDictionary());
812 // Recursively referenced object is not cloned. 814 // Recursively referenced object is not cloned.
813 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr")); 815 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("arr"));
814 } 816 }
815 { 817 {
816 // Create a dictionary/stream pair with a reference loop. 818 // Create a dictionary/stream pair with a reference loop.
817 CPDF_Dictionary* dict_obj = new CPDF_Dictionary(); 819 auto dict_obj = pdfium::MakeUnique<CPDF_Dictionary>();
818 std::unique_ptr<CPDF_Stream> stream_obj( 820 CPDF_Stream* stream_obj =
819 new CPDF_Stream(nullptr, 0, dict_obj)); 821 dict_obj->SetNewFor<CPDF_Stream>("stream", nullptr, 0, dict_obj.get());
820 dict_obj->SetFor("stream", stream_obj.get());
821
822 // Clone this object to see whether stack overflow will be triggered. 822 // Clone this object to see whether stack overflow will be triggered.
823 std::unique_ptr<CPDF_Stream> cloned_stream = ToStream(stream_obj->Clone()); 823 std::unique_ptr<CPDF_Stream> cloned_stream = ToStream(stream_obj->Clone());
824 // Cloned object should be the same as the original. 824 // Cloned object should be the same as the original.
825 ASSERT_TRUE(cloned_stream); 825 ASSERT_TRUE(cloned_stream);
826 CPDF_Object* cloned_dict = cloned_stream->GetDict(); 826 CPDF_Object* cloned_dict = cloned_stream->GetDict();
827 ASSERT_TRUE(cloned_dict); 827 ASSERT_TRUE(cloned_dict);
828 ASSERT_TRUE(cloned_dict->IsDictionary()); 828 ASSERT_TRUE(cloned_dict->IsDictionary());
829 // Recursively referenced object is not cloned. 829 // Recursively referenced object is not cloned.
830 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream")); 830 EXPECT_EQ(nullptr, cloned_dict->AsDictionary()->GetObjectFor("stream"));
831 } 831 }
832 { 832 {
833 CPDF_IndirectObjectHolder objects_holder; 833 CPDF_IndirectObjectHolder objects_holder;
834 // Create an object with a reference loop. 834 // Create an object with a reference loop.
835 CPDF_Dictionary* dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>(); 835 CPDF_Dictionary* dict_obj = objects_holder.NewIndirect<CPDF_Dictionary>();
836 std::unique_ptr<CPDF_Array> arr_obj = pdfium::MakeUnique<CPDF_Array>(); 836 std::unique_ptr<CPDF_Array> arr_obj = pdfium::MakeUnique<CPDF_Array>();
837 arr_obj->InsertNewAt<CPDF_Reference>(0, &objects_holder, 837 arr_obj->InsertNewAt<CPDF_Reference>(0, &objects_holder,
838 dict_obj->GetObjNum()); 838 dict_obj->GetObjNum());
839 CPDF_Object* elem0 = arr_obj->GetObjectAt(0); 839 CPDF_Object* elem0 = arr_obj->GetObjectAt(0);
840 dict_obj->SetFor("arr", arr_obj.release()); 840 dict_obj->SetFor("arr", std::move(arr_obj));
841 EXPECT_EQ(1u, dict_obj->GetObjNum()); 841 EXPECT_EQ(1u, dict_obj->GetObjNum());
842 ASSERT_TRUE(elem0); 842 ASSERT_TRUE(elem0);
843 ASSERT_TRUE(elem0->IsReference()); 843 ASSERT_TRUE(elem0->IsReference());
844 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum()); 844 EXPECT_EQ(1u, elem0->AsReference()->GetRefObjNum());
845 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect()); 845 EXPECT_EQ(dict_obj, elem0->AsReference()->GetDirect());
846 846
847 // Clone this object to see whether stack overflow will be triggered. 847 // Clone this object to see whether stack overflow will be triggered.
848 std::unique_ptr<CPDF_Dictionary> cloned_dict = 848 std::unique_ptr<CPDF_Dictionary> cloned_dict =
849 ToDictionary(dict_obj->CloneDirectObject()); 849 ToDictionary(dict_obj->CloneDirectObject());
850 // Cloned object should be the same as the original. 850 // Cloned object should be the same as the original.
851 ASSERT_TRUE(cloned_dict); 851 ASSERT_TRUE(cloned_dict);
852 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr"); 852 CPDF_Object* cloned_arr = cloned_dict->GetObjectFor("arr");
853 ASSERT_TRUE(cloned_arr); 853 ASSERT_TRUE(cloned_arr);
854 ASSERT_TRUE(cloned_arr->IsArray()); 854 ASSERT_TRUE(cloned_arr->IsArray());
855 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount()); 855 EXPECT_EQ(1u, cloned_arr->AsArray()->GetCount());
856 // Recursively referenced object is not cloned. 856 // Recursively referenced object is not cloned.
857 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0)); 857 EXPECT_EQ(nullptr, cloned_arr->AsArray()->GetObjectAt(0));
858 } 858 }
859 } 859 }
860 860
861 TEST(PDFDictionaryTest, ConvertIndirect) { 861 TEST(PDFDictionaryTest, ConvertIndirect) {
862 CPDF_IndirectObjectHolder objects_holder; 862 CPDF_IndirectObjectHolder objects_holder;
863 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary); 863 std::unique_ptr<CPDF_Dictionary> dict(new CPDF_Dictionary);
864 CPDF_Object* pObj = new CPDF_Number(42); 864 CPDF_Object* pObj = dict->SetNewFor<CPDF_Number>("clams", 42);
865 dict->SetFor("clams", pObj);
866 dict->ConvertToIndirectObjectFor("clams", &objects_holder); 865 dict->ConvertToIndirectObjectFor("clams", &objects_holder);
867 CPDF_Object* pRef = dict->GetObjectFor("clams"); 866 CPDF_Object* pRef = dict->GetObjectFor("clams");
868 CPDF_Object* pNum = dict->GetDirectObjectFor("clams"); 867 CPDF_Object* pNum = dict->GetDirectObjectFor("clams");
869 EXPECT_TRUE(pRef->IsReference()); 868 EXPECT_TRUE(pRef->IsReference());
870 EXPECT_TRUE(pNum->IsNumber()); 869 EXPECT_TRUE(pNum->IsNumber());
871 EXPECT_NE(pObj, pRef); 870 EXPECT_NE(pObj, pRef);
872 EXPECT_EQ(pObj, pNum); 871 EXPECT_EQ(pObj, pNum);
873 EXPECT_EQ(42, dict->GetIntegerFor("clams")); 872 EXPECT_EQ(42, dict->GetIntegerFor("clams"));
874 } 873 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698