1 // Copyright 2016 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
8
9 #include <memory>
10 #include <utility>
11 #include <vector>
12
13 #include "core/fpdfapi/parser/cpdf_array.h"
14 #include "core/fpdfapi/parser/cpdf_dictionary.h"
15 #include "core/fpdfdoc/cpdf_nametree.h"
16 #include "core/fxcrt/fx_memory_wrappers.h"
17 #include "fpdfsdk/cpdfsdk_actionhandler.h"
18 #include "fpdfsdk/cpdfsdk_annothandlermgr.h"
19 #include "fpdfsdk/cpdfsdk_helpers.h"
20 #include "fpdfsdk/cpdfsdk_interactiveform.h"
21 #include "fpdfsdk/cpdfsdk_pageview.h"
22 #include "fpdfsdk/cpdfsdk_widget.h"
23 #include "fpdfsdk/formfiller/cffl_formfiller.h"
24 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
25 #include "fxjs/ijs_runtime.h"
26 #include "third_party/base/ptr_util.h"
27 #include "third_party/base/stl_util.h"
28
AsFPDFWideString(ByteString * bsUTF16LE)29 FPDF_WIDESTRING AsFPDFWideString(ByteString* bsUTF16LE) {
30 // Force a private version of the string, since we're about to hand it off
31 // to the embedder. Should the embedder modify it by accident, it won't
32 // corrupt other shares of the string beyond |bsUTF16LE|.
33 return reinterpret_cast<FPDF_WIDESTRING>(
34 bsUTF16LE->GetBuffer(bsUTF16LE->GetLength()).data());
35 }
36
CPDFSDK_FormFillEnvironment(CPDF_Document * pDoc,FPDF_FORMFILLINFO * pFFinfo,std::unique_ptr<CPDFSDK_AnnotHandlerMgr> pHandlerMgr)37 CPDFSDK_FormFillEnvironment::CPDFSDK_FormFillEnvironment(
38 CPDF_Document* pDoc,
39 FPDF_FORMFILLINFO* pFFinfo,
40 std::unique_ptr<CPDFSDK_AnnotHandlerMgr> pHandlerMgr)
41 : m_pInfo(pFFinfo),
42 m_pCPDFDoc(pDoc),
43 m_pAnnotHandlerMgr(std::move(pHandlerMgr)) {
44 ASSERT(m_pCPDFDoc);
45 m_pAnnotHandlerMgr->SetFormFillEnv(this);
46 }
47
~CPDFSDK_FormFillEnvironment()48 CPDFSDK_FormFillEnvironment::~CPDFSDK_FormFillEnvironment() {
49 m_bBeingDestroyed = true;
50 ClearAllFocusedAnnots();
51
52 // |m_PageMap| will try to access |m_pInteractiveForm| when it cleans itself
53 // up. Make sure it is deleted before |m_pInteractiveForm|.
54 m_PageMap.clear();
55
56 // |m_pAnnotHandlerMgr| will try to access |m_pFormFiller| when it cleans
57 // itself up. Make sure it is deleted before |m_pFormFiller|.
58 m_pAnnotHandlerMgr.reset();
59
60 // Must destroy the |m_pFormFiller| before the environment (|this|)
61 // because any created form widgets hold a pointer to the environment.
62 // Those widgets may call things like KillTimer() as they are shutdown.
63 m_pFormFiller.reset();
64
65 if (m_pInfo && m_pInfo->Release)
66 m_pInfo->Release(m_pInfo);
67 }
68
InvalidateRect(PerWindowData * pWidgetData,const CFX_FloatRect & rect)69 void CPDFSDK_FormFillEnvironment::InvalidateRect(PerWindowData* pWidgetData,
70 const CFX_FloatRect& rect) {
71 auto* pPrivateData = static_cast<CFFL_PrivateData*>(pWidgetData);
72 CPDFSDK_Widget* widget = pPrivateData->pWidget.Get();
73 if (!widget)
74 return;
75
76 CPDFSDK_PageView* pPageView = widget->GetPageView();
77 IPDF_Page* pPage = widget->GetPage();
78 if (!pPage || !pPageView)
79 return;
80
81 CFX_Matrix device2page = pPageView->GetCurrentMatrix().GetInverse();
82 CFX_PointF left_top = device2page.Transform(CFX_PointF(rect.left, rect.top));
83 CFX_PointF right_bottom =
84 device2page.Transform(CFX_PointF(rect.right, rect.bottom));
85
86 CFX_FloatRect rcPDF(left_top.x, right_bottom.y, right_bottom.x, left_top.y);
87 rcPDF.Normalize();
88 Invalidate(pPage, rcPDF.GetOuterRect());
89 }
90
OutputSelectedRect(CFFL_FormFiller * pFormFiller,const CFX_FloatRect & rect)91 void CPDFSDK_FormFillEnvironment::OutputSelectedRect(
92 CFFL_FormFiller* pFormFiller,
93 const CFX_FloatRect& rect) {
94 if (!pFormFiller || !m_pInfo || !m_pInfo->FFI_OutputSelectedRect)
95 return;
96
97 auto* pPage = FPDFPageFromIPDFPage(pFormFiller->GetSDKAnnot()->GetPage());
98 ASSERT(pPage);
99
100 CFX_PointF ptA = pFormFiller->PWLtoFFL(CFX_PointF(rect.left, rect.bottom));
101 CFX_PointF ptB = pFormFiller->PWLtoFFL(CFX_PointF(rect.right, rect.top));
102 m_pInfo->FFI_OutputSelectedRect(m_pInfo, pPage, ptA.x, ptB.y, ptB.x, ptA.y);
103 }
104
IsSelectionImplemented() const105 bool CPDFSDK_FormFillEnvironment::IsSelectionImplemented() const {
106 FPDF_FORMFILLINFO* pInfo = GetFormFillInfo();
107 return pInfo && pInfo->FFI_OutputSelectedRect;
108 }
109
110 #ifdef PDF_ENABLE_V8
GetCurrentView()111 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetCurrentView() {
112 IPDF_Page* pPage = IPDFPageFromFPDFPage(GetCurrentPage());
113 return pPage ? GetPageView(pPage, true) : nullptr;
114 }
115
GetCurrentPage() const116 FPDF_PAGE CPDFSDK_FormFillEnvironment::GetCurrentPage() const {
117 if (m_pInfo && m_pInfo->FFI_GetCurrentPage) {
118 return m_pInfo->FFI_GetCurrentPage(
119 m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc.Get()));
120 }
121 return nullptr;
122 }
123
GetLanguage()124 WideString CPDFSDK_FormFillEnvironment::GetLanguage() {
125 #ifdef PDF_ENABLE_XFA
126 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetLanguage)
127 return WideString();
128
129 int nRequiredLen = m_pInfo->FFI_GetLanguage(m_pInfo, nullptr, 0);
130 if (nRequiredLen <= 0)
131 return WideString();
132
133 std::vector<uint8_t, FxAllocAllocator<uint8_t>> pBuff(nRequiredLen);
134 int nActualLen =
135 m_pInfo->FFI_GetLanguage(m_pInfo, pBuff.data(), nRequiredLen);
136 if (nActualLen <= 0 || nActualLen > nRequiredLen)
137 return WideString();
138
139 return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
140 nActualLen / sizeof(uint16_t));
141 #else // PDF_ENABLE_XFA
142 return WideString();
143 #endif // PDF_ENABLE_XFA
144 }
145
GetPlatform()146 WideString CPDFSDK_FormFillEnvironment::GetPlatform() {
147 #ifdef PDF_ENABLE_XFA
148 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetPlatform)
149 return WideString();
150
151 int nRequiredLen = m_pInfo->FFI_GetPlatform(m_pInfo, nullptr, 0);
152 if (nRequiredLen <= 0)
153 return WideString();
154
155 std::vector<uint8_t, FxAllocAllocator<uint8_t>> pBuff(nRequiredLen);
156 int nActualLen =
157 m_pInfo->FFI_GetPlatform(m_pInfo, pBuff.data(), nRequiredLen);
158 if (nActualLen <= 0 || nActualLen > nRequiredLen)
159 return WideString();
160
161 return WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.data()),
162 nActualLen / sizeof(uint16_t));
163 #else // PDF_ENABLE_XFA
164 return WideString();
165 #endif // PDF_ENABLE_XFA
166 }
167
JS_appAlert(const WideString & Msg,const WideString & Title,int Type,int Icon)168 int CPDFSDK_FormFillEnvironment::JS_appAlert(const WideString& Msg,
169 const WideString& Title,
170 int Type,
171 int Icon) {
172 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
173 !m_pInfo->m_pJsPlatform->app_alert) {
174 return -1;
175 }
176
177 ByteString bsMsg = Msg.ToUTF16LE();
178 ByteString bsTitle = Title.ToUTF16LE();
179 return m_pInfo->m_pJsPlatform->app_alert(
180 m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsMsg),
181 AsFPDFWideString(&bsTitle), Type, Icon);
182 }
183
JS_appResponse(const WideString & Question,const WideString & Title,const WideString & Default,const WideString & Label,FPDF_BOOL bPassword,void * response,int length)184 int CPDFSDK_FormFillEnvironment::JS_appResponse(const WideString& Question,
185 const WideString& Title,
186 const WideString& Default,
187 const WideString& Label,
188 FPDF_BOOL bPassword,
189 void* response,
190 int length) {
191 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
192 !m_pInfo->m_pJsPlatform->app_response) {
193 return -1;
194 }
195 ByteString bsQuestion = Question.ToUTF16LE();
196 ByteString bsTitle = Title.ToUTF16LE();
197 ByteString bsDefault = Default.ToUTF16LE();
198 ByteString bsLabel = Label.ToUTF16LE();
199 return m_pInfo->m_pJsPlatform->app_response(
200 m_pInfo->m_pJsPlatform, AsFPDFWideString(&bsQuestion),
201 AsFPDFWideString(&bsTitle), AsFPDFWideString(&bsDefault),
202 AsFPDFWideString(&bsLabel), bPassword, response, length);
203 }
204
JS_appBeep(int nType)205 void CPDFSDK_FormFillEnvironment::JS_appBeep(int nType) {
206 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
207 !m_pInfo->m_pJsPlatform->app_beep) {
208 return;
209 }
210 m_pInfo->m_pJsPlatform->app_beep(m_pInfo->m_pJsPlatform, nType);
211 }
212
JS_fieldBrowse()213 WideString CPDFSDK_FormFillEnvironment::JS_fieldBrowse() {
214 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
215 !m_pInfo->m_pJsPlatform->Field_browse) {
216 return WideString();
217 }
218 const int nRequiredLen =
219 m_pInfo->m_pJsPlatform->Field_browse(m_pInfo->m_pJsPlatform, nullptr, 0);
220 if (nRequiredLen <= 0)
221 return WideString();
222
223 std::vector<uint8_t, FxAllocAllocator<uint8_t>> pBuff(nRequiredLen);
224 const int nActualLen = m_pInfo->m_pJsPlatform->Field_browse(
225 m_pInfo->m_pJsPlatform, pBuff.data(), nRequiredLen);
226 if (nActualLen <= 0 || nActualLen > nRequiredLen)
227 return WideString();
228
229 // Don't include trailing NUL.
230 pBuff.resize(nActualLen - 1);
231 return WideString::FromDefANSI(ByteStringView(pBuff));
232 }
233
JS_docmailForm(void * mailData,int length,FPDF_BOOL bUI,const WideString & To,const WideString & Subject,const WideString & CC,const WideString & BCC,const WideString & Msg)234 void CPDFSDK_FormFillEnvironment::JS_docmailForm(void* mailData,
235 int length,
236 FPDF_BOOL bUI,
237 const WideString& To,
238 const WideString& Subject,
239 const WideString& CC,
240 const WideString& BCC,
241 const WideString& Msg) {
242 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
243 !m_pInfo->m_pJsPlatform->Doc_mail) {
244 return;
245 }
246 ByteString bsTo = To.ToUTF16LE();
247 ByteString bsSubject = Subject.ToUTF16LE();
248 ByteString bsCC = CC.ToUTF16LE();
249 ByteString bsBcc = BCC.ToUTF16LE();
250 ByteString bsMsg = Msg.ToUTF16LE();
251 m_pInfo->m_pJsPlatform->Doc_mail(
252 m_pInfo->m_pJsPlatform, mailData, length, bUI, AsFPDFWideString(&bsTo),
253 AsFPDFWideString(&bsSubject), AsFPDFWideString(&bsCC),
254 AsFPDFWideString(&bsBcc), AsFPDFWideString(&bsMsg));
255 }
256
JS_docprint(FPDF_BOOL bUI,int nStart,int nEnd,FPDF_BOOL bSilent,FPDF_BOOL bShrinkToFit,FPDF_BOOL bPrintAsImage,FPDF_BOOL bReverse,FPDF_BOOL bAnnotations)257 void CPDFSDK_FormFillEnvironment::JS_docprint(FPDF_BOOL bUI,
258 int nStart,
259 int nEnd,
260 FPDF_BOOL bSilent,
261 FPDF_BOOL bShrinkToFit,
262 FPDF_BOOL bPrintAsImage,
263 FPDF_BOOL bReverse,
264 FPDF_BOOL bAnnotations) {
265 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
266 !m_pInfo->m_pJsPlatform->Doc_print) {
267 return;
268 }
269 m_pInfo->m_pJsPlatform->Doc_print(m_pInfo->m_pJsPlatform, bUI, nStart, nEnd,
270 bSilent, bShrinkToFit, bPrintAsImage,
271 bReverse, bAnnotations);
272 }
273
JS_docgotoPage(int nPageNum)274 void CPDFSDK_FormFillEnvironment::JS_docgotoPage(int nPageNum) {
275 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
276 !m_pInfo->m_pJsPlatform->Doc_gotoPage) {
277 return;
278 }
279 m_pInfo->m_pJsPlatform->Doc_gotoPage(m_pInfo->m_pJsPlatform, nPageNum);
280 }
281
JS_docGetFilePath()282 WideString CPDFSDK_FormFillEnvironment::JS_docGetFilePath() {
283 return GetFilePath();
284 }
285 #endif // PDF_ENABLE_V8
286
GetFilePath() const287 WideString CPDFSDK_FormFillEnvironment::GetFilePath() const {
288 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
289 !m_pInfo->m_pJsPlatform->Doc_getFilePath) {
290 return WideString();
291 }
292 const int nRequiredLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
293 m_pInfo->m_pJsPlatform, nullptr, 0);
294 if (nRequiredLen <= 0)
295 return WideString();
296
297 std::vector<uint8_t, FxAllocAllocator<uint8_t>> pBuff(nRequiredLen);
298 const int nActualLen = m_pInfo->m_pJsPlatform->Doc_getFilePath(
299 m_pInfo->m_pJsPlatform, pBuff.data(), nRequiredLen);
300 if (nActualLen <= 0 || nActualLen > nRequiredLen)
301 return WideString();
302
303 // Don't include trailing NUL.
304 pBuff.resize(nActualLen - 1);
305 return WideString::FromDefANSI(ByteStringView(pBuff));
306 }
307
SubmitForm(pdfium::span<uint8_t> form_data,const WideString & URL)308 void CPDFSDK_FormFillEnvironment::SubmitForm(pdfium::span<uint8_t> form_data,
309 const WideString& URL) {
310 if (!m_pInfo || !m_pInfo->m_pJsPlatform ||
311 !m_pInfo->m_pJsPlatform->Doc_submitForm) {
312 return;
313 }
314 ByteString bsUrl = URL.ToUTF16LE();
315 m_pInfo->m_pJsPlatform->Doc_submitForm(m_pInfo->m_pJsPlatform,
316 form_data.data(), form_data.size(),
317 AsFPDFWideString(&bsUrl));
318 }
319
GetIJSRuntime()320 IJS_Runtime* CPDFSDK_FormFillEnvironment::GetIJSRuntime() {
321 if (!m_pIJSRuntime)
322 m_pIJSRuntime = IJS_Runtime::Create(this);
323 return m_pIJSRuntime.get();
324 }
325
GetAnnotHandlerMgr()326 CPDFSDK_AnnotHandlerMgr* CPDFSDK_FormFillEnvironment::GetAnnotHandlerMgr() {
327 return m_pAnnotHandlerMgr.get();
328 }
329
GetActionHandler()330 CPDFSDK_ActionHandler* CPDFSDK_FormFillEnvironment::GetActionHandler() {
331 if (!m_pActionHandler)
332 m_pActionHandler = pdfium::MakeUnique<CPDFSDK_ActionHandler>();
333 return m_pActionHandler.get();
334 }
335
336 CFFL_InteractiveFormFiller*
GetInteractiveFormFiller()337 CPDFSDK_FormFillEnvironment::GetInteractiveFormFiller() {
338 if (!m_pFormFiller)
339 m_pFormFiller = pdfium::MakeUnique<CFFL_InteractiveFormFiller>(this);
340 return m_pFormFiller.get();
341 }
342
Invalidate(IPDF_Page * page,const FX_RECT & rect)343 void CPDFSDK_FormFillEnvironment::Invalidate(IPDF_Page* page,
344 const FX_RECT& rect) {
345 if (m_pInfo && m_pInfo->FFI_Invalidate) {
346 m_pInfo->FFI_Invalidate(m_pInfo, FPDFPageFromIPDFPage(page), rect.left,
347 rect.top, rect.right, rect.bottom);
348 }
349 }
350
SetCursor(int nCursorType)351 void CPDFSDK_FormFillEnvironment::SetCursor(int nCursorType) {
352 if (m_pInfo && m_pInfo->FFI_SetCursor)
353 m_pInfo->FFI_SetCursor(m_pInfo, nCursorType);
354 }
355
SetTimer(int uElapse,TimerCallback lpTimerFunc)356 int CPDFSDK_FormFillEnvironment::SetTimer(int uElapse,
357 TimerCallback lpTimerFunc) {
358 if (m_pInfo && m_pInfo->FFI_SetTimer)
359 return m_pInfo->FFI_SetTimer(m_pInfo, uElapse, lpTimerFunc);
360 return TimerHandlerIface::kInvalidTimerID;
361 }
362
KillTimer(int nTimerID)363 void CPDFSDK_FormFillEnvironment::KillTimer(int nTimerID) {
364 if (m_pInfo && m_pInfo->FFI_KillTimer)
365 m_pInfo->FFI_KillTimer(m_pInfo, nTimerID);
366 }
367
OnChange()368 void CPDFSDK_FormFillEnvironment::OnChange() {
369 if (m_pInfo && m_pInfo->FFI_OnChange)
370 m_pInfo->FFI_OnChange(m_pInfo);
371 }
372
ExecuteNamedAction(const char * namedAction)373 void CPDFSDK_FormFillEnvironment::ExecuteNamedAction(const char* namedAction) {
374 if (m_pInfo && m_pInfo->FFI_ExecuteNamedAction)
375 m_pInfo->FFI_ExecuteNamedAction(m_pInfo, namedAction);
376 }
377
OnSetFieldInputFocus(FPDF_WIDESTRING focusText,FPDF_DWORD nTextLen,bool bFocus)378 void CPDFSDK_FormFillEnvironment::OnSetFieldInputFocus(
379 FPDF_WIDESTRING focusText,
380 FPDF_DWORD nTextLen,
381 bool bFocus) {
382 if (m_pInfo && m_pInfo->FFI_SetTextFieldFocus)
383 m_pInfo->FFI_SetTextFieldFocus(m_pInfo, focusText, nTextLen, bFocus);
384 }
385
DoURIAction(const char * bsURI)386 void CPDFSDK_FormFillEnvironment::DoURIAction(const char* bsURI) {
387 if (m_pInfo && m_pInfo->FFI_DoURIAction)
388 m_pInfo->FFI_DoURIAction(m_pInfo, bsURI);
389 }
390
DoGoToAction(int nPageIndex,int zoomMode,float * fPosArray,int sizeOfArray)391 void CPDFSDK_FormFillEnvironment::DoGoToAction(int nPageIndex,
392 int zoomMode,
393 float* fPosArray,
394 int sizeOfArray) {
395 if (m_pInfo && m_pInfo->FFI_DoGoToAction) {
396 m_pInfo->FFI_DoGoToAction(m_pInfo, nPageIndex, zoomMode, fPosArray,
397 sizeOfArray);
398 }
399 }
400
401 #ifdef PDF_ENABLE_XFA
GetPageViewCount() const402 int CPDFSDK_FormFillEnvironment::GetPageViewCount() const {
403 return pdfium::CollectionSize<int>(m_PageMap);
404 }
405
DisplayCaret(IPDF_Page * page,FPDF_BOOL bVisible,double left,double top,double right,double bottom)406 void CPDFSDK_FormFillEnvironment::DisplayCaret(IPDF_Page* page,
407 FPDF_BOOL bVisible,
408 double left,
409 double top,
410 double right,
411 double bottom) {
412 if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_DisplayCaret) {
413 m_pInfo->FFI_DisplayCaret(m_pInfo, FPDFPageFromIPDFPage(page), bVisible,
414 left, top, right, bottom);
415 }
416 }
417
GetCurrentPageIndex() const418 int CPDFSDK_FormFillEnvironment::GetCurrentPageIndex() const {
419 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetCurrentPageIndex)
420 return -1;
421 return m_pInfo->FFI_GetCurrentPageIndex(
422 m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc.Get()));
423 }
424
SetCurrentPage(int iCurPage)425 void CPDFSDK_FormFillEnvironment::SetCurrentPage(int iCurPage) {
426 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_SetCurrentPage)
427 return;
428 m_pInfo->FFI_SetCurrentPage(
429 m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc.Get()), iCurPage);
430 }
431
GotoURL(const WideString & wsURL)432 void CPDFSDK_FormFillEnvironment::GotoURL(const WideString& wsURL) {
433 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GotoURL)
434 return;
435
436 ByteString bsTo = wsURL.ToUTF16LE();
437 m_pInfo->FFI_GotoURL(m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc.Get()),
438 AsFPDFWideString(&bsTo));
439 }
440
GetPageViewRect(IPDF_Page * page)441 FS_RECTF CPDFSDK_FormFillEnvironment::GetPageViewRect(IPDF_Page* page) {
442 FS_RECTF rect = {0.0f, 0.0f, 0.0f, 0.0f};
443 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_GetPageViewRect)
444 return rect;
445
446 double left;
447 double top;
448 double right;
449 double bottom;
450 m_pInfo->FFI_GetPageViewRect(m_pInfo, FPDFPageFromIPDFPage(page), &left, &top,
451 &right, &bottom);
452
453 rect.left = static_cast<float>(left);
454 rect.top = static_cast<float>(top);
455 rect.bottom = static_cast<float>(bottom);
456 rect.right = static_cast<float>(right);
457 return rect;
458 }
459
PopupMenu(IPDF_Page * page,FPDF_WIDGET hWidget,int menuFlag,const CFX_PointF & pt)460 bool CPDFSDK_FormFillEnvironment::PopupMenu(IPDF_Page* page,
461 FPDF_WIDGET hWidget,
462 int menuFlag,
463 const CFX_PointF& pt) {
464 return m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_PopupMenu &&
465 m_pInfo->FFI_PopupMenu(m_pInfo, FPDFPageFromIPDFPage(page), hWidget,
466 menuFlag, pt.x, pt.y);
467 }
468
EmailTo(FPDF_FILEHANDLER * fileHandler,FPDF_WIDESTRING pTo,FPDF_WIDESTRING pSubject,FPDF_WIDESTRING pCC,FPDF_WIDESTRING pBcc,FPDF_WIDESTRING pMsg)469 void CPDFSDK_FormFillEnvironment::EmailTo(FPDF_FILEHANDLER* fileHandler,
470 FPDF_WIDESTRING pTo,
471 FPDF_WIDESTRING pSubject,
472 FPDF_WIDESTRING pCC,
473 FPDF_WIDESTRING pBcc,
474 FPDF_WIDESTRING pMsg) {
475 if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_EmailTo)
476 m_pInfo->FFI_EmailTo(m_pInfo, fileHandler, pTo, pSubject, pCC, pBcc, pMsg);
477 }
478
UploadTo(FPDF_FILEHANDLER * fileHandler,int fileFlag,FPDF_WIDESTRING uploadTo)479 void CPDFSDK_FormFillEnvironment::UploadTo(FPDF_FILEHANDLER* fileHandler,
480 int fileFlag,
481 FPDF_WIDESTRING uploadTo) {
482 if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_UploadTo)
483 m_pInfo->FFI_UploadTo(m_pInfo, fileHandler, fileFlag, uploadTo);
484 }
485
OpenFile(int fileType,FPDF_WIDESTRING wsURL,const char * mode)486 FPDF_FILEHANDLER* CPDFSDK_FormFillEnvironment::OpenFile(int fileType,
487 FPDF_WIDESTRING wsURL,
488 const char* mode) {
489 if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_OpenFile)
490 return m_pInfo->FFI_OpenFile(m_pInfo, fileType, wsURL, mode);
491 return nullptr;
492 }
493
DownloadFromURL(const WideString & url)494 RetainPtr<IFX_SeekableReadStream> CPDFSDK_FormFillEnvironment::DownloadFromURL(
495 const WideString& url) {
496 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_DownloadFromURL)
497 return nullptr;
498
499 ByteString bstrURL = url.ToUTF16LE();
500 FPDF_FILEHANDLER* fileHandler =
501 m_pInfo->FFI_DownloadFromURL(m_pInfo, AsFPDFWideString(&bstrURL));
502
503 return MakeSeekableStream(fileHandler);
504 }
505
PostRequestURL(const WideString & wsURL,const WideString & wsData,const WideString & wsContentType,const WideString & wsEncode,const WideString & wsHeader)506 WideString CPDFSDK_FormFillEnvironment::PostRequestURL(
507 const WideString& wsURL,
508 const WideString& wsData,
509 const WideString& wsContentType,
510 const WideString& wsEncode,
511 const WideString& wsHeader) {
512 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_PostRequestURL)
513 return WideString();
514
515 ByteString bsURL = wsURL.ToUTF16LE();
516 ByteString bsData = wsData.ToUTF16LE();
517 ByteString bsContentType = wsContentType.ToUTF16LE();
518 ByteString bsEncode = wsEncode.ToUTF16LE();
519 ByteString bsHeader = wsHeader.ToUTF16LE();
520
521 FPDF_BSTR response;
522 FPDF_BStr_Init(&response);
523 m_pInfo->FFI_PostRequestURL(
524 m_pInfo, AsFPDFWideString(&bsURL), AsFPDFWideString(&bsData),
525 AsFPDFWideString(&bsContentType), AsFPDFWideString(&bsEncode),
526 AsFPDFWideString(&bsHeader), &response);
527
528 WideString wsRet =
529 WideString::FromUTF16LE(reinterpret_cast<FPDF_WIDESTRING>(response.str),
530 response.len / sizeof(FPDF_WIDESTRING));
531
532 FPDF_BStr_Clear(&response);
533 return wsRet;
534 }
535
PutRequestURL(const WideString & wsURL,const WideString & wsData,const WideString & wsEncode)536 FPDF_BOOL CPDFSDK_FormFillEnvironment::PutRequestURL(
537 const WideString& wsURL,
538 const WideString& wsData,
539 const WideString& wsEncode) {
540 if (!m_pInfo || m_pInfo->version < 2 || !m_pInfo->FFI_PutRequestURL)
541 return false;
542
543 ByteString bsURL = wsURL.ToUTF16LE();
544 ByteString bsData = wsData.ToUTF16LE();
545 ByteString bsEncode = wsEncode.ToUTF16LE();
546
547 return m_pInfo->FFI_PutRequestURL(m_pInfo, AsFPDFWideString(&bsURL),
548 AsFPDFWideString(&bsData),
549 AsFPDFWideString(&bsEncode));
550 }
551
PageEvent(int iPageCount,uint32_t dwEventType) const552 void CPDFSDK_FormFillEnvironment::PageEvent(int iPageCount,
553 uint32_t dwEventType) const {
554 if (m_pInfo && m_pInfo->version >= 2 && m_pInfo->FFI_PageEvent)
555 m_pInfo->FFI_PageEvent(m_pInfo, iPageCount, dwEventType);
556 }
557 #endif // PDF_ENABLE_XFA
558
ClearAllFocusedAnnots()559 void CPDFSDK_FormFillEnvironment::ClearAllFocusedAnnots() {
560 for (auto& it : m_PageMap) {
561 if (it.second->IsValidSDKAnnot(GetFocusAnnot()))
562 KillFocusAnnot(0);
563 }
564 }
565
GetPageView(IPDF_Page * pUnderlyingPage,bool renew)566 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(
567 IPDF_Page* pUnderlyingPage,
568 bool renew) {
569 auto it = m_PageMap.find(pUnderlyingPage);
570 if (it != m_PageMap.end())
571 return it->second.get();
572
573 if (!renew)
574 return nullptr;
575
576 auto pNew = pdfium::MakeUnique<CPDFSDK_PageView>(this, pUnderlyingPage);
577 CPDFSDK_PageView* pPageView = pNew.get();
578 m_PageMap[pUnderlyingPage] = std::move(pNew);
579
580 // Delay to load all the annotations, to avoid endless loop.
581 pPageView->LoadFXAnnots();
582 return pPageView;
583 }
584
GetPageView(int nIndex)585 CPDFSDK_PageView* CPDFSDK_FormFillEnvironment::GetPageView(int nIndex) {
586 IPDF_Page* pTempPage = GetPage(nIndex);
587 if (!pTempPage)
588 return nullptr;
589
590 auto it = m_PageMap.find(pTempPage);
591 return it != m_PageMap.end() ? it->second.get() : nullptr;
592 }
593
ProcJavascriptAction()594 void CPDFSDK_FormFillEnvironment::ProcJavascriptAction() {
595 CPDF_NameTree docJS(m_pCPDFDoc.Get(), "JavaScript");
596 int iCount = docJS.GetCount();
597 for (int i = 0; i < iCount; i++) {
598 WideString name;
599 CPDF_Action action(ToDictionary(docJS.LookupValueAndName(i, &name)));
600 GetActionHandler()->DoAction_JavaScript(action, name, this);
601 }
602 }
603
ProcOpenAction()604 bool CPDFSDK_FormFillEnvironment::ProcOpenAction() {
605 CPDF_Dictionary* pRoot = m_pCPDFDoc->GetRoot();
606 if (!pRoot)
607 return false;
608
609 CPDF_Object* pOpenAction = pRoot->GetDictFor("OpenAction");
610 if (!pOpenAction)
611 pOpenAction = pRoot->GetArrayFor("OpenAction");
612 if (!pOpenAction)
613 return false;
614
615 if (pOpenAction->IsArray())
616 return true;
617
618 CPDF_Dictionary* pDict = pOpenAction->AsDictionary();
619 if (!pDict)
620 return false;
621
622 CPDF_Action action(pDict);
623 GetActionHandler()->DoAction_DocOpen(action, this);
624 return true;
625 }
626
RemovePageView(IPDF_Page * pUnderlyingPage)627 void CPDFSDK_FormFillEnvironment::RemovePageView(IPDF_Page* pUnderlyingPage) {
628 auto it = m_PageMap.find(pUnderlyingPage);
629 if (it == m_PageMap.end())
630 return;
631
632 CPDFSDK_PageView* pPageView = it->second.get();
633 if (pPageView->IsLocked() || pPageView->IsBeingDestroyed())
634 return;
635
636 // Mark the page view so we do not come into |RemovePageView| a second
637 // time while we're in the process of removing.
638 pPageView->SetBeingDestroyed();
639
640 // This must happen before we remove |pPageView| from the map because
641 // |KillFocusAnnot| can call into the |GetPage| method which will
642 // look for this page view in the map, if it doesn't find it a new one will
643 // be created. We then have two page views pointing to the same page and
644 // bad things happen.
645 if (pPageView->IsValidSDKAnnot(GetFocusAnnot()))
646 KillFocusAnnot(0);
647
648 // Remove the page from the map to make sure we don't accidentally attempt
649 // to use the |pPageView| while we're cleaning it up.
650 m_PageMap.erase(it);
651 }
652
GetPage(int nIndex)653 IPDF_Page* CPDFSDK_FormFillEnvironment::GetPage(int nIndex) {
654 if (!m_pInfo || !m_pInfo->FFI_GetPage)
655 return nullptr;
656 return IPDFPageFromFPDFPage(m_pInfo->FFI_GetPage(
657 m_pInfo, FPDFDocumentFromCPDFDocument(m_pCPDFDoc.Get()), nIndex));
658 }
659
GetInteractiveForm()660 CPDFSDK_InteractiveForm* CPDFSDK_FormFillEnvironment::GetInteractiveForm() {
661 if (!m_pInteractiveForm)
662 m_pInteractiveForm = pdfium::MakeUnique<CPDFSDK_InteractiveForm>(this);
663 return m_pInteractiveForm.get();
664 }
665
UpdateAllViews(CPDFSDK_PageView * pSender,CPDFSDK_Annot * pAnnot)666 void CPDFSDK_FormFillEnvironment::UpdateAllViews(CPDFSDK_PageView* pSender,
667 CPDFSDK_Annot* pAnnot) {
668 for (const auto& it : m_PageMap) {
669 CPDFSDK_PageView* pPageView = it.second.get();
670 if (pPageView != pSender)
671 pPageView->UpdateView(pAnnot);
672 }
673 }
674
SetFocusAnnot(ObservedPtr<CPDFSDK_Annot> * pAnnot)675 bool CPDFSDK_FormFillEnvironment::SetFocusAnnot(
676 ObservedPtr<CPDFSDK_Annot>* pAnnot) {
677 if (m_bBeingDestroyed)
678 return false;
679 if (m_pFocusAnnot == *pAnnot)
680 return true;
681 if (m_pFocusAnnot && !KillFocusAnnot(0))
682 return false;
683 if (!pAnnot->HasObservable())
684 return false;
685
686 CPDFSDK_PageView* pPageView = (*pAnnot)->GetPageView();
687 if (!pPageView || !pPageView->IsValid())
688 return false;
689
690 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
691 if (m_pFocusAnnot)
692 return false;
693
694 #ifdef PDF_ENABLE_XFA
695 ObservedPtr<CPDFSDK_Annot> pLastFocusAnnot(m_pFocusAnnot.Get());
696 if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot, &pLastFocusAnnot))
697 return false;
698
699 // |pAnnot| may be destroyed in |Annot_OnChangeFocus|.
700 if (!pAnnot->HasObservable())
701 return false;
702 #endif // PDF_ENABLE_XFA
703 if (!pAnnotHandler->Annot_OnSetFocus(pAnnot, 0))
704 return false;
705 if (m_pFocusAnnot)
706 return false;
707
708 m_pFocusAnnot.Reset(pAnnot->Get());
709 return true;
710 }
711
KillFocusAnnot(uint32_t nFlag)712 bool CPDFSDK_FormFillEnvironment::KillFocusAnnot(uint32_t nFlag) {
713 if (!m_pFocusAnnot)
714 return false;
715
716 CPDFSDK_AnnotHandlerMgr* pAnnotHandler = GetAnnotHandlerMgr();
717 ObservedPtr<CPDFSDK_Annot> pFocusAnnot(m_pFocusAnnot.Get());
718 m_pFocusAnnot.Reset();
719
720 #ifdef PDF_ENABLE_XFA
721 ObservedPtr<CPDFSDK_Annot> pNull;
722 if (!pAnnotHandler->Annot_OnChangeFocus(&pNull, &pFocusAnnot))
723 return false;
724 #endif // PDF_ENABLE_XFA
725
726 if (!pAnnotHandler->Annot_OnKillFocus(&pFocusAnnot, nFlag)) {
727 m_pFocusAnnot.Reset(pFocusAnnot.Get());
728 return false;
729 }
730
731 if (pFocusAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::WIDGET) {
732 CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pFocusAnnot.Get());
733 FormFieldType fieldType = pWidget->GetFieldType();
734 if (fieldType == FormFieldType::kTextField ||
735 fieldType == FormFieldType::kComboBox) {
736 OnSetFieldInputFocus(nullptr, 0, false);
737 }
738 }
739 return !m_pFocusAnnot;
740 }
741
GetPageCount() const742 int CPDFSDK_FormFillEnvironment::GetPageCount() const {
743 CPDF_Document::Extension* pExtension = m_pCPDFDoc->GetExtension();
744 return pExtension ? pExtension->GetPageCount() : m_pCPDFDoc->GetPageCount();
745 }
746
GetPermissions(int nFlag) const747 bool CPDFSDK_FormFillEnvironment::GetPermissions(int nFlag) const {
748 return !!(m_pCPDFDoc->GetUserPermissions() & nFlag);
749 }
750