1 // Copyright 2014 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/include/fsdk_define.h"
8 #include "fpdfsdk/include/fsdk_mgr.h"
9 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
10 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_util.h"
11 #include "fpdfsdk/include/javascript/IJavaScript.h"
12 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h"
13 #include "public/fpdf_formfill.h"
14 
15 CPDFXFA_App* CPDFXFA_App::g_pApp = NULL;
16 
GetInstance()17 CPDFXFA_App* CPDFXFA_App::GetInstance() {
18   if (!g_pApp) {
19     g_pApp = new CPDFXFA_App();
20   }
21   return g_pApp;
22 }
23 
ReleaseInstance()24 void CPDFXFA_App::ReleaseInstance() {
25   delete g_pApp;
26   g_pApp = NULL;
27 }
28 
CPDFXFA_App()29 CPDFXFA_App::CPDFXFA_App()
30     : m_bJavaScriptInitialized(FALSE),
31       m_pXFAApp(NULL),
32       m_pFontMgr(NULL),
33       m_hJSERuntime(NULL),
34       m_csAppType(JS_STR_VIEWERTYPE_STANDARD) {
35   m_pEnvList.RemoveAll();
36 }
37 
~CPDFXFA_App()38 CPDFXFA_App::~CPDFXFA_App() {
39   delete m_pFontMgr;
40   m_pFontMgr = NULL;
41 
42   delete m_pXFAApp;
43   m_pXFAApp = NULL;
44 
45 #ifdef PDF_ENABLE_XFA
46   FXJSE_Runtime_Release(m_hJSERuntime);
47   m_hJSERuntime = NULL;
48 
49   FXJSE_Finalize();
50   BC_Library_Destory();
51 #endif
52 }
53 
Initialize()54 FX_BOOL CPDFXFA_App::Initialize() {
55 #ifdef PDF_ENABLE_XFA
56   BC_Library_Init();
57   FXJSE_Initialize();
58 
59   m_hJSERuntime = FXJSE_Runtime_Create();
60   if (!m_hJSERuntime)
61     return FALSE;
62 
63   m_pXFAApp = IXFA_App::Create(this);
64   if (!m_pXFAApp)
65     return FALSE;
66 
67   m_pFontMgr = IXFA_FontMgr::CreateDefault();
68   if (!m_pFontMgr)
69     return FALSE;
70 
71   m_pXFAApp->SetDefaultFontMgr(m_pFontMgr);
72 #endif
73   return TRUE;
74 }
75 
AddFormFillEnv(CPDFDoc_Environment * pEnv)76 FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv) {
77   if (!pEnv)
78     return FALSE;
79 
80   m_pEnvList.Add(pEnv);
81   return TRUE;
82 }
83 
RemoveFormFillEnv(CPDFDoc_Environment * pEnv)84 FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv) {
85   if (!pEnv)
86     return FALSE;
87 
88   int nFind = m_pEnvList.Find(pEnv);
89   if (nFind != -1) {
90     m_pEnvList.RemoveAt(nFind);
91     return TRUE;
92   }
93 
94   return FALSE;
95 }
96 
GetAppType(CFX_WideString & wsAppType)97 void CPDFXFA_App::GetAppType(CFX_WideString& wsAppType) {
98   wsAppType = m_csAppType;
99 }
100 
GetAppName(CFX_WideString & wsName)101 void CPDFXFA_App::GetAppName(CFX_WideString& wsName) {
102   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
103   if (pEnv) {
104     wsName = pEnv->FFI_GetAppName();
105   }
106 }
107 
SetAppType(const CFX_WideStringC & wsAppType)108 void CPDFXFA_App::SetAppType(const CFX_WideStringC& wsAppType) {
109   m_csAppType = wsAppType;
110 }
111 
GetLanguage(CFX_WideString & wsLanguage)112 void CPDFXFA_App::GetLanguage(CFX_WideString& wsLanguage) {
113   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
114   if (pEnv) {
115     wsLanguage = pEnv->FFI_GetLanguage();
116   }
117 }
118 
GetPlatform(CFX_WideString & wsPlatform)119 void CPDFXFA_App::GetPlatform(CFX_WideString& wsPlatform) {
120   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
121   if (pEnv) {
122     wsPlatform = pEnv->FFI_GetPlatform();
123   }
124 }
125 
GetVariation(CFX_WideString & wsVariation)126 void CPDFXFA_App::GetVariation(CFX_WideString& wsVariation) {
127   wsVariation = JS_STR_VIEWERVARIATION;
128 }
129 
GetVersion(CFX_WideString & wsVersion)130 void CPDFXFA_App::GetVersion(CFX_WideString& wsVersion) {
131   wsVersion = JS_STR_VIEWERVERSION_XFA;
132 }
133 
Beep(FX_DWORD dwType)134 void CPDFXFA_App::Beep(FX_DWORD dwType) {
135   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
136   if (pEnv) {
137     pEnv->JS_appBeep(dwType);
138   }
139 }
140 
MsgBox(const CFX_WideStringC & wsMessage,const CFX_WideStringC & wsTitle,FX_DWORD dwIconType,FX_DWORD dwButtonType)141 int32_t CPDFXFA_App::MsgBox(const CFX_WideStringC& wsMessage,
142                             const CFX_WideStringC& wsTitle,
143                             FX_DWORD dwIconType,
144                             FX_DWORD dwButtonType) {
145   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
146   if (!pEnv)
147     return -1;
148 
149   FX_DWORD iconType = 0;
150   int iButtonType = 0;
151   switch (dwIconType) {
152     case XFA_MBICON_Error:
153       iconType |= 0;
154       break;
155     case XFA_MBICON_Warning:
156       iconType |= 1;
157       break;
158     case XFA_MBICON_Question:
159       iconType |= 2;
160       break;
161     case XFA_MBICON_Status:
162       iconType |= 3;
163       break;
164   }
165   switch (dwButtonType) {
166     case XFA_MB_OK:
167       iButtonType |= 0;
168       break;
169     case XFA_MB_OKCancel:
170       iButtonType |= 1;
171       break;
172     case XFA_MB_YesNo:
173       iButtonType |= 2;
174       break;
175     case XFA_MB_YesNoCancel:
176       iButtonType |= 3;
177       break;
178   }
179   int32_t iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(),
180                                    iButtonType, iconType);
181   switch (iRet) {
182     case 1:
183       return XFA_IDOK;
184     case 2:
185       return XFA_IDCancel;
186     case 3:
187       return XFA_IDNo;
188     case 4:
189       return XFA_IDYes;
190   }
191   return XFA_IDYes;
192 }
193 
Response(CFX_WideString & wsAnswer,const CFX_WideStringC & wsQuestion,const CFX_WideStringC & wsTitle,const CFX_WideStringC & wsDefaultAnswer,FX_BOOL bMark)194 void CPDFXFA_App::Response(CFX_WideString& wsAnswer,
195                            const CFX_WideStringC& wsQuestion,
196                            const CFX_WideStringC& wsTitle,
197                            const CFX_WideStringC& wsDefaultAnswer,
198                            FX_BOOL bMark) {
199   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
200   if (pEnv) {
201     int nLength = 2048;
202     char* pBuff = new char[nLength];
203     nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(),
204                                    wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff,
205                                    nLength);
206     if (nLength > 0) {
207       nLength = nLength > 2046 ? 2046 : nLength;
208       pBuff[nLength] = 0;
209       pBuff[nLength + 1] = 0;
210       wsAnswer = CFX_WideString::FromUTF16LE(
211           reinterpret_cast<const unsigned short*>(pBuff),
212           nLength / sizeof(unsigned short));
213     }
214     delete[] pBuff;
215   }
216 }
217 
GetCurDocumentInBatch()218 int32_t CPDFXFA_App::GetCurDocumentInBatch() {
219   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
220   if (pEnv) {
221     return pEnv->FFI_GetCurDocument();
222   }
223   return 0;
224 }
225 
GetDocumentCountInBatch()226 int32_t CPDFXFA_App::GetDocumentCountInBatch() {
227   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
228   if (pEnv) {
229     return pEnv->FFI_GetDocumentCount();
230   }
231 
232   return 0;
233 }
234 
DownloadURL(const CFX_WideStringC & wsURL)235 IFX_FileRead* CPDFXFA_App::DownloadURL(const CFX_WideStringC& wsURL) {
236   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
237   if (pEnv) {
238     return pEnv->FFI_DownloadFromURL(wsURL.GetPtr());
239   }
240   return NULL;
241 }
242 
PostRequestURL(const CFX_WideStringC & wsURL,const CFX_WideStringC & wsData,const CFX_WideStringC & wsContentType,const CFX_WideStringC & wsEncode,const CFX_WideStringC & wsHeader,CFX_WideString & wsResponse)243 FX_BOOL CPDFXFA_App::PostRequestURL(const CFX_WideStringC& wsURL,
244                                     const CFX_WideStringC& wsData,
245                                     const CFX_WideStringC& wsContentType,
246                                     const CFX_WideStringC& wsEncode,
247                                     const CFX_WideStringC& wsHeader,
248                                     CFX_WideString& wsResponse) {
249   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
250   if (pEnv) {
251     wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(),
252                                           wsContentType.GetPtr(),
253                                           wsEncode.GetPtr(), wsHeader.GetPtr());
254     return TRUE;
255   }
256   return FALSE;
257 }
258 
PutRequestURL(const CFX_WideStringC & wsURL,const CFX_WideStringC & wsData,const CFX_WideStringC & wsEncode)259 FX_BOOL CPDFXFA_App::PutRequestURL(const CFX_WideStringC& wsURL,
260                                    const CFX_WideStringC& wsData,
261                                    const CFX_WideStringC& wsEncode) {
262   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
263   if (pEnv) {
264     return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(),
265                                    wsEncode.GetPtr());
266   }
267   return FALSE;
268 }
269 
LoadString(int32_t iStringID,CFX_WideString & wsString)270 void CPDFXFA_App::LoadString(int32_t iStringID, CFX_WideString& wsString) {
271   switch (iStringID) {
272     case XFA_IDS_ValidateFailed:
273       wsString = L"%s validate failed";
274       return;
275     case XFA_IDS_CalcOverride:
276       wsString = L"Calculate Override";
277       return;
278     case XFA_IDS_ModifyField:
279       wsString = L"Are you sure you want to modify this field?";
280       return;
281     case XFA_IDS_NotModifyField:
282       wsString = L"You are not allowed to modify this field.";
283       return;
284     case XFA_IDS_AppName:
285       wsString = L"Foxit";
286       return;
287     case XFA_IDS_ImageFilter:
288       wsString =
289           L"Image "
290           L"Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|"
291           L"All Files(*.*)|*.*||";
292       return;
293     case XFA_IDS_UNKNOW_CATCHED:
294       wsString = L"unknown error is catched!";
295       return;
296     case XFA_IDS_Unable_TO_SET:
297       wsString = L"Unable to set ";
298       return;
299     case XFA_IDS_VALUE_EXCALMATORY:
300       wsString = L" value!";
301       return;
302     case XFA_IDS_INVALID_ENUM_VALUE:
303       wsString = L"Invalid enumerated value: ";
304       return;
305     case XFA_IDS_UNSUPPORT_METHOD:
306       wsString = L"unsupport %s method.";
307       return;
308     case XFA_IDS_UNSUPPORT_PROP:
309       wsString = L"unsupport %s property.";
310       return;
311     case XFA_IDS_INVAlID_PROP_SET:
312       wsString = L"Invalid property set operation;";
313       return;
314     case XFA_IDS_NOT_DEFAUL_VALUE:
315       wsString = L" doesn't have a default property";
316       return;
317     case XFA_IDS_UNABLE_SET_LANGUAGE:
318       wsString = L"Unable to set language value!";
319       return;
320     case XFA_IDS_UNABLE_SET_NUMPAGES:
321       wsString = L"Unable to set numPages value!";
322       return;
323     case XFA_IDS_UNABLE_SET_PLATFORM:
324       wsString = L"Unable to set platform value!";
325       return;
326     case XFA_IDS_UNABLE_SET_VALIDATIONENABLE:
327       wsString = L"Unable to set validationsEnabled value!";
328       return;
329     case XFA_IDS_UNABLE_SET_VARIATION:
330       wsString = L"Unable to set variation value!";
331       return;
332     case XFA_IDS_UNABLE_SET_VERSION:
333       wsString = L"Unable to set version value!";
334       return;
335     case XFA_IDS_UNABLE_SET_READY:
336       wsString = L"Unable to set ready value!";
337       return;
338     case XFA_IDS_NUMBER_OF_OCCUR:
339       wsString =
340           L"The element [%s] has violated its allowable number of occurrences";
341       return;
342     case XFA_IDS_UNABLE_SET_CLASS_NAME:
343       wsString = L"Unable to set className value!";
344       return;
345     case XFA_IDS_UNABLE_SET_LENGTH_VALUE:
346       wsString = L"Unable to set length value!";
347       return;
348     case XFA_IDS_UNSUPPORT_CHAR:
349       wsString = L"unsupported char '%c'";
350       return;
351     case XFA_IDS_BAD_SUFFIX:
352       wsString = L"bad suffix on number";
353       return;
354     case XFA_IDS_EXPECTED_IDENT:
355       wsString = L"expected identifier instead of '%s'";
356       return;
357     case XFA_IDS_EXPECTED_STRING:
358       wsString = L"expected '%s' instead of '%s'";
359       return;
360     case XFA_IDS_INVALIDATE_CHAR:
361       wsString = L"invalidate char '%c'";
362       return;
363     case XFA_IDS_REDEFINITION:
364       wsString = L"'%s' redefinition ";
365       return;
366     case XFA_IDS_INVALIDATE_TOKEN:
367       wsString = L"invalidate token '%s'";
368       return;
369     case XFA_IDS_INVALIDATE_EXPRESSION:
370       wsString = L"invalidate expression '%s'";
371       return;
372     case XFA_IDS_UNDEFINE_IDENTIFIER:
373       wsString = L"undefined identifier '%s'";
374       return;
375     case XFA_IDS_INVALIDATE_LEFTVALUE:
376       wsString = L"invalidate left-value '%s'";
377       return;
378     case XFA_IDS_COMPILER_ERROR:
379       wsString = L"compiler error";
380       return;
381     case XFA_IDS_CANNOT_MODIFY_VALUE:
382       wsString = L"can't modify the '%s' value";
383       return;
384     case XFA_IDS_ERROR_PARAMETERS:
385       wsString = L"function '%s' has not %d parameters";
386       return;
387     case XFA_IDS_EXPECT_ENDIF:
388       wsString = L"expected 'endif' instead of '%s'";
389       return;
390     case XFA_IDS_UNEXPECTED_EXPRESSION:
391       wsString = L"unexpected expression '%s'";
392       return;
393     case XFA_IDS_CONDITION_IS_NULL:
394       wsString = L"condition is null";
395       return;
396     case XFA_IDS_ILLEGALBREAK:
397       wsString = L"illegal break";
398       return;
399     case XFA_IDS_ILLEGALCONTINUE:
400       wsString = L"illegal continue";
401       return;
402     case XFA_IDS_EXPECTED_OPERATOR:
403       wsString = L"expected operator '%s' instead of '%s'";
404       return;
405     case XFA_IDS_DIVIDE_ZERO:
406       wsString = L"divide by zero";
407       return;
408     case XFA_IDS_CANNOT_COVERT_OBJECT:
409       wsString = L"%s.%s can not covert to object";
410       return;
411     case XFA_IDS_NOT_FOUND_CONTAINER:
412       wsString = L"can not found container '%s'";
413       return;
414     case XFA_IDS_NOT_FOUND_PROPERTY:
415       wsString = L"can not found property '%s'";
416       return;
417     case XFA_IDS_NOT_FOUND_METHOD:
418       wsString = L"can not found method '%s'";
419       return;
420     case XFA_IDS_NOT_FOUND_CONST:
421       wsString = L"can not found const '%s'";
422       return;
423     case XFA_IDS_NOT_ASSIGN_OBJECT:
424       wsString = L"can not direct assign value to object";
425       return;
426     case XFA_IDS_IVALIDATE_INSTRUCTION:
427       wsString = L"invalidate instruction";
428       return;
429     case XFA_IDS_EXPECT_NUMBER:
430       wsString = L"expected number instead of '%s'";
431       return;
432     case XFA_IDS_VALIDATE_OUT_ARRAY:
433       wsString = L"validate access index '%s' out of array";
434       return;
435     case XFA_IDS_CANNOT_ASSIGN_IDENT:
436       wsString = L"can not assign to %s";
437       return;
438     case XFA_IDS_NOT_FOUNT_FUNCTION:
439       wsString = L"can not found '%s' function";
440       return;
441     case XFA_IDS_NOT_ARRAY:
442       wsString = L"'%s' doesn't an array";
443       return;
444     case XFA_IDS_OUT_ARRAY:
445       wsString = L"out of range of '%s' array";
446       return;
447     case XFA_IDS_NOT_SUPPORT_CALC:
448       wsString = L"'%s' operator can not support array calculate";
449       return;
450     case XFA_IDS_ARGUMENT_NOT_ARRAY:
451       wsString = L"'%s' function's %d argument can not be array";
452       return;
453     case XFA_IDS_ARGUMENT_EXPECT_CONTAINER:
454       wsString = L"'%s' argument expected a container";
455       return;
456     case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT:
457       wsString =
458           L"an attempt was made to reference property '%s' of a non-object in "
459           L"SOM expression %s";
460       return;
461     case XFA_IDS_FUNCTION_IS_BUILDIN:
462       wsString = L"function '%s' is buildin";
463       return;
464     case XFA_IDS_ERROR_MSG:
465       wsString = L"%s : %s";
466       return;
467     case XFA_IDS_INDEX_OUT_OF_BOUNDS:
468       wsString = L"Index value is out of bounds";
469       return;
470     case XFA_IDS_INCORRECT_NUMBER_OF_METHOD:
471       wsString = L"Incorrect number of parameters calling method '%s'";
472       return;
473     case XFA_IDS_ARGUMENT_MISMATCH:
474       wsString = L"Argument mismatch in property or function argument";
475       return;
476     case XFA_IDS_INVALID_ENUMERATE:
477       wsString = L"Invalid enumerated value: %s";
478       return;
479     case XFA_IDS_INVALID_APPEND:
480       wsString =
481           L"Invalid append operation: %s cannot have a child element of %s";
482       return;
483     case XFA_IDS_SOM_EXPECTED_LIST:
484       wsString =
485           L"SOM expression returned list when single result was expected";
486       return;
487     case XFA_IDS_NOT_HAVE_PROPERTY:
488       wsString = L"'%s' doesn't have property '%s'";
489       return;
490     case XFA_IDS_INVALID_NODE_TYPE:
491       wsString = L"Invalid node type : '%s'";
492       return;
493     case XFA_IDS_VIOLATE_BOUNDARY:
494       wsString =
495           L"The element [%s] has violated its allowable number of occurrences";
496       return;
497     case XFA_IDS_SERVER_DENY:
498       wsString = L"Server does not permit";
499       return;
500     case XFA_IDS_ValidateLimit:
501       wsString = FX_WSTRC(
502           L"Message limit exceeded. Remaining %d validation errors not "
503           L"reported.");
504       return;
505     case XFA_IDS_ValidateNullWarning:
506       wsString = FX_WSTRC(
507           L"%s cannot be left blank. To ignore validations for %s, click "
508           L"Ignore.");
509       return;
510     case XFA_IDS_ValidateNullError:
511       wsString = FX_WSTRC(L"%s cannot be left blank.");
512       return;
513     case XFA_IDS_ValidateWarning:
514       wsString = FX_WSTRC(
515           L"The value you entered for %s is invalid. To ignore validations for "
516           L"%s, click Ignore.");
517       return;
518     case XFA_IDS_ValidateError:
519       wsString = FX_WSTRC(L"The value you entered for %s is invalid.");
520       return;
521   }
522 }
523 
ShowFileDialog(const CFX_WideStringC & wsTitle,const CFX_WideStringC & wsFilter,CFX_WideStringArray & wsPathArr,FX_BOOL bOpen)524 FX_BOOL CPDFXFA_App::ShowFileDialog(const CFX_WideStringC& wsTitle,
525                                     const CFX_WideStringC& wsFilter,
526                                     CFX_WideStringArray& wsPathArr,
527                                     FX_BOOL bOpen) {
528   return FALSE;
529 }
530 
GetTimerMgr()531 IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr() {
532   CXFA_FWLAdapterTimerMgr* pAdapter = NULL;
533   CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
534   if (pEnv)
535     pAdapter = new CXFA_FWLAdapterTimerMgr(pEnv);
536   return pAdapter;
537 }
538