OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "fpdfsdk/fpdfxfa/cpdfxfa_document.h" | 7 #include "fpdfsdk/fpdfxfa/cpdfxfa_document.h" |
8 | 8 |
9 #include "core/fpdfapi/parser/cpdf_document.h" | 9 #include "core/fpdfapi/parser/cpdf_document.h" |
10 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" | 10 #include "fpdfsdk/cpdfsdk_formfillenvironment.h" |
11 #include "fpdfsdk/cpdfsdk_interform.h" | 11 #include "fpdfsdk/cpdfsdk_interform.h" |
12 #include "fpdfsdk/cpdfsdk_pageview.h" | 12 #include "fpdfsdk/cpdfsdk_pageview.h" |
13 #include "fpdfsdk/fpdfxfa/cpdfxfa_app.h" | |
14 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h" | 13 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h" |
15 #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" | 14 #include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h" |
16 #include "fpdfsdk/fsdk_define.h" | 15 #include "fpdfsdk/fsdk_define.h" |
| 16 #include "fpdfsdk/javascript/cjs_runtime.h" |
17 #include "fpdfsdk/javascript/ijs_runtime.h" | 17 #include "fpdfsdk/javascript/ijs_runtime.h" |
18 #include "public/fpdf_formfill.h" | 18 #include "public/fpdf_formfill.h" |
19 #include "third_party/base/ptr_util.h" | 19 #include "third_party/base/ptr_util.h" |
20 #include "xfa/fxfa/cxfa_eventparam.h" | 20 #include "xfa/fxfa/cxfa_eventparam.h" |
21 #include "xfa/fxfa/xfa_ffapp.h" | 21 #include "xfa/fxfa/xfa_ffapp.h" |
22 #include "xfa/fxfa/xfa_ffdoc.h" | 22 #include "xfa/fxfa/xfa_ffdoc.h" |
23 #include "xfa/fxfa/xfa_ffdocview.h" | 23 #include "xfa/fxfa/xfa_ffdocview.h" |
24 #include "xfa/fxfa/xfa_ffpageview.h" | 24 #include "xfa/fxfa/xfa_ffpageview.h" |
25 #include "xfa/fxfa/xfa_ffwidgethandler.h" | 25 #include "xfa/fxfa/xfa_ffwidgethandler.h" |
| 26 #include "xfa/fxfa/xfa_fontmgr.h" |
26 | 27 |
27 #ifndef _WIN32 | 28 #ifndef _WIN32 |
28 extern void SetLastError(int err); | 29 extern void SetLastError(int err); |
29 extern int GetLastError(); | 30 extern int GetLastError(); |
30 #endif | 31 #endif |
31 | 32 |
32 CPDFXFA_Document::CPDFXFA_Document(std::unique_ptr<CPDF_Document> pPDFDoc) | 33 CPDFXFA_Document::CPDFXFA_Document(std::unique_ptr<CPDF_Document> pPDFDoc) |
33 : m_iDocType(DOCTYPE_PDF), | 34 : m_iDocType(DOCTYPE_PDF), |
34 m_pPDFDoc(std::move(pPDFDoc)), | 35 m_pPDFDoc(std::move(pPDFDoc)), |
35 m_pFormFillEnv(nullptr), | 36 m_pFormFillEnv(nullptr), |
36 m_pXFADocView(nullptr), | 37 m_pXFADocView(nullptr), |
37 m_nLoadStatus(FXFA_LOADSTATUS_PRELOAD), | 38 m_nLoadStatus(FXFA_LOADSTATUS_PRELOAD), |
38 m_nPageCount(0), | 39 m_nPageCount(0), |
39 m_DocEnv(this) {} | 40 m_DocEnv(this) { |
| 41 m_pXFAApp = pdfium::MakeUnique<CXFA_FFApp>(this); |
| 42 m_pXFAApp->SetDefaultFontMgr(pdfium::MakeUnique<CXFA_DefFontMgr>()); |
| 43 } |
40 | 44 |
41 CPDFXFA_Document::~CPDFXFA_Document() { | 45 CPDFXFA_Document::~CPDFXFA_Document() { |
42 m_nLoadStatus = FXFA_LOADSTATUS_CLOSING; | 46 m_nLoadStatus = FXFA_LOADSTATUS_CLOSING; |
43 | 47 |
44 // Must happen before we remove the form fill environment. | 48 // Must happen before we remove the form fill environment. |
45 if (m_pXFADoc) { | 49 CloseXFADoc(); |
46 if (CXFA_FFApp* pApp = GetApp()->GetXFAApp()) | |
47 CloseXFADoc(pApp->GetDocHandler()); | |
48 } | |
49 | 50 |
50 if (m_pFormFillEnv) { | 51 if (m_pFormFillEnv) { |
51 m_pFormFillEnv->ClearAllFocusedAnnots(); | 52 m_pFormFillEnv->ClearAllFocusedAnnots(); |
52 // Once we're deleted the FormFillEnvironment will point at a bad underlying | 53 // Once we're deleted the FormFillEnvironment will point at a bad underlying |
53 // doc so we need to reset it ... | 54 // doc so we need to reset it ... |
54 m_pFormFillEnv->ResetXFADocument(); | 55 m_pFormFillEnv->ResetXFADocument(); |
55 m_pFormFillEnv = nullptr; | 56 m_pFormFillEnv = nullptr; |
56 } | 57 } |
57 | 58 |
58 m_nLoadStatus = FXFA_LOADSTATUS_CLOSED; | 59 m_nLoadStatus = FXFA_LOADSTATUS_CLOSED; |
59 } | 60 } |
60 | 61 |
61 void CPDFXFA_Document::CloseXFADoc(CXFA_FFDocHandler* pDoc) { | 62 void CPDFXFA_Document::CloseXFADoc() { |
62 if (!pDoc) | 63 if (!m_pXFADoc) |
63 return; | 64 return; |
64 m_pXFADoc->CloseDoc(); | 65 m_pXFADoc->CloseDoc(); |
65 m_pXFADoc.reset(); | 66 m_pXFADoc.reset(); |
66 m_pXFADocView = nullptr; | 67 m_pXFADocView = nullptr; |
67 } | 68 } |
68 | 69 |
69 CPDFXFA_App* CPDFXFA_Document::GetApp() { | |
70 if (!m_pApp) | |
71 m_pApp = pdfium::MakeUnique<CPDFXFA_App>(); | |
72 return m_pApp.get(); | |
73 } | |
74 | |
75 void CPDFXFA_Document::SetFormFillEnv( | 70 void CPDFXFA_Document::SetFormFillEnv( |
76 CPDFSDK_FormFillEnvironment* pFormFillEnv) { | 71 CPDFSDK_FormFillEnvironment* pFormFillEnv) { |
77 // The layout data can have pointers back into the script context. That | 72 // The layout data can have pointers back into the script context. That |
78 // context will be different if the form fill environment closes, so, force | 73 // context will be different if the form fill environment closes, so, force |
79 // the layout data to clear. | 74 // the layout data to clear. |
80 if (m_pXFADoc && m_pXFADoc->GetXFADoc()) | 75 if (m_pXFADoc && m_pXFADoc->GetXFADoc()) |
81 m_pXFADoc->GetXFADoc()->ClearLayoutData(); | 76 m_pXFADoc->GetXFADoc()->ClearLayoutData(); |
82 | 77 |
83 GetApp()->SetFormFillEnv(pFormFillEnv); | |
84 m_pFormFillEnv = pFormFillEnv; | 78 m_pFormFillEnv = pFormFillEnv; |
85 } | 79 } |
86 | 80 |
87 FX_BOOL CPDFXFA_Document::LoadXFADoc() { | 81 FX_BOOL CPDFXFA_Document::LoadXFADoc() { |
88 m_nLoadStatus = FXFA_LOADSTATUS_LOADING; | 82 m_nLoadStatus = FXFA_LOADSTATUS_LOADING; |
89 | 83 |
90 if (!m_pPDFDoc) | 84 if (!m_pPDFDoc) |
91 return FALSE; | 85 return FALSE; |
92 | 86 |
93 m_XFAPageList.RemoveAll(); | 87 m_XFAPageList.RemoveAll(); |
94 | 88 |
95 CXFA_FFApp* pApp = GetApp()->GetXFAApp(); | 89 CXFA_FFApp* pApp = GetXFAApp(); |
96 if (!pApp) | 90 if (!pApp) |
97 return FALSE; | 91 return FALSE; |
98 | 92 |
99 m_pXFADoc.reset(pApp->CreateDoc(&m_DocEnv, m_pPDFDoc.get())); | 93 m_pXFADoc.reset(pApp->CreateDoc(&m_DocEnv, m_pPDFDoc.get())); |
100 if (!m_pXFADoc) { | 94 if (!m_pXFADoc) { |
101 SetLastError(FPDF_ERR_XFALOAD); | 95 SetLastError(FPDF_ERR_XFALOAD); |
102 return FALSE; | 96 return FALSE; |
103 } | 97 } |
104 | 98 |
105 CXFA_FFDocHandler* pDocHandler = pApp->GetDocHandler(); | 99 CXFA_FFDocHandler* pDocHandler = pApp->GetDocHandler(); |
106 if (!pDocHandler) { | 100 if (!pDocHandler) { |
107 SetLastError(FPDF_ERR_XFALOAD); | 101 SetLastError(FPDF_ERR_XFALOAD); |
108 return FALSE; | 102 return FALSE; |
109 } | 103 } |
110 | 104 |
111 m_pXFADoc->StartLoad(); | 105 m_pXFADoc->StartLoad(); |
112 int iStatus = m_pXFADoc->DoLoad(nullptr); | 106 int iStatus = m_pXFADoc->DoLoad(nullptr); |
113 if (iStatus != XFA_PARSESTATUS_Done) { | 107 if (iStatus != XFA_PARSESTATUS_Done) { |
114 CloseXFADoc(pDocHandler); | 108 CloseXFADoc(); |
115 SetLastError(FPDF_ERR_XFALOAD); | 109 SetLastError(FPDF_ERR_XFALOAD); |
116 return FALSE; | 110 return FALSE; |
117 } | 111 } |
118 m_pXFADoc->StopLoad(); | 112 m_pXFADoc->StopLoad(); |
119 m_pXFADoc->GetXFADoc()->InitScriptContext(GetApp()->GetJSERuntime()); | 113 m_pXFADoc->GetXFADoc()->InitScriptContext(GetJSERuntime()); |
120 | 114 |
121 if (m_pXFADoc->GetDocType() == XFA_DOCTYPE_Dynamic) | 115 if (m_pXFADoc->GetDocType() == XFA_DOCTYPE_Dynamic) |
122 m_iDocType = DOCTYPE_DYNAMIC_XFA; | 116 m_iDocType = DOCTYPE_DYNAMIC_XFA; |
123 else | 117 else |
124 m_iDocType = DOCTYPE_STATIC_XFA; | 118 m_iDocType = DOCTYPE_STATIC_XFA; |
125 | 119 |
126 m_pXFADocView = m_pXFADoc->CreateDocView(XFA_DOCVIEW_View); | 120 m_pXFADocView = m_pXFADoc->CreateDocView(XFA_DOCVIEW_View); |
127 if (m_pXFADocView->StartLayout() < 0) { | 121 if (m_pXFADocView->StartLayout() < 0) { |
128 CloseXFADoc(pDocHandler); | 122 CloseXFADoc(); |
129 SetLastError(FPDF_ERR_XFALAYOUT); | 123 SetLastError(FPDF_ERR_XFALAYOUT); |
130 return FALSE; | 124 return FALSE; |
131 } | 125 } |
132 | 126 |
133 m_pXFADocView->DoLayout(nullptr); | 127 m_pXFADocView->DoLayout(nullptr); |
134 m_pXFADocView->StopLayout(); | 128 m_pXFADocView->StopLayout(); |
135 m_nLoadStatus = FXFA_LOADSTATUS_LOADED; | 129 m_nLoadStatus = FXFA_LOADSTATUS_LOADED; |
136 | 130 |
137 return TRUE; | 131 return TRUE; |
138 } | 132 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 } | 211 } |
218 | 212 |
219 void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { | 213 void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page) { |
220 m_XFAPageList.SetAt(page->GetPageIndex(), nullptr); | 214 m_XFAPageList.SetAt(page->GetPageIndex(), nullptr); |
221 } | 215 } |
222 | 216 |
223 void CPDFXFA_Document::ClearChangeMark() { | 217 void CPDFXFA_Document::ClearChangeMark() { |
224 if (m_pFormFillEnv) | 218 if (m_pFormFillEnv) |
225 m_pFormFillEnv->ClearChangeMark(); | 219 m_pFormFillEnv->ClearChangeMark(); |
226 } | 220 } |
| 221 |
| 222 v8::Isolate* CPDFXFA_Document::GetJSERuntime() const { |
| 223 if (!m_pFormFillEnv) |
| 224 return nullptr; |
| 225 |
| 226 // XFA requires V8, if we have V8 then we have a CJS_Runtime and not the stub. |
| 227 CJS_Runtime* runtime = |
| 228 static_cast<CJS_Runtime*>(m_pFormFillEnv->GetJSRuntime()); |
| 229 return runtime->GetIsolate(); |
| 230 } |
| 231 |
| 232 void CPDFXFA_Document::GetAppName(CFX_WideString& wsName) { |
| 233 if (m_pFormFillEnv) |
| 234 wsName = m_pFormFillEnv->FFI_GetAppName(); |
| 235 } |
| 236 |
| 237 void CPDFXFA_Document::GetLanguage(CFX_WideString& wsLanguage) { |
| 238 if (m_pFormFillEnv) |
| 239 wsLanguage = m_pFormFillEnv->GetLanguage(); |
| 240 } |
| 241 |
| 242 void CPDFXFA_Document::GetPlatform(CFX_WideString& wsPlatform) { |
| 243 if (m_pFormFillEnv) |
| 244 wsPlatform = m_pFormFillEnv->GetPlatform(); |
| 245 } |
| 246 |
| 247 void CPDFXFA_Document::Beep(uint32_t dwType) { |
| 248 if (m_pFormFillEnv) |
| 249 m_pFormFillEnv->JS_appBeep(dwType); |
| 250 } |
| 251 |
| 252 int32_t CPDFXFA_Document::MsgBox(const CFX_WideString& wsMessage, |
| 253 const CFX_WideString& wsTitle, |
| 254 uint32_t dwIconType, |
| 255 uint32_t dwButtonType) { |
| 256 if (!m_pFormFillEnv) |
| 257 return -1; |
| 258 |
| 259 uint32_t iconType = 0; |
| 260 int iButtonType = 0; |
| 261 switch (dwIconType) { |
| 262 case XFA_MBICON_Error: |
| 263 iconType |= 0; |
| 264 break; |
| 265 case XFA_MBICON_Warning: |
| 266 iconType |= 1; |
| 267 break; |
| 268 case XFA_MBICON_Question: |
| 269 iconType |= 2; |
| 270 break; |
| 271 case XFA_MBICON_Status: |
| 272 iconType |= 3; |
| 273 break; |
| 274 } |
| 275 switch (dwButtonType) { |
| 276 case XFA_MB_OK: |
| 277 iButtonType |= 0; |
| 278 break; |
| 279 case XFA_MB_OKCancel: |
| 280 iButtonType |= 1; |
| 281 break; |
| 282 case XFA_MB_YesNo: |
| 283 iButtonType |= 2; |
| 284 break; |
| 285 case XFA_MB_YesNoCancel: |
| 286 iButtonType |= 3; |
| 287 break; |
| 288 } |
| 289 int32_t iRet = m_pFormFillEnv->JS_appAlert(wsMessage.c_str(), wsTitle.c_str(), |
| 290 iButtonType, iconType); |
| 291 switch (iRet) { |
| 292 case 1: |
| 293 return XFA_IDOK; |
| 294 case 2: |
| 295 return XFA_IDCancel; |
| 296 case 3: |
| 297 return XFA_IDNo; |
| 298 case 4: |
| 299 return XFA_IDYes; |
| 300 } |
| 301 return XFA_IDYes; |
| 302 } |
| 303 |
| 304 CFX_WideString CPDFXFA_Document::Response(const CFX_WideString& wsQuestion, |
| 305 const CFX_WideString& wsTitle, |
| 306 const CFX_WideString& wsDefaultAnswer, |
| 307 FX_BOOL bMark) { |
| 308 CFX_WideString wsAnswer; |
| 309 if (!m_pFormFillEnv) |
| 310 return wsAnswer; |
| 311 |
| 312 int nLength = 2048; |
| 313 char* pBuff = new char[nLength]; |
| 314 nLength = m_pFormFillEnv->JS_appResponse(wsQuestion.c_str(), wsTitle.c_str(), |
| 315 wsDefaultAnswer.c_str(), nullptr, |
| 316 bMark, pBuff, nLength); |
| 317 if (nLength > 0) { |
| 318 nLength = nLength > 2046 ? 2046 : nLength; |
| 319 pBuff[nLength] = 0; |
| 320 pBuff[nLength + 1] = 0; |
| 321 wsAnswer = CFX_WideString::FromUTF16LE( |
| 322 reinterpret_cast<const unsigned short*>(pBuff), |
| 323 nLength / sizeof(unsigned short)); |
| 324 } |
| 325 delete[] pBuff; |
| 326 return wsAnswer; |
| 327 } |
| 328 |
| 329 IFX_SeekableReadStream* CPDFXFA_Document::DownloadURL( |
| 330 const CFX_WideString& wsURL) { |
| 331 return m_pFormFillEnv ? m_pFormFillEnv->DownloadFromURL(wsURL.c_str()) |
| 332 : nullptr; |
| 333 } |
| 334 |
| 335 FX_BOOL CPDFXFA_Document::PostRequestURL(const CFX_WideString& wsURL, |
| 336 const CFX_WideString& wsData, |
| 337 const CFX_WideString& wsContentType, |
| 338 const CFX_WideString& wsEncode, |
| 339 const CFX_WideString& wsHeader, |
| 340 CFX_WideString& wsResponse) { |
| 341 if (!m_pFormFillEnv) |
| 342 return FALSE; |
| 343 |
| 344 wsResponse = m_pFormFillEnv->PostRequestURL( |
| 345 wsURL.c_str(), wsData.c_str(), wsContentType.c_str(), wsEncode.c_str(), |
| 346 wsHeader.c_str()); |
| 347 return TRUE; |
| 348 } |
| 349 |
| 350 FX_BOOL CPDFXFA_Document::PutRequestURL(const CFX_WideString& wsURL, |
| 351 const CFX_WideString& wsData, |
| 352 const CFX_WideString& wsEncode) { |
| 353 return m_pFormFillEnv && |
| 354 m_pFormFillEnv->PutRequestURL(wsURL.c_str(), wsData.c_str(), |
| 355 wsEncode.c_str()); |
| 356 } |
| 357 |
| 358 void CPDFXFA_Document::LoadString(int32_t iStringID, CFX_WideString& wsString) { |
| 359 switch (iStringID) { |
| 360 case XFA_IDS_ValidateFailed: |
| 361 wsString = L"%s validation failed"; |
| 362 return; |
| 363 case XFA_IDS_CalcOverride: |
| 364 wsString = L"Calculate Override"; |
| 365 return; |
| 366 case XFA_IDS_ModifyField: |
| 367 wsString = L"Are you sure you want to modify this field?"; |
| 368 return; |
| 369 case XFA_IDS_NotModifyField: |
| 370 wsString = L"You are not allowed to modify this field."; |
| 371 return; |
| 372 case XFA_IDS_AppName: |
| 373 wsString = L"pdfium"; |
| 374 return; |
| 375 case XFA_IDS_Unable_TO_SET: |
| 376 wsString = L"Unable to set "; |
| 377 return; |
| 378 case XFA_IDS_INVAlID_PROP_SET: |
| 379 wsString = L"Invalid property set operation."; |
| 380 return; |
| 381 case XFA_IDS_NOT_DEFAUL_VALUE: |
| 382 wsString = L" doesn't have a default property."; |
| 383 return; |
| 384 case XFA_IDS_UNABLE_SET_LANGUAGE: |
| 385 wsString = L"Unable to set language value."; |
| 386 return; |
| 387 case XFA_IDS_UNABLE_SET_NUMPAGES: |
| 388 wsString = L"Unable to set numPages value."; |
| 389 return; |
| 390 case XFA_IDS_UNABLE_SET_PLATFORM: |
| 391 wsString = L"Unable to set platform value."; |
| 392 return; |
| 393 case XFA_IDS_UNABLE_SET_VARIATION: |
| 394 wsString = L"Unable to set variation value."; |
| 395 return; |
| 396 case XFA_IDS_UNABLE_SET_VERSION: |
| 397 wsString = L"Unable to set version value."; |
| 398 return; |
| 399 case XFA_IDS_UNABLE_SET_READY: |
| 400 wsString = L"Unable to set ready value."; |
| 401 return; |
| 402 case XFA_IDS_COMPILER_ERROR: |
| 403 wsString = L"Compiler error."; |
| 404 return; |
| 405 case XFA_IDS_DIVIDE_ZERO: |
| 406 wsString = L"Divide by zero."; |
| 407 return; |
| 408 case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT: |
| 409 wsString = |
| 410 L"An attempt was made to reference property '%s' of a non-object in " |
| 411 L"SOM expression %s."; |
| 412 return; |
| 413 case XFA_IDS_INDEX_OUT_OF_BOUNDS: |
| 414 wsString = L"Index value is out of bounds."; |
| 415 return; |
| 416 case XFA_IDS_INCORRECT_NUMBER_OF_METHOD: |
| 417 wsString = L"Incorrect number of parameters calling method '%s'."; |
| 418 return; |
| 419 case XFA_IDS_ARGUMENT_MISMATCH: |
| 420 wsString = L"Argument mismatch in property or function argument."; |
| 421 return; |
| 422 case XFA_IDS_NOT_HAVE_PROPERTY: |
| 423 wsString = L"'%s' doesn't have property '%s'."; |
| 424 return; |
| 425 case XFA_IDS_VIOLATE_BOUNDARY: |
| 426 wsString = |
| 427 L"The element [%s] has violated its allowable number of occurrences."; |
| 428 return; |
| 429 case XFA_IDS_SERVER_DENY: |
| 430 wsString = L"Server does not permit."; |
| 431 return; |
| 432 case XFA_IDS_ValidateLimit: |
| 433 wsString = |
| 434 L"Message limit exceeded. Remaining %d validation errors not " |
| 435 L"reported."; |
| 436 return; |
| 437 case XFA_IDS_ValidateNullWarning: |
| 438 wsString = |
| 439 L"%s cannot be blank. To ignore validations for %s, click Ignore."; |
| 440 return; |
| 441 case XFA_IDS_ValidateNullError: |
| 442 wsString = L"%s cannot be blank."; |
| 443 return; |
| 444 case XFA_IDS_ValidateWarning: |
| 445 wsString = |
| 446 L"The value you entered for %s is invalid. To ignore validations for " |
| 447 L"%s, click Ignore."; |
| 448 return; |
| 449 case XFA_IDS_ValidateError: |
| 450 wsString = L"The value you entered for %s is invalid."; |
| 451 return; |
| 452 } |
| 453 } |
| 454 |
| 455 IFWL_AdapterTimerMgr* CPDFXFA_Document::GetTimerMgr() { |
| 456 CXFA_FWLAdapterTimerMgr* pAdapter = nullptr; |
| 457 if (m_pFormFillEnv) |
| 458 pAdapter = new CXFA_FWLAdapterTimerMgr(m_pFormFillEnv); |
| 459 return pAdapter; |
| 460 } |
OLD | NEW |