1 // Copyright 2015 PDFium Authors. All rights reserved.
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 <memory>
6 #include <string>
7 #include <vector>
8 
9 #include "core/fxcrt/fx_coordinates.h"
10 #include "core/fxcrt/fx_string.h"
11 #include "core/fxcrt/fx_system.h"
12 #include "public/cpp/fpdf_deleters.h"
13 #include "public/fpdf_formfill.h"
14 #include "public/fpdf_fwlevent.h"
15 #include "testing/embedder_test.h"
16 #include "testing/embedder_test_mock_delegate.h"
17 #include "testing/embedder_test_timer_handling_delegate.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 
21 using testing::_;
22 
23 using FPDFFormFillEmbeddertest = EmbedderTest;
24 
25 // A base class for many related tests that involve clicking and typing into
26 // form fields.
27 class FPDFFormFillInteractiveEmbeddertest : public FPDFFormFillEmbeddertest {
28  protected:
29   FPDFFormFillInteractiveEmbeddertest() = default;
30   ~FPDFFormFillInteractiveEmbeddertest() override = default;
31 
SetUp()32   void SetUp() override {
33     FPDFFormFillEmbeddertest::SetUp();
34     ASSERT_TRUE(OpenDocument(GetDocumentName()));
35     page_ = LoadPage(0);
36     ASSERT_TRUE(page_);
37     FormSanityChecks();
38   }
39 
TearDown()40   void TearDown() override {
41     UnloadPage(page_);
42     FPDFFormFillEmbeddertest::TearDown();
43   }
44 
45   // Returns the name of the PDF to use.
46   virtual const char* GetDocumentName() const = 0;
47 
48   // Returns the type of field(s) in the PDF.
49   virtual int GetFormType() const = 0;
50 
51   // Optionally do some sanity check on the document after loading.
FormSanityChecks()52   virtual void FormSanityChecks() {}
53 
page()54   FPDF_PAGE page() { return page_; }
55 
GetFormTypeAtPoint(const CFX_PointF & point)56   int GetFormTypeAtPoint(const CFX_PointF& point) {
57     return FPDFPage_HasFormFieldAtPoint(form_handle(), page_, point.x, point.y);
58   }
59 
ClickOnFormFieldAtPoint(const CFX_PointF & point)60   void ClickOnFormFieldAtPoint(const CFX_PointF& point) {
61     // Click on the text field or combobox as specified by coordinates.
62     FORM_OnMouseMove(form_handle(), page_, 0, point.x, point.y);
63     FORM_OnLButtonDown(form_handle(), page_, 0, point.x, point.y);
64     FORM_OnLButtonUp(form_handle(), page_, 0, point.x, point.y);
65   }
66 
TypeTextIntoTextField(int num_chars,const CFX_PointF & point)67   void TypeTextIntoTextField(int num_chars, const CFX_PointF& point) {
68     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(point));
69     ClickOnFormFieldAtPoint(point);
70 
71     // Type text starting with 'A' to as many chars as specified by |num_chars|.
72     for (int i = 0; i < num_chars; ++i) {
73       FORM_OnChar(form_handle(), page_, 'A' + i, 0);
74     }
75   }
76 
77   // Navigates to text field using the mouse and then selects text via the
78   // shift and specfied left or right arrow key.
SelectTextWithKeyboard(int num_chars,int arrow_key,const CFX_PointF & point)79   void SelectTextWithKeyboard(int num_chars,
80                               int arrow_key,
81                               const CFX_PointF& point) {
82     // Navigate to starting position for selection.
83     ClickOnFormFieldAtPoint(point);
84 
85     // Hold down shift (and don't release until entire text is selected).
86     FORM_OnKeyDown(form_handle(), page_, FWL_VKEY_Shift, 0);
87 
88     // Select text char by char via left or right arrow key.
89     for (int i = 0; i < num_chars; ++i) {
90       FORM_OnKeyDown(form_handle(), page_, arrow_key, FWL_EVENTFLAG_ShiftKey);
91       FORM_OnKeyUp(form_handle(), page_, arrow_key, FWL_EVENTFLAG_ShiftKey);
92     }
93     FORM_OnKeyUp(form_handle(), page_, FWL_VKEY_Shift, 0);
94   }
95 
96   // Uses the mouse to navigate to text field and select text.
SelectTextWithMouse(const CFX_PointF & start,const CFX_PointF & end)97   void SelectTextWithMouse(const CFX_PointF& start, const CFX_PointF& end) {
98     ASSERT(start.y == end.y);
99 
100     // Navigate to starting position and click mouse.
101     FORM_OnMouseMove(form_handle(), page_, 0, start.x, start.y);
102     FORM_OnLButtonDown(form_handle(), page_, 0, start.x, start.y);
103 
104     // Hold down mouse until reach end of desired selection.
105     FORM_OnMouseMove(form_handle(), page_, 0, end.x, end.y);
106     FORM_OnLButtonUp(form_handle(), page_, 0, end.x, end.y);
107   }
108 
CheckSelection(const WideStringView & expected_string)109   void CheckSelection(const WideStringView& expected_string) {
110     // Calculate expected length for selected text.
111     int num_chars = expected_string.GetLength();
112 
113     // Check actual selection against expected selection.
114     const unsigned long expected_length =
115         sizeof(unsigned short) * (num_chars + 1);
116     unsigned long sel_text_len =
117         FORM_GetSelectedText(form_handle(), page_, nullptr, 0);
118     ASSERT_EQ(expected_length, sel_text_len);
119 
120     std::vector<unsigned short> buf(sel_text_len);
121     EXPECT_EQ(expected_length, FORM_GetSelectedText(form_handle(), page_,
122                                                     buf.data(), sel_text_len));
123 
124     EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars));
125   }
126 
127  private:
128   FPDF_PAGE page_ = nullptr;
129 };
130 
131 class FPDFFormFillTextFormEmbeddertest
132     : public FPDFFormFillInteractiveEmbeddertest {
133  protected:
134   FPDFFormFillTextFormEmbeddertest() = default;
135   ~FPDFFormFillTextFormEmbeddertest() override = default;
136 
GetDocumentName() const137   const char* GetDocumentName() const override {
138     // PDF with several form text fields:
139     // - "Text Box" - Regular text box with no special attributes.
140     // - "ReadOnly" - Ff: 1.
141     // - "CharLimit" - MaxLen: 10, V: Elephant.
142     return "text_form_multiple.pdf";
143   }
144 
GetFormType() const145   int GetFormType() const override { return FPDF_FORMFIELD_TEXTFIELD; }
146 
FormSanityChecks()147   void FormSanityChecks() override {
148     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(CharLimitFormBegin()));
149     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(CharLimitFormEnd()));
150     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(RegularFormBegin()));
151     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(RegularFormEnd()));
152   }
153 
SelectAllCharLimitFormTextWithMouse()154   void SelectAllCharLimitFormTextWithMouse() {
155     SelectTextWithMouse(CharLimitFormEnd(), CharLimitFormBegin());
156   }
157 
SelectAllRegularFormTextWithMouse()158   void SelectAllRegularFormTextWithMouse() {
159     SelectTextWithMouse(RegularFormEnd(), RegularFormBegin());
160   }
161 
CharLimitFormBegin() const162   const CFX_PointF& CharLimitFormBegin() const {
163     static const CFX_PointF point = CharLimitFormAtX(kFormBeginX);
164     return point;
165   }
166 
CharLimitFormEnd() const167   const CFX_PointF& CharLimitFormEnd() const {
168     static const CFX_PointF point = CharLimitFormAtX(kFormEndX);
169     return point;
170   }
171 
RegularFormBegin() const172   const CFX_PointF& RegularFormBegin() const {
173     static const CFX_PointF point = RegularFormAtX(kFormBeginX);
174     return point;
175   }
176 
RegularFormEnd() const177   const CFX_PointF& RegularFormEnd() const {
178     static const CFX_PointF point = RegularFormAtX(kFormEndX);
179     return point;
180   }
181 
CharLimitFormAtX(float x)182   static CFX_PointF CharLimitFormAtX(float x) {
183     ASSERT(x >= kFormBeginX);
184     ASSERT(x <= kFormEndX);
185     return CFX_PointF(x, kCharLimitFormY);
186   }
187 
RegularFormAtX(float x)188   static CFX_PointF RegularFormAtX(float x) {
189     ASSERT(x >= kFormBeginX);
190     ASSERT(x <= kFormEndX);
191     return CFX_PointF(x, kRegularFormY);
192   }
193 
194  private:
195   static constexpr float kFormBeginX = 102.0;
196   static constexpr float kFormEndX = 195.0;
197   static constexpr float kCharLimitFormY = 60.0;
198   static constexpr float kRegularFormY = 115.0;
199 };
200 
201 class FPDFFormFillComboBoxFormEmbeddertest
202     : public FPDFFormFillInteractiveEmbeddertest {
203  protected:
204   FPDFFormFillComboBoxFormEmbeddertest() = default;
205   ~FPDFFormFillComboBoxFormEmbeddertest() override = default;
206 
GetDocumentName() const207   const char* GetDocumentName() const override {
208     // PDF with form comboboxes:
209     // - "Combo_Editable" - Ff: 393216, 3 options with pair values.
210     // - "Combo1" - Ff: 131072, 3 options with single values.
211     // - "Combo_ReadOnly" - Ff: 131073, 3 options with single values.
212     return "combobox_form.pdf";
213   }
214 
GetFormType() const215   int GetFormType() const override { return FPDF_FORMFIELD_COMBOBOX; }
216 
FormSanityChecks()217   void FormSanityChecks() override {
218     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormBegin()));
219     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormEnd()));
220     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormDropDown()));
221     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormBegin()));
222     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormEnd()));
223     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormDropDown()));
224   }
225 
SelectEditableFormOption(int item_index)226   void SelectEditableFormOption(int item_index) {
227     SelectOption(item_index, EditableFormDropDown());
228   }
229 
SelectNonEditableFormOption(int item_index)230   void SelectNonEditableFormOption(int item_index) {
231     SelectOption(item_index, NonEditableFormDropDown());
232   }
233 
SelectAllEditableFormTextWithMouse()234   void SelectAllEditableFormTextWithMouse() {
235     SelectTextWithMouse(EditableFormEnd(), EditableFormBegin());
236   }
237 
EditableFormBegin() const238   const CFX_PointF& EditableFormBegin() const {
239     static const CFX_PointF point = EditableFormAtX(kFormBeginX);
240     return point;
241   }
242 
EditableFormEnd() const243   const CFX_PointF& EditableFormEnd() const {
244     static const CFX_PointF point = EditableFormAtX(kFormEndX);
245     return point;
246   }
247 
EditableFormDropDown() const248   const CFX_PointF& EditableFormDropDown() const {
249     static const CFX_PointF point(kFormDropDownX, kEditableFormY);
250     return point;
251   }
252 
NonEditableFormBegin() const253   const CFX_PointF& NonEditableFormBegin() const {
254     static const CFX_PointF point = NonEditableFormAtX(kFormBeginX);
255     return point;
256   }
257 
NonEditableFormEnd() const258   const CFX_PointF& NonEditableFormEnd() const {
259     static const CFX_PointF point = NonEditableFormAtX(kFormEndX);
260     return point;
261   }
262 
NonEditableFormDropDown() const263   const CFX_PointF& NonEditableFormDropDown() const {
264     static const CFX_PointF point(kFormDropDownX, kNonEditableFormY);
265     return point;
266   }
267 
EditableFormAtX(float x)268   static CFX_PointF EditableFormAtX(float x) {
269     ASSERT(x >= kFormBeginX);
270     ASSERT(x <= kFormEndX);
271     return CFX_PointF(x, kEditableFormY);
272   }
273 
NonEditableFormAtX(float x)274   static CFX_PointF NonEditableFormAtX(float x) {
275     ASSERT(x >= kFormBeginX);
276     ASSERT(x <= kFormEndX);
277     return CFX_PointF(x, kNonEditableFormY);
278   }
279 
280  private:
281   // Selects one of the pre-selected values from a combobox with three options.
282   // Options are specified by |item_index|, which is 0-based.
SelectOption(int item_index,const CFX_PointF & point)283   void SelectOption(int item_index, const CFX_PointF& point) {
284     // Only relevant for comboboxes with three choices and the same dimensions
285     // as those in combobox_form.pdf.
286     ASSERT(item_index >= 0);
287     ASSERT(item_index < 3);
288 
289     // Navigate to button for drop down and click mouse to reveal options.
290     ClickOnFormFieldAtPoint(point);
291 
292     // Calculate to Y-coordinate of dropdown option to be selected.
293     constexpr double kChoiceHeight = 15;
294     CFX_PointF option_point = point;
295     option_point.y -= kChoiceHeight * (item_index + 1);
296 
297     // Navigate to option and click mouse to select it.
298     ClickOnFormFieldAtPoint(option_point);
299   }
300 
301   static constexpr float kFormBeginX = 102.0;
302   static constexpr float kFormEndX = 183.0;
303   static constexpr float kFormDropDownX = 192.0;
304   static constexpr float kEditableFormY = 60.0;
305   static constexpr float kNonEditableFormY = 110.0;
306 };
307 
TEST_F(FPDFFormFillEmbeddertest,FirstTest)308 TEST_F(FPDFFormFillEmbeddertest, FirstTest) {
309   EmbedderTestMockDelegate mock;
310   EXPECT_CALL(mock, Alert(_, _, _, _)).Times(0);
311   EXPECT_CALL(mock, UnsupportedHandler(_)).Times(0);
312   EXPECT_CALL(mock, SetTimer(_, _)).Times(0);
313   EXPECT_CALL(mock, KillTimer(_)).Times(0);
314   SetDelegate(&mock);
315 
316   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
317   FPDF_PAGE page = LoadPage(0);
318   EXPECT_TRUE(page);
319   UnloadPage(page);
320 }
321 
TEST_F(FPDFFormFillEmbeddertest,BUG_487928)322 TEST_F(FPDFFormFillEmbeddertest, BUG_487928) {
323   EmbedderTestTimerHandlingDelegate delegate;
324   SetDelegate(&delegate);
325 
326   EXPECT_TRUE(OpenDocument("bug_487928.pdf"));
327   FPDF_PAGE page = LoadPage(0);
328   EXPECT_TRUE(page);
329   DoOpenActions();
330   delegate.AdvanceTime(5000);
331   UnloadPage(page);
332 }
333 
TEST_F(FPDFFormFillEmbeddertest,BUG_507316)334 TEST_F(FPDFFormFillEmbeddertest, BUG_507316) {
335   EmbedderTestTimerHandlingDelegate delegate;
336   SetDelegate(&delegate);
337 
338   EXPECT_TRUE(OpenDocument("bug_507316.pdf"));
339   FPDF_PAGE page = LoadPage(2);
340   EXPECT_TRUE(page);
341   DoOpenActions();
342   delegate.AdvanceTime(4000);
343   UnloadPage(page);
344 }
345 
TEST_F(FPDFFormFillEmbeddertest,BUG_514690)346 TEST_F(FPDFFormFillEmbeddertest, BUG_514690) {
347   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
348   FPDF_PAGE page = LoadPage(0);
349   EXPECT_TRUE(page);
350 
351   // Test that FORM_OnMouseMove() etc. permit null HANDLES and PAGES.
352   FORM_OnMouseMove(nullptr, page, 0, 10.0, 10.0);
353   FORM_OnMouseMove(form_handle(), nullptr, 0, 10.0, 10.0);
354 
355   UnloadPage(page);
356 }
357 
358 #ifdef PDF_ENABLE_V8
TEST_F(FPDFFormFillEmbeddertest,BUG_551248)359 TEST_F(FPDFFormFillEmbeddertest, BUG_551248) {
360   // Test that timers fire once and intervals fire repeatedly.
361   EmbedderTestTimerHandlingDelegate delegate;
362   SetDelegate(&delegate);
363 
364   EXPECT_TRUE(OpenDocument("bug_551248.pdf"));
365   FPDF_PAGE page = LoadPage(0);
366   EXPECT_TRUE(page);
367   DoOpenActions();
368 
369   const auto& alerts = delegate.GetAlerts();
370   EXPECT_EQ(0U, alerts.size());
371 
372   delegate.AdvanceTime(1000);
373   EXPECT_EQ(0U, alerts.size());  // nothing fired.
374   delegate.AdvanceTime(1000);
375   EXPECT_EQ(1U, alerts.size());  // interval fired.
376   delegate.AdvanceTime(1000);
377   EXPECT_EQ(2U, alerts.size());  // timer fired.
378   delegate.AdvanceTime(1000);
379   EXPECT_EQ(3U, alerts.size());  // interval fired again.
380   delegate.AdvanceTime(1000);
381   EXPECT_EQ(3U, alerts.size());  // nothing fired.
382   delegate.AdvanceTime(1000);
383   EXPECT_EQ(4U, alerts.size());  // interval fired again.
384   delegate.AdvanceTime(1000);
385   EXPECT_EQ(4U, alerts.size());  // nothing fired.
386   UnloadPage(page);
387 
388   ASSERT_EQ(4U, alerts.size());  // nothing else fired.
389 
390   EXPECT_STREQ(L"interval fired", alerts[0].message.c_str());
391   EXPECT_STREQ(L"Alert", alerts[0].title.c_str());
392   EXPECT_EQ(0, alerts[0].type);
393   EXPECT_EQ(0, alerts[0].icon);
394 
395   EXPECT_STREQ(L"timer fired", alerts[1].message.c_str());
396   EXPECT_STREQ(L"Alert", alerts[1].title.c_str());
397   EXPECT_EQ(0, alerts[1].type);
398   EXPECT_EQ(0, alerts[1].icon);
399 
400   EXPECT_STREQ(L"interval fired", alerts[2].message.c_str());
401   EXPECT_STREQ(L"Alert", alerts[2].title.c_str());
402   EXPECT_EQ(0, alerts[2].type);
403   EXPECT_EQ(0, alerts[2].icon);
404 
405   EXPECT_STREQ(L"interval fired", alerts[3].message.c_str());
406   EXPECT_STREQ(L"Alert", alerts[3].title.c_str());
407   EXPECT_EQ(0, alerts[3].type);
408   EXPECT_EQ(0, alerts[3].icon);
409 }
410 
TEST_F(FPDFFormFillEmbeddertest,BUG_620428)411 TEST_F(FPDFFormFillEmbeddertest, BUG_620428) {
412   // Test that timers and intervals are cancelable.
413   EmbedderTestTimerHandlingDelegate delegate;
414   SetDelegate(&delegate);
415 
416   EXPECT_TRUE(OpenDocument("bug_620428.pdf"));
417   FPDF_PAGE page = LoadPage(0);
418   EXPECT_TRUE(page);
419   DoOpenActions();
420   delegate.AdvanceTime(5000);
421   UnloadPage(page);
422 
423   const auto& alerts = delegate.GetAlerts();
424   ASSERT_EQ(1U, alerts.size());
425   EXPECT_STREQ(L"done", alerts[0].message.c_str());
426 }
427 
TEST_F(FPDFFormFillEmbeddertest,BUG_634394)428 TEST_F(FPDFFormFillEmbeddertest, BUG_634394) {
429   // Cancel timer inside timer callback.
430   EmbedderTestTimerHandlingDelegate delegate;
431   SetDelegate(&delegate);
432 
433   EXPECT_TRUE(OpenDocument("bug_634394.pdf"));
434   FPDF_PAGE page = LoadPage(0);
435   EXPECT_TRUE(page);
436   DoOpenActions();
437 
438   // Timers fire at most once per AdvanceTime(), allow intervals
439   // to fire several times if possible.
440   delegate.AdvanceTime(1000);
441   delegate.AdvanceTime(1000);
442   delegate.AdvanceTime(1000);
443   delegate.AdvanceTime(1000);
444   delegate.AdvanceTime(1000);
445   UnloadPage(page);
446 
447   const auto& alerts = delegate.GetAlerts();
448   EXPECT_EQ(2U, alerts.size());
449 }
450 
TEST_F(FPDFFormFillEmbeddertest,BUG_634716)451 TEST_F(FPDFFormFillEmbeddertest, BUG_634716) {
452   EmbedderTestTimerHandlingDelegate delegate;
453   SetDelegate(&delegate);
454 
455   EXPECT_TRUE(OpenDocument("bug_634716.pdf"));
456   FPDF_PAGE page = LoadPage(0);
457   EXPECT_TRUE(page);
458   DoOpenActions();
459 
460   // Timers fire at most once per AdvanceTime(), allow intervals
461   // to fire several times if possible.
462   delegate.AdvanceTime(1000);
463   delegate.AdvanceTime(1000);
464   delegate.AdvanceTime(1000);
465   delegate.AdvanceTime(1000);
466   delegate.AdvanceTime(1000);
467   UnloadPage(page);
468 
469   const auto& alerts = delegate.GetAlerts();
470   EXPECT_EQ(2U, alerts.size());
471 }
472 
TEST_F(FPDFFormFillEmbeddertest,BUG_679649)473 TEST_F(FPDFFormFillEmbeddertest, BUG_679649) {
474   EmbedderTestTimerHandlingDelegate delegate;
475   SetDelegate(&delegate);
476 
477   EXPECT_TRUE(OpenDocument("bug_679649.pdf"));
478   FPDF_PAGE page = LoadPage(0);
479   EXPECT_TRUE(page);
480 
481   delegate.SetFailNextTimer();
482   DoOpenActions();
483   delegate.AdvanceTime(2000);
484   UnloadPage(page);
485 
486   const auto& alerts = delegate.GetAlerts();
487   EXPECT_EQ(0u, alerts.size());
488 }
489 
TEST_F(FPDFFormFillEmbeddertest,BUG_707673)490 TEST_F(FPDFFormFillEmbeddertest, BUG_707673) {
491   EmbedderTestTimerHandlingDelegate delegate;
492   SetDelegate(&delegate);
493 
494   EXPECT_TRUE(OpenDocument("bug_707673.pdf"));
495   FPDF_PAGE page = LoadPage(0);
496   EXPECT_TRUE(page);
497 
498   DoOpenActions();
499   FORM_OnLButtonDown(form_handle(), page, 0, 140, 590);
500   FORM_OnLButtonUp(form_handle(), page, 0, 140, 590);
501   delegate.AdvanceTime(1000);
502   UnloadPage(page);
503 
504   const auto& alerts = delegate.GetAlerts();
505   EXPECT_EQ(0u, alerts.size());
506 }
507 
TEST_F(FPDFFormFillEmbeddertest,BUG_765384)508 TEST_F(FPDFFormFillEmbeddertest, BUG_765384) {
509   EXPECT_TRUE(OpenDocument("bug_765384.pdf"));
510   FPDF_PAGE page = LoadPage(0);
511   EXPECT_TRUE(page);
512 
513   DoOpenActions();
514   FORM_OnLButtonDown(form_handle(), page, 0, 140, 590);
515   FORM_OnLButtonUp(form_handle(), page, 0, 140, 590);
516   UnloadPage(page);
517 }
518 
519 #endif  // PDF_ENABLE_V8
520 
TEST_F(FPDFFormFillEmbeddertest,FormText)521 TEST_F(FPDFFormFillEmbeddertest, FormText) {
522 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
523   const char md5_1[] = "5f11dbe575fe197a37c3fb422559f8ff";
524   const char md5_2[] = "35b1a4b679eafc749a0b6fda750c0e8d";
525   const char md5_3[] = "65c64a7c355388f719a752aa1e23f6fe";
526 #else
527   const char md5_1[] = "b890950d4b9bc163b1a96797f3004b53";
528   const char md5_2[] = "11487d5597599a26e8912b9c1d9422cb";
529   const char md5_3[] = "bffe0ecea9a533f217047ee41d6be466";
530 #endif
531   {
532     EXPECT_TRUE(OpenDocument("text_form.pdf"));
533     FPDF_PAGE page = LoadPage(0);
534     ASSERT_TRUE(page);
535     std::unique_ptr<void, FPDFBitmapDeleter> bitmap1(RenderPage(page));
536     CompareBitmap(bitmap1.get(), 300, 300, md5_1);
537 
538     // Click on the textfield
539     EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
540               FPDFPage_HasFormFieldAtPoint(form_handle(), page, 120.0, 120.0));
541     FORM_OnMouseMove(form_handle(), page, 0, 120.0, 120.0);
542     FORM_OnLButtonDown(form_handle(), page, 0, 120.0, 120.0);
543     FORM_OnLButtonUp(form_handle(), page, 0, 120.0, 120.0);
544 
545     // Write "ABC"
546     FORM_OnChar(form_handle(), page, 65, 0);
547     FORM_OnChar(form_handle(), page, 66, 0);
548     FORM_OnChar(form_handle(), page, 67, 0);
549     std::unique_ptr<void, FPDFBitmapDeleter> bitmap2(RenderPage(page));
550     CompareBitmap(bitmap2.get(), 300, 300, md5_2);
551 
552     // Take out focus by clicking out of the textfield
553     FORM_OnMouseMove(form_handle(), page, 0, 15.0, 15.0);
554     FORM_OnLButtonDown(form_handle(), page, 0, 15.0, 15.0);
555     FORM_OnLButtonUp(form_handle(), page, 0, 15.0, 15.0);
556     std::unique_ptr<void, FPDFBitmapDeleter> bitmap3(RenderPage(page));
557     CompareBitmap(bitmap3.get(), 300, 300, md5_3);
558 
559     EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
560 
561     // Close page
562     UnloadPage(page);
563   }
564   // Check saved document
565   VerifySavedDocument(300, 300, md5_3);
566 }
567 
TEST_F(FPDFFormFillEmbeddertest,HasFormInfoNone)568 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoNone) {
569   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
570   EXPECT_EQ(FORMTYPE_NONE, FPDF_GetFormType(document_));
571 }
572 
TEST_F(FPDFFormFillEmbeddertest,HasFormInfoAcroForm)573 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoAcroForm) {
574   EXPECT_TRUE(OpenDocument("text_form.pdf"));
575   EXPECT_EQ(FORMTYPE_ACRO_FORM, FPDF_GetFormType(document_));
576 }
577 
TEST_F(FPDFFormFillEmbeddertest,HasFormInfoXFAFull)578 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoXFAFull) {
579   EXPECT_TRUE(OpenDocument("simple_xfa.pdf"));
580   EXPECT_EQ(FORMTYPE_XFA_FULL, FPDF_GetFormType(document_));
581 }
582 
TEST_F(FPDFFormFillEmbeddertest,HasFormInfoXFAForeground)583 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoXFAForeground) {
584   EXPECT_TRUE(OpenDocument("bug_216.pdf"));
585   EXPECT_EQ(FORMTYPE_XFA_FOREGROUND, FPDF_GetFormType(document_));
586 }
587 
TEST_F(FPDFFormFillTextFormEmbeddertest,GetSelectedTextEmptyAndBasicKeyboard)588 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextEmptyAndBasicKeyboard) {
589   // Test empty selection.
590   CheckSelection(L"");
591 
592   // Test basic selection.
593   TypeTextIntoTextField(3, RegularFormBegin());
594   SelectTextWithKeyboard(3, FWL_VKEY_Left, RegularFormAtX(123.0));
595   CheckSelection(L"ABC");
596 }
597 
TEST_F(FPDFFormFillTextFormEmbeddertest,GetSelectedTextEmptyAndBasicMouse)598 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextEmptyAndBasicMouse) {
599   // Test empty selection.
600   CheckSelection(L"");
601 
602   // Test basic selection.
603   TypeTextIntoTextField(3, RegularFormBegin());
604   SelectTextWithMouse(RegularFormAtX(125.0), RegularFormBegin());
605   CheckSelection(L"ABC");
606 }
607 
TEST_F(FPDFFormFillTextFormEmbeddertest,GetSelectedTextFragmentsKeyBoard)608 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextFragmentsKeyBoard) {
609   TypeTextIntoTextField(12, RegularFormBegin());
610 
611   // Test selecting first character in forward direction.
612   SelectTextWithKeyboard(1, FWL_VKEY_Right, RegularFormBegin());
613   CheckSelection(L"A");
614 
615   // Test selecting entire long string in backwards direction.
616   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
617   CheckSelection(L"ABCDEFGHIJKL");
618 
619   // Test selecting middle section in backwards direction.
620   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(170.0));
621   CheckSelection(L"DEFGHI");
622 
623   // Test selecting middle selection in forward direction.
624   SelectTextWithKeyboard(6, FWL_VKEY_Right, RegularFormAtX(125.0));
625   CheckSelection(L"DEFGHI");
626 
627   // Test selecting last character in backwards direction.
628   SelectTextWithKeyboard(1, FWL_VKEY_Left, RegularFormEnd());
629   CheckSelection(L"L");
630 }
631 
TEST_F(FPDFFormFillTextFormEmbeddertest,GetSelectedTextFragmentsMouse)632 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextFragmentsMouse) {
633   TypeTextIntoTextField(12, RegularFormBegin());
634 
635   // Test selecting first character in forward direction.
636   SelectTextWithMouse(RegularFormBegin(), RegularFormAtX(106.0));
637   CheckSelection(L"A");
638 
639   // Test selecting entire long string in backwards direction.
640   SelectAllRegularFormTextWithMouse();
641   CheckSelection(L"ABCDEFGHIJKL");
642 
643   // Test selecting middle section in backwards direction.
644   SelectTextWithMouse(RegularFormAtX(170.0), RegularFormAtX(125.0));
645   CheckSelection(L"DEFGHI");
646 
647   // Test selecting middle selection in forward direction.
648   SelectTextWithMouse(RegularFormAtX(125.0), RegularFormAtX(170.0));
649   CheckSelection(L"DEFGHI");
650 
651   // Test selecting last character in backwards direction.
652   SelectTextWithMouse(RegularFormEnd(), RegularFormAtX(186.0));
653   CheckSelection(L"L");
654 }
655 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,GetSelectedTextEmptyAndBasicNormalComboBox)656 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
657        GetSelectedTextEmptyAndBasicNormalComboBox) {
658   // Test empty selection.
659   CheckSelection(L"");
660 
661   // Non-editable comboboxes don't allow selection with keyboard.
662   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(142.0));
663   CheckSelection(L"Banana");
664 
665   // Select other another provided option.
666   SelectNonEditableFormOption(0);
667   CheckSelection(L"Apple");
668 }
669 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,GetSelectedTextEmptyAndBasicEditableComboBoxKeyboard)670 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
671        GetSelectedTextEmptyAndBasicEditableComboBoxKeyboard) {
672   // Test empty selection.
673   CheckSelection(L"");
674 
675   // Test basic selection of text within user editable combobox using keyboard.
676   TypeTextIntoTextField(3, EditableFormBegin());
677   SelectTextWithKeyboard(3, FWL_VKEY_Left, EditableFormAtX(128.0));
678   CheckSelection(L"ABC");
679 
680   // Select a provided option.
681   SelectEditableFormOption(1);
682   CheckSelection(L"Bar");
683 }
684 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,GetSelectedTextEmptyAndBasicEditableComboBoxMouse)685 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
686        GetSelectedTextEmptyAndBasicEditableComboBoxMouse) {
687   // Test empty selection.
688   CheckSelection(L"");
689 
690   // Test basic selection of text within user editable combobox using mouse.
691   TypeTextIntoTextField(3, EditableFormBegin());
692   SelectTextWithMouse(EditableFormAtX(128.0), EditableFormBegin());
693   CheckSelection(L"ABC");
694 
695   // Select a provided option.
696   SelectEditableFormOption(2);
697   CheckSelection(L"Qux");
698 }
699 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,GetSelectedTextFragmentsNormalComboBox)700 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
701        GetSelectedTextFragmentsNormalComboBox) {
702   // Test selecting first character in forward direction.
703   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(107.0));
704   CheckSelection(L"B");
705 
706   // Test selecting entire string in backwards direction.
707   SelectTextWithMouse(NonEditableFormAtX(142.0), NonEditableFormBegin());
708   CheckSelection(L"Banana");
709 
710   // Test selecting middle section in backwards direction.
711   SelectTextWithMouse(NonEditableFormAtX(135.0), NonEditableFormAtX(117.0));
712   CheckSelection(L"nan");
713 
714   // Test selecting middle section in forward direction.
715   SelectTextWithMouse(NonEditableFormAtX(117.0), NonEditableFormAtX(135.0));
716   CheckSelection(L"nan");
717 
718   // Test selecting last character in backwards direction.
719   SelectTextWithMouse(NonEditableFormAtX(142.0), NonEditableFormAtX(138.0));
720   CheckSelection(L"a");
721 
722   // Select another option and then reset selection as first three chars.
723   SelectNonEditableFormOption(2);
724   CheckSelection(L"Cherry");
725   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(122.0));
726   CheckSelection(L"Che");
727 }
728 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,GetSelectedTextFragmentsEditableComboBoxKeyboard)729 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
730        GetSelectedTextFragmentsEditableComboBoxKeyboard) {
731   TypeTextIntoTextField(10, EditableFormBegin());
732 
733   // Test selecting first character in forward direction.
734   SelectTextWithKeyboard(1, FWL_VKEY_Right, EditableFormBegin());
735   CheckSelection(L"A");
736 
737   // Test selecting entire long string in backwards direction.
738   SelectTextWithKeyboard(10, FWL_VKEY_Left, EditableFormEnd());
739   CheckSelection(L"ABCDEFGHIJ");
740 
741   // Test selecting middle section in backwards direction.
742   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(168.0));
743   CheckSelection(L"DEFGH");
744 
745   // Test selecting middle selection in forward direction.
746   SelectTextWithKeyboard(5, FWL_VKEY_Right, EditableFormAtX(127.0));
747   CheckSelection(L"DEFGH");
748 
749   // Test selecting last character in backwards direction.
750   SelectTextWithKeyboard(1, FWL_VKEY_Left, EditableFormEnd());
751   CheckSelection(L"J");
752 
753   // Select a provided option and then reset selection as first two chars.
754   SelectEditableFormOption(0);
755   CheckSelection(L"Foo");
756   SelectTextWithKeyboard(2, FWL_VKEY_Right, EditableFormBegin());
757   CheckSelection(L"Fo");
758 }
759 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,GetSelectedTextFragmentsEditableComboBoxMouse)760 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
761        GetSelectedTextFragmentsEditableComboBoxMouse) {
762   TypeTextIntoTextField(10, EditableFormBegin());
763 
764   // Test selecting first character in forward direction.
765   SelectTextWithMouse(EditableFormBegin(), EditableFormAtX(107.0));
766   CheckSelection(L"A");
767 
768   // Test selecting entire long string in backwards direction.
769   SelectAllEditableFormTextWithMouse();
770   CheckSelection(L"ABCDEFGHIJ");
771 
772   // Test selecting middle section in backwards direction.
773   SelectTextWithMouse(EditableFormAtX(168.0), EditableFormAtX(127.0));
774   CheckSelection(L"DEFGH");
775 
776   // Test selecting middle selection in forward direction.
777   SelectTextWithMouse(EditableFormAtX(127.0), EditableFormAtX(168.0));
778   CheckSelection(L"DEFGH");
779 
780   // Test selecting last character in backwards direction.
781   SelectTextWithMouse(EditableFormEnd(), EditableFormAtX(174.0));
782   CheckSelection(L"J");
783 }
784 
TEST_F(FPDFFormFillTextFormEmbeddertest,DeleteTextFieldEntireSelection)785 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldEntireSelection) {
786   // Select entire contents of text field.
787   TypeTextIntoTextField(12, RegularFormBegin());
788   SelectAllRegularFormTextWithMouse();
789   CheckSelection(L"ABCDEFGHIJKL");
790 
791   // Test deleting current text selection. Select what remains after deletion to
792   // check that remaining text is as expected.
793   FORM_ReplaceSelection(form_handle(), page(), nullptr);
794 
795   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
796   CheckSelection(L"");
797 }
798 
TEST_F(FPDFFormFillTextFormEmbeddertest,DeleteTextFieldSelectionMiddle)799 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionMiddle) {
800   // Select middle section of text.
801   TypeTextIntoTextField(12, RegularFormBegin());
802   SelectTextWithMouse(RegularFormAtX(170.0), RegularFormAtX(125.0));
803   CheckSelection(L"DEFGHI");
804 
805   // Test deleting current text selection. Select what remains after deletion to
806   // check that remaining text is as expected.
807   FORM_ReplaceSelection(form_handle(), page(), nullptr);
808   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
809   CheckSelection(L"ABCJKL");
810 }
811 
TEST_F(FPDFFormFillTextFormEmbeddertest,DeleteTextFieldSelectionLeft)812 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionLeft) {
813   // Select first few characters of text.
814   TypeTextIntoTextField(12, RegularFormBegin());
815   SelectTextWithMouse(RegularFormBegin(), RegularFormAtX(132.0));
816   CheckSelection(L"ABCD");
817 
818   // Test deleting current text selection. Select what remains after deletion to
819   // check that remaining text is as expected.
820   FORM_ReplaceSelection(form_handle(), page(), nullptr);
821   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
822   CheckSelection(L"EFGHIJKL");
823 }
824 
TEST_F(FPDFFormFillTextFormEmbeddertest,DeleteTextFieldSelectionRight)825 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionRight) {
826   // Select last few characters of text.
827   TypeTextIntoTextField(12, RegularFormBegin());
828   SelectTextWithMouse(RegularFormEnd(), RegularFormAtX(165.0));
829   CheckSelection(L"IJKL");
830 
831   // Test deleting current text selection. Select what remains after deletion to
832   // check that remaining text is as expected.
833   FORM_ReplaceSelection(form_handle(), page(), nullptr);
834   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
835   CheckSelection(L"ABCDEFGH");
836 }
837 
TEST_F(FPDFFormFillTextFormEmbeddertest,DeleteEmptyTextFieldSelection)838 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteEmptyTextFieldSelection) {
839   // Do not select text.
840   TypeTextIntoTextField(12, RegularFormBegin());
841   CheckSelection(L"");
842 
843   // Test that attempt to delete empty text selection has no effect.
844   FORM_ReplaceSelection(form_handle(), page(), nullptr);
845   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
846   CheckSelection(L"ABCDEFGHIJKL");
847 }
848 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,DeleteEditableComboBoxEntireSelection)849 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
850        DeleteEditableComboBoxEntireSelection) {
851   // Select entire contents of user-editable combobox text field.
852   TypeTextIntoTextField(10, EditableFormBegin());
853   SelectAllEditableFormTextWithMouse();
854   CheckSelection(L"ABCDEFGHIJ");
855 
856   // Test deleting current text selection. Select what remains after deletion to
857   // check that remaining text is as expected.
858   FORM_ReplaceSelection(form_handle(), page(), nullptr);
859   SelectAllEditableFormTextWithMouse();
860   CheckSelection(L"");
861 }
862 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,DeleteEditableComboBoxSelectionMiddle)863 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
864        DeleteEditableComboBoxSelectionMiddle) {
865   // Select middle section of text.
866   TypeTextIntoTextField(10, EditableFormBegin());
867   SelectTextWithMouse(EditableFormAtX(168.0), EditableFormAtX(127.0));
868   CheckSelection(L"DEFGH");
869 
870   // Test deleting current text selection. Select what remains after deletion to
871   // check that remaining text is as expected.
872   FORM_ReplaceSelection(form_handle(), page(), nullptr);
873   SelectAllEditableFormTextWithMouse();
874   CheckSelection(L"ABCIJ");
875 }
876 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,DeleteEditableComboBoxSelectionLeft)877 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
878        DeleteEditableComboBoxSelectionLeft) {
879   // Select first few characters of text.
880   TypeTextIntoTextField(10, EditableFormBegin());
881   SelectTextWithMouse(EditableFormBegin(), EditableFormAtX(132.0));
882   CheckSelection(L"ABCD");
883 
884   // Test deleting current text selection. Select what remains after deletion to
885   // check that remaining text is as expected.
886   FORM_ReplaceSelection(form_handle(), page(), nullptr);
887   SelectAllEditableFormTextWithMouse();
888   CheckSelection(L"EFGHIJ");
889 }
890 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,DeleteEditableComboBoxSelectionRight)891 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
892        DeleteEditableComboBoxSelectionRight) {
893   // Select last few characters of text.
894   TypeTextIntoTextField(10, EditableFormBegin());
895   SelectTextWithMouse(EditableFormEnd(), EditableFormAtX(152.0));
896   CheckSelection(L"GHIJ");
897 
898   // Test deleting current text selection. Select what remains after deletion to
899   // check that remaining text is as expected.
900   FORM_ReplaceSelection(form_handle(), page(), nullptr);
901   SelectAllEditableFormTextWithMouse();
902   CheckSelection(L"ABCDEF");
903 }
904 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,DeleteEmptyEditableComboBoxSelection)905 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
906        DeleteEmptyEditableComboBoxSelection) {
907   // Do not select text.
908   TypeTextIntoTextField(10, EditableFormBegin());
909   CheckSelection(L"");
910 
911   // Test that attempt to delete empty text selection has no effect.
912   FORM_ReplaceSelection(form_handle(), page(), nullptr);
913   SelectAllEditableFormTextWithMouse();
914   CheckSelection(L"ABCDEFGHIJ");
915 }
916 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInEmptyTextField)917 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInEmptyTextField) {
918   ClickOnFormFieldAtPoint(RegularFormBegin());
919 
920   // Test inserting text into empty text field.
921   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
922       GetFPDFWideString(L"Hello");
923   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
924 
925   // Select entire contents of text field to check that insertion worked
926   // as expected.
927   SelectAllRegularFormTextWithMouse();
928   CheckSelection(L"Hello");
929 }
930 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInPopulatedTextFieldLeft)931 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldLeft) {
932   TypeTextIntoTextField(8, RegularFormBegin());
933 
934   // Click on the leftmost part of the text field.
935   ClickOnFormFieldAtPoint(RegularFormBegin());
936 
937   // Test inserting text in front of existing text in text field.
938   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
939       GetFPDFWideString(L"Hello");
940   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
941 
942   // Select entire contents of text field to check that insertion worked
943   // as expected.
944   SelectAllRegularFormTextWithMouse();
945   CheckSelection(L"HelloABCDEFGH");
946 }
947 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInPopulatedTextFieldMiddle)948 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldMiddle) {
949   TypeTextIntoTextField(8, RegularFormBegin());
950 
951   // Click on the middle of the text field.
952   ClickOnFormFieldAtPoint(RegularFormAtX(134.0));
953 
954   // Test inserting text in the middle of existing text in text field.
955   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
956       GetFPDFWideString(L"Hello");
957   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
958 
959   // Select entire contents of text field to check that insertion worked
960   // as expected.
961   SelectAllRegularFormTextWithMouse();
962   CheckSelection(L"ABCDHelloEFGH");
963 }
964 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInPopulatedTextFieldRight)965 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldRight) {
966   TypeTextIntoTextField(8, RegularFormBegin());
967 
968   // Click on the rightmost part of the text field.
969   ClickOnFormFieldAtPoint(RegularFormAtX(166.0));
970 
971   // Test inserting text behind existing text in text field.
972   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
973       GetFPDFWideString(L"Hello");
974   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
975 
976   // Select entire contents of text field to check that insertion worked
977   // as expected.
978   SelectAllRegularFormTextWithMouse();
979   CheckSelection(L"ABCDEFGHHello");
980 }
981 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedTextFieldWhole)982 TEST_F(FPDFFormFillTextFormEmbeddertest,
983        InsertTextAndReplaceSelectionInPopulatedTextFieldWhole) {
984   TypeTextIntoTextField(12, RegularFormBegin());
985 
986   // Select entire string in text field.
987   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
988   CheckSelection(L"ABCDEFGHIJKL");
989 
990   // Test replacing text selection with text to be inserted.
991   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
992       GetFPDFWideString(L"Hello");
993   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
994 
995   // Select entire contents of text field to check that insertion worked
996   // as expected.
997   SelectAllRegularFormTextWithMouse();
998   CheckSelection(L"Hello");
999 }
1000 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedTextFieldLeft)1001 TEST_F(FPDFFormFillTextFormEmbeddertest,
1002        InsertTextAndReplaceSelectionInPopulatedTextFieldLeft) {
1003   TypeTextIntoTextField(12, RegularFormBegin());
1004 
1005   // Select left portion of string in text field.
1006   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(148.0));
1007   CheckSelection(L"ABCDEF");
1008 
1009   // Test replacing text selection with text to be inserted.
1010   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1011       GetFPDFWideString(L"Hello");
1012   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1013 
1014   // Select entire contents of text field to check that insertion worked
1015   // as expected.
1016   SelectAllRegularFormTextWithMouse();
1017   CheckSelection(L"HelloGHIJKL");
1018 }
1019 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedTextFieldMiddle)1020 TEST_F(FPDFFormFillTextFormEmbeddertest,
1021        InsertTextAndReplaceSelectionInPopulatedTextFieldMiddle) {
1022   TypeTextIntoTextField(12, RegularFormBegin());
1023 
1024   // Select middle portion of string in text field.
1025   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(171.0));
1026   CheckSelection(L"DEFGHI");
1027 
1028   // Test replacing text selection with text to be inserted.
1029   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1030       GetFPDFWideString(L"Hello");
1031   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1032 
1033   // Select entire contents of text field to check that insertion worked
1034   // as expected.
1035   SelectAllRegularFormTextWithMouse();
1036   CheckSelection(L"ABCHelloJKL");
1037 }
1038 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedTextFieldRight)1039 TEST_F(FPDFFormFillTextFormEmbeddertest,
1040        InsertTextAndReplaceSelectionInPopulatedTextFieldRight) {
1041   TypeTextIntoTextField(12, RegularFormBegin());
1042 
1043   // Select right portion of string in text field.
1044   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormEnd());
1045   CheckSelection(L"GHIJKL");
1046 
1047   // Test replacing text selection with text to be inserted.
1048   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1049       GetFPDFWideString(L"Hello");
1050   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1051 
1052   // Select entire contents of text field to check that insertion worked
1053   // as expected.
1054   SelectAllRegularFormTextWithMouse();
1055   CheckSelection(L"ABCDEFHello");
1056 }
1057 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextInEmptyEditableComboBox)1058 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1059        InsertTextInEmptyEditableComboBox) {
1060   ClickOnFormFieldAtPoint(EditableFormBegin());
1061 
1062   // Test inserting text into empty user-editable combobox.
1063   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1064       GetFPDFWideString(L"Hello");
1065   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1066 
1067   // Select entire contents of user-editable combobox text field to check that
1068   // insertion worked as expected.
1069   SelectAllEditableFormTextWithMouse();
1070   CheckSelection(L"Hello");
1071 }
1072 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextInPopulatedEditableComboBoxLeft)1073 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1074        InsertTextInPopulatedEditableComboBoxLeft) {
1075   TypeTextIntoTextField(6, EditableFormBegin());
1076 
1077   // Click on the leftmost part of the user-editable combobox.
1078   ClickOnFormFieldAtPoint(EditableFormBegin());
1079 
1080   // Test inserting text in front of existing text in user-editable combobox.
1081   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1082       GetFPDFWideString(L"Hello");
1083   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1084 
1085   // Select entire contents of user-editable combobox text field to check that
1086   // insertion worked as expected.
1087   SelectAllEditableFormTextWithMouse();
1088   CheckSelection(L"HelloABCDEF");
1089 }
1090 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextInPopulatedEditableComboBoxMiddle)1091 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1092        InsertTextInPopulatedEditableComboBoxMiddle) {
1093   TypeTextIntoTextField(6, EditableFormBegin());
1094 
1095   // Click on the middle of the user-editable combobox.
1096   ClickOnFormFieldAtPoint(EditableFormAtX(126.0));
1097 
1098   // Test inserting text in the middle of existing text in user-editable
1099   // combobox.
1100   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1101       GetFPDFWideString(L"Hello");
1102   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1103 
1104   // Select entire contents of user-editable combobox text field to check that
1105   // insertion worked as expected.
1106   SelectAllEditableFormTextWithMouse();
1107   CheckSelection(L"ABCHelloDEF");
1108 }
1109 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextInPopulatedEditableComboBoxRight)1110 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1111        InsertTextInPopulatedEditableComboBoxRight) {
1112   TypeTextIntoTextField(6, EditableFormBegin());
1113 
1114   // Click on the rightmost part of the user-editable combobox.
1115   ClickOnFormFieldAtPoint(EditableFormEnd());
1116 
1117   // Test inserting text behind existing text in user-editable combobox.
1118   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1119       GetFPDFWideString(L"Hello");
1120   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1121 
1122   // Select entire contents of user-editable combobox text field to check that
1123   // insertion worked as expected.
1124   SelectAllEditableFormTextWithMouse();
1125   CheckSelection(L"ABCDEFHello");
1126 }
1127 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole)1128 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1129        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole) {
1130   TypeTextIntoTextField(10, EditableFormBegin());
1131 
1132   // Select entire string in user-editable combobox.
1133   SelectTextWithKeyboard(10, FWL_VKEY_Left, EditableFormEnd());
1134   CheckSelection(L"ABCDEFGHIJ");
1135 
1136   // Test replacing text selection with text to be inserted.
1137   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1138       GetFPDFWideString(L"Hello");
1139   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1140 
1141   // Select entire contents of user-editable combobox text field to check that
1142   // insertion worked as expected.
1143   SelectAllEditableFormTextWithMouse();
1144   CheckSelection(L"Hello");
1145 }
1146 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft)1147 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1148        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft) {
1149   TypeTextIntoTextField(10, EditableFormBegin());
1150 
1151   // Select left portion of string in user-editable combobox.
1152   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(142.0));
1153   CheckSelection(L"ABCDE");
1154 
1155   // Test replacing text selection with text to be inserted.
1156   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1157       GetFPDFWideString(L"Hello");
1158   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1159 
1160   // Select entire contents of user-editable combobox text field to check that
1161   // insertion worked as expected.
1162   SelectAllEditableFormTextWithMouse();
1163   CheckSelection(L"HelloFGHIJ");
1164 }
1165 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle)1166 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1167        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle) {
1168   TypeTextIntoTextField(10, EditableFormBegin());
1169 
1170   // Select middle portion of string in user-editable combobox.
1171   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(167.0));
1172   CheckSelection(L"DEFGH");
1173 
1174   // Test replacing text selection with text to be inserted.
1175   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1176       GetFPDFWideString(L"Hello");
1177   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1178 
1179   // Select entire contents of user-editable combobox text field to check that
1180   // insertion worked as expected.
1181   SelectAllEditableFormTextWithMouse();
1182   CheckSelection(L"ABCHelloIJ");
1183 }
1184 
TEST_F(FPDFFormFillComboBoxFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight)1185 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
1186        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight) {
1187   TypeTextIntoTextField(10, EditableFormBegin());
1188 
1189   // Select right portion of string in user-editable combobox.
1190   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormEnd());
1191   CheckSelection(L"FGHIJ");
1192 
1193   // Test replacing text selection with text to be inserted.
1194   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1195       GetFPDFWideString(L"Hello");
1196   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1197 
1198   // Select entire contents of user-editable combobox text field to check that
1199   // insertion worked as expected.
1200   SelectAllEditableFormTextWithMouse();
1201   CheckSelection(L"ABCDEHello");
1202 }
1203 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInEmptyCharLimitTextFieldOverflow)1204 TEST_F(FPDFFormFillTextFormEmbeddertest,
1205        InsertTextInEmptyCharLimitTextFieldOverflow) {
1206   // Click on the textfield.
1207   ClickOnFormFieldAtPoint(CharLimitFormEnd());
1208 
1209   // Delete pre-filled contents of text field with char limit.
1210   SelectAllCharLimitFormTextWithMouse();
1211   CheckSelection(L"Elephant");
1212   FORM_ReplaceSelection(form_handle(), page(), nullptr);
1213 
1214   // Test inserting text into now empty text field so text to be inserted
1215   // exceeds the char limit and is cut off.
1216   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1217       GetFPDFWideString(L"Hippopotamus");
1218   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1219 
1220   // Select entire contents of text field to check that insertion worked
1221   // as expected.
1222   SelectAllCharLimitFormTextWithMouse();
1223   CheckSelection(L"Hippopotam");
1224 }
1225 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInEmptyCharLimitTextFieldFit)1226 TEST_F(FPDFFormFillTextFormEmbeddertest,
1227        InsertTextInEmptyCharLimitTextFieldFit) {
1228   // Click on the textfield.
1229   ClickOnFormFieldAtPoint(CharLimitFormEnd());
1230 
1231   // Delete pre-filled contents of text field with char limit.
1232   SelectAllCharLimitFormTextWithMouse();
1233   CheckSelection(L"Elephant");
1234   FORM_ReplaceSelection(form_handle(), page(), nullptr);
1235 
1236   // Test inserting text into now empty text field so text to be inserted
1237   // exceeds the char limit and is cut off.
1238   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1239       GetFPDFWideString(L"Zebra");
1240   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1241 
1242   // Select entire contents of text field to check that insertion worked
1243   // as expected.
1244   SelectAllCharLimitFormTextWithMouse();
1245   CheckSelection(L"Zebra");
1246 }
1247 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInPopulatedCharLimitTextFieldLeft)1248 TEST_F(FPDFFormFillTextFormEmbeddertest,
1249        InsertTextInPopulatedCharLimitTextFieldLeft) {
1250   // Click on the leftmost part of the text field.
1251   ClickOnFormFieldAtPoint(CharLimitFormBegin());
1252 
1253   // Test inserting text in front of existing text in text field.
1254   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1255       GetFPDFWideString(L"Hippopotamus");
1256   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1257 
1258   // Select entire contents of text field to check that insertion worked
1259   // as expected.
1260   SelectAllCharLimitFormTextWithMouse();
1261   CheckSelection(L"HiElephant");
1262 }
1263 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInPopulatedCharLimitTextFieldMiddle)1264 TEST_F(FPDFFormFillTextFormEmbeddertest,
1265        InsertTextInPopulatedCharLimitTextFieldMiddle) {
1266   TypeTextIntoTextField(8, RegularFormBegin());
1267 
1268   // Click on the middle of the text field.
1269   ClickOnFormFieldAtPoint(CharLimitFormAtX(134.0));
1270 
1271   // Test inserting text in the middle of existing text in text field.
1272   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1273       GetFPDFWideString(L"Hippopotamus");
1274   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1275 
1276   // Select entire contents of text field to check that insertion worked
1277   // as expected.
1278   SelectAllCharLimitFormTextWithMouse();
1279   CheckSelection(L"ElephHiant");
1280 }
1281 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextInPopulatedCharLimitTextFieldRight)1282 TEST_F(FPDFFormFillTextFormEmbeddertest,
1283        InsertTextInPopulatedCharLimitTextFieldRight) {
1284   TypeTextIntoTextField(8, RegularFormBegin());
1285 
1286   // Click on the rightmost part of the text field.
1287   ClickOnFormFieldAtPoint(CharLimitFormAtX(166.0));
1288 
1289   // Test inserting text behind existing text in text field.
1290   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1291       GetFPDFWideString(L"Hippopotamus");
1292   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1293 
1294   // Select entire contents of text field to check that insertion worked
1295   // as expected.
1296   SelectAllCharLimitFormTextWithMouse();
1297   CheckSelection(L"ElephantHi");
1298 }
1299 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldWhole)1300 TEST_F(FPDFFormFillTextFormEmbeddertest,
1301        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldWhole) {
1302   TypeTextIntoTextField(12, RegularFormBegin());
1303 
1304   // Select entire string in text field.
1305   SelectTextWithKeyboard(12, FWL_VKEY_Left, CharLimitFormEnd());
1306   CheckSelection(L"Elephant");
1307 
1308   // Test replacing text selection with text to be inserted.
1309   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1310       GetFPDFWideString(L"Hippopotamus");
1311   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1312 
1313   // Select entire contents of text field to check that insertion worked
1314   // as expected.
1315   SelectAllCharLimitFormTextWithMouse();
1316   CheckSelection(L"Hippopotam");
1317 }
1318 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldLeft)1319 TEST_F(FPDFFormFillTextFormEmbeddertest,
1320        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldLeft) {
1321   TypeTextIntoTextField(12, RegularFormBegin());
1322 
1323   // Select left portion of string in text field.
1324   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(122.0));
1325   CheckSelection(L"Elep");
1326 
1327   // Test replacing text selection with text to be inserted.
1328   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1329       GetFPDFWideString(L"Hippopotamus");
1330   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1331 
1332   // Select entire contents of text field to check that insertion worked
1333   // as expected.
1334   SelectAllCharLimitFormTextWithMouse();
1335   CheckSelection(L"Hippophant");
1336 }
1337 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldMiddle)1338 TEST_F(FPDFFormFillTextFormEmbeddertest,
1339        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldMiddle) {
1340   TypeTextIntoTextField(12, RegularFormBegin());
1341 
1342   // Select middle portion of string in text field.
1343   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(136.0));
1344   CheckSelection(L"epha");
1345 
1346   // Test replacing text selection with text to be inserted.
1347   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1348       GetFPDFWideString(L"Hippopotamus");
1349   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1350 
1351   // Select entire contents of text field to check that insertion worked
1352   // as expected.
1353   SelectAllCharLimitFormTextWithMouse();
1354   CheckSelection(L"ElHippopnt");
1355 }
1356 
TEST_F(FPDFFormFillTextFormEmbeddertest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldRight)1357 TEST_F(FPDFFormFillTextFormEmbeddertest,
1358        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldRight) {
1359   TypeTextIntoTextField(12, RegularFormBegin());
1360 
1361   // Select right portion of string in text field.
1362   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(152.0));
1363   CheckSelection(L"hant");
1364 
1365   // Test replacing text selection with text to be inserted.
1366   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
1367       GetFPDFWideString(L"Hippopotamus");
1368   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
1369 
1370   // Select entire contents of text field to check that insertion worked
1371   // as expected.
1372   SelectAllCharLimitFormTextWithMouse();
1373   CheckSelection(L"ElepHippop");
1374 }
1375