• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_
8 #define FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_
9 
10 #include <stdint.h>
11 
12 #include <map>
13 #include <memory>
14 #include <set>
15 #include <utility>
16 #include <vector>
17 
18 #include "core/fpdfapi/page/cpdf_occontext.h"
19 #include "core/fpdfapi/parser/cpdf_document.h"
20 #include "core/fpdfdoc/cpdf_aaction.h"
21 #include "core/fxcrt/cfx_timer.h"
22 #include "core/fxcrt/mask.h"
23 #include "core/fxcrt/observed_ptr.h"
24 #include "core/fxcrt/retain_ptr.h"
25 #include "core/fxcrt/unowned_ptr.h"
26 #include "fpdfsdk/cpdfsdk_annot.h"
27 #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
28 #include "fpdfsdk/pwl/cpwl_wnd.h"
29 #include "fpdfsdk/pwl/ipwl_fillernotify.h"
30 #include "public/fpdf_formfill.h"
31 #include "third_party/base/span.h"
32 
33 class CPDF_Action;
34 class CPDF_FormField;
35 class CPDFSDK_InteractiveForm;
36 class CPDFSDK_PageView;
37 class IJS_EventContext;
38 class IJS_Runtime;
39 class IPDF_Page;
40 struct CFFL_FieldAction;
41 
42 // NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken
43 // since modifying the result would impact |bsUTF16LE|.
44 FPDF_WIDESTRING AsFPDFWideString(ByteString* bsUTF16LE);
45 
46 // The CPDFSDK_FormFillEnvironment is "owned" by the embedder across the
47 // C API as a FPDF_FormHandle, and may pop out of existence at any time,
48 // so long as the associated embedder-owned FPDF_Document outlives it.
49 // Pointers from objects in the FPDF_Document ownership hierarchy should
50 // be ObservedPtr<> so as to clear themselves when the embedder "exits"
51 // the form fill environment.  Pointers from objects in this ownership
52 // heirarcy to objects in the FPDF_Document ownership hierarcy should be
53 // UnownedPtr<>, as should pointers from objects in this ownership
54 // hierarcy back to the form fill environment itself, so as to flag any
55 // lingering lifetime issues via the memory tools.
56 
57 class CPDFSDK_FormFillEnvironment final
58     : public CFX_Timer::HandlerIface,
59       public CFFL_InteractiveFormFiller::CallbackIface {
60  public:
61   CPDFSDK_FormFillEnvironment(CPDF_Document* pDoc, FPDF_FORMFILLINFO* pFFinfo);
62 
63   ~CPDFSDK_FormFillEnvironment() override;
64 
65   // TimerHandlerIface:
66   int32_t SetTimer(int32_t uElapse, TimerCallback lpTimerFunc) override;
67   void KillTimer(int32_t nTimerID) override;
68 
69   // CFFL_InteractiveFormFiller::CallbackIface:
70   void InvalidateRect(CPDFSDK_Widget* widget,
71                       const CFX_FloatRect& rect) override;
72   void OutputSelectedRect(CFFL_FormField* pFormField,
73                           const CFX_FloatRect& rect) override;
74   bool IsSelectionImplemented() const override;
75   void SetCursor(IPWL_FillerNotify::CursorStyle nCursorType) override;
76   void OnSetFieldInputFocus(const WideString& text) override;
77   void OnCalculate(ObservedPtr<CPDFSDK_Annot>& pAnnot) override;
78   void OnFormat(ObservedPtr<CPDFSDK_Annot>& pAnnot) override;
79   void Invalidate(IPDF_Page* page, const FX_RECT& rect) override;
80   CPDFSDK_PageView* GetOrCreatePageView(IPDF_Page* pUnderlyingPage) override;
81   CPDFSDK_PageView* GetPageView(IPDF_Page* pUnderlyingPage) override;
82   CFX_Timer::HandlerIface* GetTimerHandler() override;
83   CPDFSDK_Annot* GetFocusAnnot() const override;
84   bool SetFocusAnnot(ObservedPtr<CPDFSDK_Annot>& pAnnot) override;
85   bool HasPermissions(uint32_t flags) const override;
86   void OnChange() override;
87 
88   CPDFSDK_PageView* GetPageViewAtIndex(int nIndex);
89   void RemovePageView(IPDF_Page* pUnderlyingPage);
90   void UpdateAllViews(CPDFSDK_Annot* pAnnot);
91 
92   bool KillFocusAnnot(Mask<FWL_EVENTFLAG> nFlags);
93   void ClearAllFocusedAnnots();
94 
95   int GetPageCount() const;
96 
GetChangeMark()97   bool GetChangeMark() const { return m_bChangeMask; }
SetChangeMark()98   void SetChangeMark() { m_bChangeMask = true; }
ClearChangeMark()99   void ClearChangeMark() { m_bChangeMask = false; }
100 
101   void ProcJavascriptAction();
102   bool ProcOpenAction();
103 
104   void ExecuteNamedAction(const ByteString& namedAction);
105   void DoURIAction(const ByteString& bsURI, Mask<FWL_EVENTFLAG> modifiers);
106   void DoGoToAction(int nPageIndex,
107                     int zoomMode,
108                     pdfium::span<float> fPosArray);
109 
GetPDFDocument()110   CPDF_Document* GetPDFDocument() const { return m_pCPDFDoc; }
GetDocExtension()111   CPDF_Document::Extension* GetDocExtension() const {
112     return m_pCPDFDoc->GetExtension();
113   }
114 
IsJSPlatformPresent()115   bool IsJSPlatformPresent() const { return m_pInfo && m_pInfo->m_pJsPlatform; }
GetJSPlatform()116   IPDF_JSPLATFORM* GetJSPlatform() const {
117     return m_pInfo ? m_pInfo->m_pJsPlatform : nullptr;
118   }
119 
120   // Actions.
121   bool DoActionDocOpen(const CPDF_Action& action);
122   bool DoActionJavaScript(const CPDF_Action& JsAction, WideString csJSName);
123   bool DoActionPage(const CPDF_Action& action, CPDF_AAction::AActionType eType);
124   bool DoActionDocument(const CPDF_Action& action,
125                         CPDF_AAction::AActionType eType);
126   bool DoActionField(const CPDF_Action& action,
127                      CPDF_AAction::AActionType type,
128                      CPDF_FormField* pFormField,
129                      CFFL_FieldAction* data);
130   bool DoActionFieldJavaScript(const CPDF_Action& JsAction,
131                                CPDF_AAction::AActionType type,
132                                CPDF_FormField* pFormField,
133                                CFFL_FieldAction* data);
134   bool DoActionLink(const CPDF_Action& action,
135                     CPDF_AAction::AActionType type,
136                     Mask<FWL_EVENTFLAG> modifiers);
137   bool DoActionDestination(const CPDF_Dest& dest);
138   void DoActionNoJs(const CPDF_Action& action, CPDF_AAction::AActionType type);
139   void DoActionGoTo(const CPDF_Action& action);
140   void DoActionLaunch(const CPDF_Action& action);
141   void DoActionURI(const CPDF_Action& action, Mask<FWL_EVENTFLAG> modifiers);
142   void DoActionNamed(const CPDF_Action& action);
143   bool DoActionHide(const CPDF_Action& action);
144   bool DoActionSubmitForm(const CPDF_Action& action);
145   void DoActionResetForm(const CPDF_Action& action);
146 
147 #ifdef PDF_ENABLE_V8
148   CPDFSDK_PageView* GetCurrentView();
149   IPDF_Page* GetCurrentPage() const;
150 
151   WideString GetLanguage();
152   WideString GetPlatform();
153 
154   int JS_appAlert(const WideString& Msg,
155                   const WideString& Title,
156                   int Type,
157                   int Icon);
158   int JS_appResponse(const WideString& Question,
159                      const WideString& Title,
160                      const WideString& Default,
161                      const WideString& cLabel,
162                      FPDF_BOOL bPassword,
163                      pdfium::span<uint8_t> response);
164   void JS_appBeep(int nType);
165   WideString JS_fieldBrowse();
166   void JS_docmailForm(pdfium::span<const uint8_t> mailData,
167                       FPDF_BOOL bUI,
168                       const WideString& To,
169                       const WideString& Subject,
170                       const WideString& CC,
171                       const WideString& BCC,
172                       const WideString& Msg);
173   void JS_docprint(FPDF_BOOL bUI,
174                    int nStart,
175                    int nEnd,
176                    FPDF_BOOL bSilent,
177                    FPDF_BOOL bShrinkToFit,
178                    FPDF_BOOL bPrintAsImage,
179                    FPDF_BOOL bReverse,
180                    FPDF_BOOL bAnnotations);
181   void JS_docgotoPage(int nPageNum);
182   WideString JS_docGetFilePath();
183 
184 #ifdef PDF_ENABLE_XFA
185   int GetPageViewCount() const;
186   void DisplayCaret(IPDF_Page* page,
187                     FPDF_BOOL bVisible,
188                     double left,
189                     double top,
190                     double right,
191                     double bottom);
192   int GetCurrentPageIndex() const;
193   void SetCurrentPage(int iCurPage);
194 
195   // TODO(dsinclair): This should probably change to PDFium?
FFI_GetAppName()196   WideString FFI_GetAppName() const { return WideString(L"Acrobat"); }
197 
198   void GotoURL(const WideString& wsURL);
199   FS_RECTF GetPageViewRect(IPDF_Page* page);
200   bool PopupMenu(IPDF_Page* page, int menuFlag, const CFX_PointF& pt);
201   void EmailTo(FPDF_FILEHANDLER* fileHandler,
202                FPDF_WIDESTRING pTo,
203                FPDF_WIDESTRING pSubject,
204                FPDF_WIDESTRING pCC,
205                FPDF_WIDESTRING pBcc,
206                FPDF_WIDESTRING pMsg);
207   void UploadTo(FPDF_FILEHANDLER* fileHandler,
208                 int fileFlag,
209                 FPDF_WIDESTRING uploadTo);
210   FPDF_FILEHANDLER* OpenFile(int fileType,
211                              FPDF_WIDESTRING wsURL,
212                              const char* mode);
213   RetainPtr<IFX_SeekableReadStream> DownloadFromURL(const WideString& url);
214   WideString PostRequestURL(const WideString& wsURL,
215                             const WideString& wsData,
216                             const WideString& wsContentType,
217                             const WideString& wsEncode,
218                             const WideString& wsHeader);
219   FPDF_BOOL PutRequestURL(const WideString& wsURL,
220                           const WideString& wsData,
221                           const WideString& wsEncode);
222 
223   void PageEvent(int iPageCount, uint32_t dwEventType) const;
224 #endif  // PDF_ENABLE_XFA
225 #endif  // PDF_ENABLE_V8
226 
227   WideString GetFilePath() const;
GetAppName()228   ByteString GetAppName() const { return ByteString(); }
GetFormFillInfo()229   FPDF_FORMFILLINFO* GetFormFillInfo() const { return m_pInfo; }
230   void SubmitForm(pdfium::span<const uint8_t> form_data, const WideString& URL);
231 
SetFocusableAnnotSubtypes(const std::vector<CPDF_Annot::Subtype> & focusableAnnotTypes)232   void SetFocusableAnnotSubtypes(
233       const std::vector<CPDF_Annot::Subtype>& focusableAnnotTypes) {
234     m_FocusableAnnotTypes = focusableAnnotTypes;
235   }
GetFocusableAnnotSubtypes()236   const std::vector<CPDF_Annot::Subtype>& GetFocusableAnnotSubtypes() const {
237     return m_FocusableAnnotTypes;
238   }
239 
240   // Never returns null.
GetInteractiveFormFiller()241   CFFL_InteractiveFormFiller* GetInteractiveFormFiller() {
242     return m_pInteractiveFormFiller.get();
243   }
244 
245   IJS_Runtime* GetIJSRuntime();                   // Creates if not present.
246   CPDFSDK_InteractiveForm* GetInteractiveForm();  // Creates if not present.
247 
248  private:
249   using RunScriptCallback = std::function<void(IJS_EventContext* context)>;
250 
251   IPDF_Page* GetPage(int nIndex) const;
252   void OnSetFieldInputFocusInternal(const WideString& text, bool bFocus);
253   void SendOnFocusChange(ObservedPtr<CPDFSDK_Annot>& pAnnot);
254 
255   // Support methods for Actions.
256   void RunScript(const WideString& script, const RunScriptCallback& cb);
257   bool ExecuteDocumentOpenAction(const CPDF_Action& action,
258                                  std::set<const CPDF_Dictionary*>* visited);
259   bool ExecuteDocumentPageAction(const CPDF_Action& action,
260                                  CPDF_AAction::AActionType type,
261                                  std::set<const CPDF_Dictionary*>* visited);
262   bool ExecuteFieldAction(const CPDF_Action& action,
263                           CPDF_AAction::AActionType type,
264                           CPDF_FormField* pFormField,
265                           CFFL_FieldAction* data,
266                           std::set<const CPDF_Dictionary*>* visited);
267   void RunDocumentPageJavaScript(CPDF_AAction::AActionType type,
268                                  const WideString& script);
269   void RunDocumentOpenJavaScript(const WideString& sScriptName,
270                                  const WideString& script);
271   void RunFieldJavaScript(CPDF_FormField* pFormField,
272                           CPDF_AAction::AActionType type,
273                           CFFL_FieldAction* data,
274                           const WideString& script);
275   bool IsValidField(const CPDF_Dictionary* pFieldDict);
276 
277   UnownedPtr<FPDF_FORMFILLINFO> const m_pInfo;
278   std::unique_ptr<IJS_Runtime> m_pIJSRuntime;
279 
280   // Iterator stability guarantees as provided by std::map<> required.
281   std::map<IPDF_Page*, std::unique_ptr<CPDFSDK_PageView>> m_PageMap;
282 
283   std::unique_ptr<CPDFSDK_InteractiveForm> m_pInteractiveForm;
284   ObservedPtr<CPDFSDK_Annot> m_pFocusAnnot;
285   UnownedPtr<CPDF_Document> const m_pCPDFDoc;
286   std::unique_ptr<CFFL_InteractiveFormFiller> m_pInteractiveFormFiller;
287   bool m_bChangeMask = false;
288   bool m_bBeingDestroyed = false;
289 
290   // Holds the list of focusable annot types.
291   // Annotations of type WIDGET are by default focusable.
292   std::vector<CPDF_Annot::Subtype> m_FocusableAnnotTypes = {
293       CPDF_Annot::Subtype::WIDGET};
294 };
295 
296 #endif  // FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_
297