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_formfield_unittest.cpp
Go to the documentation of this file.
1// Copyright 2016 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/fpdfdoc/cpdf_formfield.h"
6
7#include <vector>
8
9#include "constants/form_fields.h"
10#include "constants/form_flags.h"
11#include "core/fpdfapi/page/cpdf_pagemodule.h"
12#include "core/fpdfapi/parser/cpdf_array.h"
13#include "core/fpdfapi/parser/cpdf_dictionary.h"
14#include "core/fpdfapi/parser/cpdf_document.h"
15#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
16#include "core/fpdfapi/parser/cpdf_name.h"
17#include "core/fpdfapi/parser/cpdf_number.h"
18#include "core/fpdfapi/parser/cpdf_reference.h"
19#include "core/fpdfapi/parser/cpdf_string.h"
20#include "core/fpdfapi/parser/cpdf_test_document.h"
21#include "core/fpdfdoc/cpdf_interactiveform.h"
22#include "core/fxcrt/fx_memory.h"
23#include "testing/gtest/include/gtest/gtest.h"
24#include "third_party/base/containers/contains.h"
25
26namespace {
27
28// Create and destroys the page module that is necessary when instantiating a
29// CPDF_Document.
30class ScopedCPDF_PageModule {
31 public:
32 FX_STACK_ALLOCATED();
33
34 ScopedCPDF_PageModule() { CPDF_PageModule::Create(); }
35 ~ScopedCPDF_PageModule() { CPDF_PageModule::Destroy(); }
36};
37
38void TestMultiselectFieldDict(RetainPtr<CPDF_Array> opt_array,
39 RetainPtr<CPDF_Object> values,
40 RetainPtr<CPDF_Object> selected_indices,
41 bool expected_use_indices,
42 const std::vector<int>& expected_indices,
43 const std::vector<int>& excluded_indices) {
44 auto form_dict = pdfium::MakeRetain<CPDF_Dictionary>();
45 form_dict->SetNewFor<CPDF_Name>("Type", "Annot");
46 form_dict->SetNewFor<CPDF_Name>("Subtype", "Widget");
47 form_dict->SetNewFor<CPDF_Name>(pdfium::form_fields::kFT,
48 pdfium::form_fields::kCh);
49 constexpr int kMuliSelectFlag = pdfium::form_flags::kChoiceMultiSelect;
50 form_dict->SetNewFor<CPDF_Number>(pdfium::form_fields::kFf, kMuliSelectFlag);
51 form_dict->SetFor("Opt", opt_array);
52 form_dict->SetFor(pdfium::form_fields::kV, values);
53 form_dict->SetFor("I", selected_indices);
54
56 CPDF_InteractiveForm form(&doc);
57 CPDF_FormField form_field(&form, std::move(form_dict));
58 EXPECT_EQ(expected_use_indices, form_field.UseSelectedIndicesObject());
59 for (int i = 0; i < form_field.CountOptions(); i++) {
60 const bool expected_selected = pdfium::Contains(expected_indices, i);
61 EXPECT_EQ(expected_selected, form_field.IsItemSelected(i));
62 }
63 for (int i : excluded_indices) {
64 EXPECT_FALSE(form_field.IsItemSelected(i));
65 }
66}
67
68} // namespace
69
71 WideString name = CPDF_FormField::GetFullNameForDict(nullptr);
72 EXPECT_TRUE(name.IsEmpty());
73
75 auto root = obj_holder.NewIndirect<CPDF_Dictionary>();
76 root->SetNewFor<CPDF_Name>("T", "foo");
78 EXPECT_STREQ("foo", name.ToUTF8().c_str());
79
80 auto dict1 = obj_holder.NewIndirect<CPDF_Dictionary>();
81 root->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict1->GetObjNum());
82 dict1->SetNewFor<CPDF_Name>("T", "bar");
84 EXPECT_STREQ("bar.foo", name.ToUTF8().c_str());
85
86 auto dict2 = dict1->SetNewFor<CPDF_Dictionary>("Parent");
88 EXPECT_STREQ("bar.foo", name.ToUTF8().c_str());
89
90 auto dict3 = obj_holder.NewIndirect<CPDF_Dictionary>();
91 dict2->SetNewFor<CPDF_Reference>("Parent", &obj_holder, dict3->GetObjNum());
92
93 dict3->SetNewFor<CPDF_Name>("T", "qux");
95 EXPECT_STREQ("qux.bar.foo", name.ToUTF8().c_str());
96
97 dict3->SetNewFor<CPDF_Reference>("Parent", &obj_holder, root->GetObjNum());
99 EXPECT_STREQ("qux.bar.foo", name.ToUTF8().c_str());
100 name = CPDF_FormField::GetFullNameForDict(dict1.Get());
101 EXPECT_STREQ("foo.qux.bar", name.ToUTF8().c_str());
102 name = CPDF_FormField::GetFullNameForDict(dict2.Get());
103 EXPECT_STREQ("bar.foo.qux", name.ToUTF8().c_str());
104 name = CPDF_FormField::GetFullNameForDict(dict3.Get());
105 EXPECT_STREQ("bar.foo.qux", name.ToUTF8().c_str());
106}
107
109 ScopedCPDF_PageModule page_module;
110
111 auto opt_array = pdfium::MakeRetain<CPDF_Array>();
112 opt_array->AppendNew<CPDF_String>(L"Alpha");
113 opt_array->AppendNew<CPDF_String>(L"Beta");
114 opt_array->AppendNew<CPDF_String>(L"Gamma");
115 opt_array->AppendNew<CPDF_String>(L"Delta");
116 opt_array->AppendNew<CPDF_String>(L"Epsilon");
117
118 {
119 // No Values (/V) or Selected Indices (/I) objects.
120 std::vector<int> expected_indices;
121 std::vector<int> excluded_indices{-1, 5};
122 TestMultiselectFieldDict(opt_array, /*values=*/nullptr,
123 /*selected_indices=*/nullptr,
124 /*expected_use_indices=*/false, expected_indices,
125 excluded_indices);
126 }
127 {
128 // Values (/V) object is just a string.
129 auto values = pdfium::MakeRetain<CPDF_String>(/*pPool=*/nullptr, L"Gamma");
130 std::vector<int> expected_indices{2};
131 std::vector<int> excluded_indices{-1, 5};
132 TestMultiselectFieldDict(opt_array, values, /*selected_indices=*/nullptr,
133 /*expected_use_indices=*/false, expected_indices,
134 excluded_indices);
135 }
136 {
137 // Values (/V) object is just an invalid string.
138 auto values = pdfium::MakeRetain<CPDF_String>(/*pPool=*/nullptr, L"Omega");
139 std::vector<int> expected_indices;
140 std::vector<int> excluded_indices{-1, 5};
141 TestMultiselectFieldDict(opt_array, values, /*selected_indices=*/nullptr,
142 /*expected_use_indices=*/false, expected_indices,
143 excluded_indices);
144 }
145 {
146 // Values (/V) object is an array with one object.
147 auto values = pdfium::MakeRetain<CPDF_Array>();
148 values->AppendNew<CPDF_String>(L"Beta");
149 std::vector<int> expected_indices{1};
150 std::vector<int> excluded_indices{-1, 5};
151 TestMultiselectFieldDict(opt_array, values, /*selected_indices=*/nullptr,
152 /*expected_use_indices=*/false, expected_indices,
153 excluded_indices);
154 }
155 {
156 // Values (/V) object is an array with one invalid object.
157 auto values = pdfium::MakeRetain<CPDF_Array>();
158 values->AppendNew<CPDF_String>(L"Omega");
159 std::vector<int> expected_indices;
160 std::vector<int> excluded_indices{-1, 5};
161 TestMultiselectFieldDict(opt_array, values, /*selected_indices=*/nullptr,
162 /*expected_use_indices=*/false, expected_indices,
163 excluded_indices);
164 }
165 {
166 // Values (/V) object is an array with multiple objects.
167 auto values = pdfium::MakeRetain<CPDF_Array>();
168 values->AppendNew<CPDF_String>(L"Beta");
169 values->AppendNew<CPDF_String>(L"Epsilon");
170 std::vector<int> expected_indices{1, 4};
171 std::vector<int> excluded_indices{-1, 5};
172 TestMultiselectFieldDict(opt_array, values, /*selected_indices=*/nullptr,
173 /*expected_use_indices=*/false, expected_indices,
174 excluded_indices);
175 }
176 {
177 // Values (/V) object is an array with multiple objects with one invalid.
178 auto values = pdfium::MakeRetain<CPDF_Array>();
179 values->AppendNew<CPDF_String>(L"Beta");
180 values->AppendNew<CPDF_String>(L"Epsilon");
181 values->AppendNew<CPDF_String>(L"Omega");
182 std::vector<int> expected_indices{1, 4};
183 std::vector<int> excluded_indices{-1, 5};
184 TestMultiselectFieldDict(opt_array, values, /*selected_indices=*/nullptr,
185 /*expected_use_indices=*/false, expected_indices,
186 excluded_indices);
187 }
188 {
189 // Selected indices (/I) object is just a number.
190 auto selected_indices = pdfium::MakeRetain<CPDF_Number>(3);
191 std::vector<int> expected_indices{3};
192 std::vector<int> excluded_indices{-1, 5};
193 TestMultiselectFieldDict(opt_array, /*values=*/nullptr, selected_indices,
194 /*expected_use_indices=*/true, expected_indices,
195 excluded_indices);
196 }
197 {
198 // Selected indices (/I) object is just an invalid number.
199 auto selected_indices = pdfium::MakeRetain<CPDF_Number>(26);
200 std::vector<int> expected_indices;
201 std::vector<int> excluded_indices{-1, 5, 26};
202 TestMultiselectFieldDict(opt_array, /*values=*/nullptr, selected_indices,
203 /*expected_use_indices=*/true, expected_indices,
204 excluded_indices);
205 }
206 {
207 // Selected indices (/I) object is an array with one object.
208 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
209 selected_indices->AppendNew<CPDF_Number>(0);
210 std::vector<int> expected_indices{0};
211 std::vector<int> excluded_indices{-1, 5};
212 TestMultiselectFieldDict(opt_array, /*values=*/nullptr, selected_indices,
213 /*expected_use_indices=*/true, expected_indices,
214 excluded_indices);
215 }
216 {
217 // Selected indices (/I) object is an array with multiple objects.
218 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
219 selected_indices->AppendNew<CPDF_Number>(0);
220 selected_indices->AppendNew<CPDF_Number>(2);
221 selected_indices->AppendNew<CPDF_Number>(3);
222 std::vector<int> expected_indices{0, 2, 3};
223 std::vector<int> excluded_indices{-1, 5};
224 TestMultiselectFieldDict(opt_array, /*values=*/nullptr, selected_indices,
225 /*expected_use_indices=*/true, expected_indices,
226 excluded_indices);
227 }
228 {
229 // Selected indices (/I) object is an array with multiple objects and some
230 // are invalid.
231 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
232 selected_indices->AppendNew<CPDF_Number>(0);
233 selected_indices->AppendNew<CPDF_Number>(2);
234 selected_indices->AppendNew<CPDF_Number>(3);
235 selected_indices->AppendNew<CPDF_Number>(-5);
236 selected_indices->AppendNew<CPDF_Number>(12);
237 selected_indices->AppendNew<CPDF_Number>(42);
238 std::vector<int> expected_indices{0, 2, 3};
239 std::vector<int> excluded_indices{-5, -1, 5, 12, 42};
240 TestMultiselectFieldDict(opt_array, /*values=*/nullptr, selected_indices,
241 /*expected_use_indices=*/true, expected_indices,
242 excluded_indices);
243 }
244 {
245 // Values (/V) or Selected Indices (/I) objects conflict with different
246 // lengths.
247 auto values = pdfium::MakeRetain<CPDF_Array>();
248 values->AppendNew<CPDF_String>(L"Beta");
249 values->AppendNew<CPDF_String>(L"Epsilon");
250 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
251 selected_indices->AppendNew<CPDF_Number>(0);
252 selected_indices->AppendNew<CPDF_Number>(2);
253 selected_indices->AppendNew<CPDF_Number>(3);
254 std::vector<int> expected_indices{1, 4};
255 std::vector<int> excluded_indices{-1, 5};
256 TestMultiselectFieldDict(opt_array, values, selected_indices,
257 /*expected_use_indices=*/false, expected_indices,
258 excluded_indices);
259 }
260 {
261 // Values (/V) or Selected Indices (/I) objects conflict with same lengths.
262 auto values = pdfium::MakeRetain<CPDF_Array>();
263 values->AppendNew<CPDF_String>(L"Alpha");
264 values->AppendNew<CPDF_String>(L"Epsilon");
265 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
266 selected_indices->AppendNew<CPDF_Number>(2);
267 selected_indices->AppendNew<CPDF_Number>(3);
268 std::vector<int> expected_indices{0, 4};
269 std::vector<int> excluded_indices{-1, 5};
270 TestMultiselectFieldDict(opt_array, values, selected_indices,
271 /*expected_use_indices=*/false, expected_indices,
272 excluded_indices);
273 }
274 {
275 // Values (/V) or Selected Indices (/I) objects conflict with values being
276 // invalid.
277 auto values = pdfium::MakeRetain<CPDF_Array>();
278 values->AppendNew<CPDF_String>(L"Beta");
279 values->AppendNew<CPDF_String>(L"Epsilon");
280 values->AppendNew<CPDF_String>(L"Omega");
281 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
282 selected_indices->AppendNew<CPDF_Number>(1);
283 selected_indices->AppendNew<CPDF_Number>(4);
284 std::vector<int> expected_indices{1, 4};
285 std::vector<int> excluded_indices{-1, 5};
286 TestMultiselectFieldDict(opt_array, values, selected_indices,
287 /*expected_use_indices=*/false, expected_indices,
288 excluded_indices);
289 }
290 {
291 // Values (/V) or Selected Indices (/I) objects conflict with selected
292 // indices being invalid.
293 auto values = pdfium::MakeRetain<CPDF_Array>();
294 values->AppendNew<CPDF_String>(L"Beta");
295 values->AppendNew<CPDF_String>(L"Epsilon");
296 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
297 selected_indices->AppendNew<CPDF_Number>(1);
298 selected_indices->AppendNew<CPDF_Number>(4);
299 selected_indices->AppendNew<CPDF_Number>(26);
300 std::vector<int> expected_indices{1, 4};
301 std::vector<int> excluded_indices{-1, 5, 26};
302 TestMultiselectFieldDict(opt_array, values, selected_indices,
303 /*expected_use_indices=*/false, expected_indices,
304 excluded_indices);
305 }
306 {
307 // Values (/V) or Selected Indices (/I) objects conflict with both being
308 // invalid.
309 auto values = pdfium::MakeRetain<CPDF_Array>();
310 values->AppendNew<CPDF_String>(L"Beta");
311 values->AppendNew<CPDF_String>(L"Epsilon");
312 values->AppendNew<CPDF_String>(L"Omega");
313 auto selected_indices = pdfium::MakeRetain<CPDF_Array>();
314 selected_indices->AppendNew<CPDF_Number>(0);
315 selected_indices->AppendNew<CPDF_Number>(2);
316 selected_indices->AppendNew<CPDF_Number>(3);
317 selected_indices->AppendNew<CPDF_Number>(26);
318 std::vector<int> expected_indices{1, 4};
319 std::vector<int> excluded_indices{-1, 5, 26};
320 TestMultiselectFieldDict(opt_array, values, selected_indices,
321 /*expected_use_indices=*/false, expected_indices,
322 excluded_indices);
323 }
324 {
325 // Values (/V) or Selected Indices (/I) objects conflict with each not being
326 // an array.
327 auto values = pdfium::MakeRetain<CPDF_String>(/*pPool=*/nullptr, L"Gamma");
328 auto selected_indices = pdfium::MakeRetain<CPDF_Number>(4);
329 std::vector<int> expected_indices{2};
330 std::vector<int> excluded_indices{-1, 5};
331 TestMultiselectFieldDict(opt_array, values, selected_indices,
332 /*expected_use_indices=*/false, expected_indices,
333 excluded_indices);
334 }
335}
bool UseSelectedIndicesObject() const
static WideString GetFullNameForDict(const CPDF_Dictionary *pFieldDict)
int CountOptions() const
bool IsItemSelected(int index) const
static void Destroy()
static void Create()
const char * c_str() const
Definition bytestring.h:76
ByteString ToUTF8() const
bool IsEmpty() const
Definition widestring.h:118
TEST(FXCRYPT, MD5GenerateEmtpyData)
constexpr uint32_t kChoiceMultiSelect
Definition form_flags.h:39