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