Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_object_walker_unittest.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "core/fpdfapi/parser/cpdf_object_walker.h"
6
7#include <sstream>
8#include <string>
9#include <utility>
10
11#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_boolean.h"
13#include "core/fpdfapi/parser/cpdf_dictionary.h"
14#include "core/fpdfapi/parser/cpdf_name.h"
15#include "core/fpdfapi/parser/cpdf_null.h"
16#include "core/fpdfapi/parser/cpdf_number.h"
17#include "core/fpdfapi/parser/cpdf_reference.h"
18#include "core/fpdfapi/parser/cpdf_stream.h"
19#include "core/fpdfapi/parser/cpdf_string.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22namespace {
23
24std::string Walk(RetainPtr<CPDF_Object> object) {
25 std::ostringstream result;
26 CPDF_ObjectWalker walker(std::move(object));
27 while (RetainPtr<const CPDF_Object> obj = walker.GetNext()) {
28 if (obj->IsDictionary())
29 result << " Dict";
30 else if (obj->IsArray())
31 result << " Arr";
32 else if (obj->IsString())
33 result << " Str";
34 else if (obj->IsBoolean())
35 result << " Bool";
36 else if (obj->IsStream())
37 result << " Stream";
38 else if (obj->IsReference())
39 result << " Ref";
40 else if (obj->IsNumber())
41 result << " Num";
42 else if (obj->IsNull())
43 result << " Null";
44 else
45 result << " Unknown";
46 }
47 std::string result_str = result.str();
48 if (!result_str.empty()) {
49 result_str.erase(result_str.begin()); // remove start space
50 }
51 return result_str;
52}
53
54} // namespace
55
57 EXPECT_EQ(Walk(pdfium::MakeRetain<CPDF_Null>()), "Null");
58 EXPECT_EQ(Walk(pdfium::MakeRetain<CPDF_Dictionary>()), "Dict");
59 EXPECT_EQ(Walk(pdfium::MakeRetain<CPDF_Array>()), "Arr");
60 EXPECT_EQ(Walk(pdfium::MakeRetain<CPDF_String>()), "Str");
61 EXPECT_EQ(Walk(pdfium::MakeRetain<CPDF_Boolean>()), "Bool");
62 EXPECT_EQ(Walk(pdfium::MakeRetain<CPDF_Stream>(
63 pdfium::MakeRetain<CPDF_Dictionary>())),
64 "Stream Dict Num");
65 EXPECT_EQ(Walk(pdfium::MakeRetain<CPDF_Reference>(nullptr, 0)), "Ref");
66}
67
70 auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
71 dict->SetFor("1", pdfium::MakeRetain<CPDF_String>());
72 dict->SetFor("2", pdfium::MakeRetain<CPDF_Boolean>());
73 auto array = pdfium::MakeRetain<CPDF_Array>();
74 array->Append(pdfium::MakeRetain<CPDF_Reference>(nullptr, 0));
75 array->Append(pdfium::MakeRetain<CPDF_Null>());
76 auto stream =
77 holder.NewIndirect<CPDF_Stream>(pdfium::MakeRetain<CPDF_Dictionary>());
78 ASSERT_TRUE(stream);
79 const uint32_t stream_object_number = stream->GetObjNum();
80 ASSERT_GT(stream_object_number, 0u);
81 array->Append(
82 pdfium::MakeRetain<CPDF_Reference>(&holder, stream_object_number));
83 dict->SetFor("3", std::move(array));
84 EXPECT_EQ(Walk(dict), "Dict Str Bool Arr Ref Null Ref");
85}
86
89 auto level_4 = pdfium::MakeRetain<CPDF_Number>(0);
90 auto level_3 = pdfium::MakeRetain<CPDF_Dictionary>();
91 level_3->SetFor("Length", std::move(level_4));
92 auto level_2 = holder.NewIndirect<CPDF_Stream>(std::move(level_3));
93 ASSERT_TRUE(level_2);
94 const uint32_t level_2_object_number = level_2->GetObjNum();
95 ASSERT_GT(level_2_object_number, 0u);
96 auto level_1 = pdfium::MakeRetain<CPDF_Array>();
97 level_1->Append(
98 pdfium::MakeRetain<CPDF_Reference>(&holder, level_2_object_number));
99 auto level_0 = pdfium::MakeRetain<CPDF_Dictionary>();
100 level_0->SetFor("Array", std::move(level_1));
101
102 // We have <</Array [ stream( << /Length 0 >>) ]>>
103 // In this case each step will increase depth.
104 // And on each step the prev object should be parent for current.
105 RetainPtr<const CPDF_Object> cur_parent;
106 CPDF_ObjectWalker walker(level_0);
107 while (RetainPtr<const CPDF_Object> obj = walker.GetNext()) {
108 EXPECT_EQ(cur_parent, walker.GetParent());
109 cur_parent = std::move(obj);
110 }
111}
112
114 auto root_array = pdfium::MakeRetain<CPDF_Array>();
115 // Add 2 null objects into |root_array|. [ null1, null2 ]
116 root_array->AppendNew<CPDF_Null>();
117 root_array->AppendNew<CPDF_Null>();
118 // |root_array| will contain 4 null objects after this.
119 // [ null1, null2, [ null3, null4 ] ]
120 root_array->Append(root_array->Clone());
121
122 int non_array_objects = 0;
123 CPDF_ObjectWalker walker(root_array);
124 while (RetainPtr<const CPDF_Object> obj = walker.GetNext()) {
125 if (obj != root_array && obj->IsArray()) {
126 // skip other array except root.
128 }
129 if (!obj->IsArray())
130 ++non_array_objects;
131 }
132 // 2 objects from child array should be skipped.
133 EXPECT_EQ(2, non_array_objects);
134}
135
137 auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
138 dict->SetFor("1", pdfium::MakeRetain<CPDF_Null>());
139 dict->SetFor("2", pdfium::MakeRetain<CPDF_Null>());
140 dict->SetFor("3", pdfium::MakeRetain<CPDF_Null>());
141 dict->SetFor("4", pdfium::MakeRetain<CPDF_Null>());
142 dict->SetFor("5", pdfium::MakeRetain<CPDF_Null>());
143
144 CPDF_ObjectWalker walker(dict);
145 while (RetainPtr<const CPDF_Object> obj = walker.GetNext()) {
146 if (dict == obj) {
147 // Ignore root dictinary object
148 continue;
149 }
150 // Test that, dictionary key is correct.
152 walker.dictionary_key()),
153 obj);
154 }
155}
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
RetainPtr< const CPDF_Object > GetObjectFor(const ByteString &key) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
const CPDF_Object * GetParent() const
const ByteString & dictionary_key() const
const CPDF_Dictionary * AsDictionary() const
TEST(FXCRYPT, MD5GenerateEmtpyData)