0

Add foundations of enabling PDFium XFA at runtime.

Replace a boolean enabling javascript with a tri-state enum and
plumb through to the appropriate code.

No functional change yet introduced. Building with PDF_ENABLE_XFA
will still result in a chromium with XFA support fully enabled. We
do not yet ship chrome built with this option.

Bug: chromium:62400
Change-Id: Idbbc8de6033cf3ed90d3eb3ecbb9a2ef0a32b623
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2417091
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808446}
This commit is contained in:
Tom Sepez
2020-09-18 19:13:23 +00:00
committed by Commit Bot
parent 0e660dfe2c
commit cc750ee302
9 changed files with 67 additions and 48 deletions

@ -455,6 +455,14 @@ bool IsSaveDataSizeValid(size_t size) {
return size > 0 && size <= kMaximumSavedFileSize; return size > 0 && size <= kMaximumSavedFileSize;
} }
PDFiumFormFiller::ScriptOption DefaultScriptOption() {
#if defined(PDF_ENABLE_XFA)
return PDFiumFormFiller::ScriptOption::kJavaScriptAndXFA;
#else // defined(PDF_ENABLE_XFA)
return PDFiumFormFiller::ScriptOption::kJavaScript;
#endif // defined(PDF_ENABLE_XFA)
}
} // namespace } // namespace
OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance) OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
@ -512,7 +520,7 @@ bool OutOfProcessInstance::Init(uint32_t argc,
text_input_ = std::make_unique<pp::TextInput_Dev>(this); text_input_ = std::make_unique<pp::TextInput_Dev>(this);
bool enable_javascript = true; PDFiumFormFiller::ScriptOption script_option = DefaultScriptOption();
bool has_edits = false; bool has_edits = false;
const char* stream_url = nullptr; const char* stream_url = nullptr;
const char* original_url = nullptr; const char* original_url = nullptr;
@ -534,8 +542,10 @@ bool OutOfProcessInstance::Init(uint32_t argc,
success = success =
base::StringToInt(argv[i], &top_toolbar_height_in_viewport_coords_); base::StringToInt(argv[i], &top_toolbar_height_in_viewport_coords_);
} else if (strcmp(argn[i], "javascript") == 0) { } else if (strcmp(argn[i], "javascript") == 0) {
if (base::FeatureList::IsEnabled(features::kPdfHonorJsContentSettings)) if (base::FeatureList::IsEnabled(features::kPdfHonorJsContentSettings)) {
enable_javascript = (strcmp(argv[i], "allow") == 0); if (strcmp(argv[i], "allow") != 0)
script_option = PDFiumFormFiller::ScriptOption::kNoJavaScript;
}
} else if (strcmp(argn[i], "has-edits") == 0) { } else if (strcmp(argn[i], "has-edits") == 0) {
has_edits = true; has_edits = true;
} }
@ -549,7 +559,7 @@ bool OutOfProcessInstance::Init(uint32_t argc,
if (!stream_url) if (!stream_url)
stream_url = original_url; stream_url = original_url;
InitializeEngine(enable_javascript); InitializeEngine(script_option);
// If we're in print preview mode we don't need to load the document yet. // If we're in print preview mode we don't need to load the document yet.
// A |kJSResetPrintPreviewModeType| message will be sent to the plugin letting // A |kJSResetPrintPreviewModeType| message will be sent to the plugin letting
@ -1092,9 +1102,8 @@ void OutOfProcessInstance::DidOpenPreview(std::unique_ptr<UrlLoader> loader,
int32_t result) { int32_t result) {
if (result == PP_OK) { if (result == PP_OK) {
preview_client_ = std::make_unique<PreviewModeClient>(this); preview_client_ = std::make_unique<PreviewModeClient>(this);
preview_engine_ = preview_engine_ = std::make_unique<PDFiumEngine>(
std::make_unique<PDFiumEngine>(preview_client_.get(), preview_client_.get(), PDFiumFormFiller::ScriptOption::kNoJavaScript);
/*enable_javascript=*/false);
preview_engine_->HandleDocumentLoad(std::move(loader)); preview_engine_->HandleDocumentLoad(std::move(loader));
} else { } else {
NOTREACHED(); NOTREACHED();
@ -1718,7 +1727,7 @@ void OutOfProcessInstance::HandleResetPrintPreviewModeMessage(
document_load_state_ = LOAD_STATE_LOADING; document_load_state_ = LOAD_STATE_LOADING;
LoadUrl(url_, /*is_print_preview=*/false); LoadUrl(url_, /*is_print_preview=*/false);
preview_engine_.reset(); preview_engine_.reset();
InitializeEngine(/*enable_javascript=*/false); InitializeEngine(PDFiumFormFiller::ScriptOption::kNoJavaScript);
engine()->SetGrayscale(dict.Get(pp::Var(kJSPrintPreviewGrayscale)).AsBool()); engine()->SetGrayscale(dict.Get(pp::Var(kJSPrintPreviewGrayscale)).AsBool());
engine()->New(url_.c_str(), /*headers=*/nullptr); engine()->New(url_.c_str(), /*headers=*/nullptr);

@ -20,8 +20,9 @@ PdfViewPluginBase::PdfViewPluginBase() = default;
PdfViewPluginBase::~PdfViewPluginBase() = default; PdfViewPluginBase::~PdfViewPluginBase() = default;
void PdfViewPluginBase::InitializeEngine(bool enable_javascript) { void PdfViewPluginBase::InitializeEngine(
engine_ = std::make_unique<PDFiumEngine>(this, enable_javascript); PDFiumFormFiller::ScriptOption script_option) {
engine_ = std::make_unique<PDFiumEngine>(this, script_option);
} }
void PdfViewPluginBase::DestroyEngine() { void PdfViewPluginBase::DestroyEngine() {

@ -13,6 +13,7 @@
#include <string> #include <string>
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "pdf/pdfium/pdfium_form_filler.h"
namespace chrome_pdf { namespace chrome_pdf {
@ -30,11 +31,8 @@ class PdfViewPluginBase : public PDFEngine::Client {
PdfViewPluginBase(); PdfViewPluginBase();
~PdfViewPluginBase() override; ~PdfViewPluginBase() override;
// Initializes the main `PDFiumEngine`. If `enable_javascript` is true, the // Initializes the main `PDFiumEngine`. Any existing engine will be replaced.
// engine will support executing JavaScript. void InitializeEngine(PDFiumFormFiller::ScriptOption script_option);
//
// Any existing engine will be replaced.
void InitializeEngine(bool enable_javascript);
// Destroys the main `PDFiumEngine`. Subclasses should call this method in // Destroys the main `PDFiumEngine`. Subclasses should call this method in
// their destructor to ensure the engine is destroyed first. // their destructor to ensure the engine is destroyed first.

@ -109,7 +109,7 @@ bool PdfViewWebPlugin::Initialize(blink::WebPluginContainer* container) {
initial_params_ = {}; initial_params_ = {};
PerProcessInitializer::GetInstance().Acquire(); PerProcessInitializer::GetInstance().Acquire();
InitializeEngine(/*enable_javascript=*/false); InitializeEngine(PDFiumFormFiller::ScriptOption::kNoJavaScript);
LoadUrl(stream_url, /*is_print_preview=*/false); LoadUrl(stream_url, /*is_print_preview=*/false);
return true; return true;
} }

@ -458,14 +458,15 @@ PDFEngine::AccessibilityTextFieldInfo::AccessibilityTextFieldInfo(
PDFEngine::AccessibilityTextFieldInfo::~AccessibilityTextFieldInfo() = default; PDFEngine::AccessibilityTextFieldInfo::~AccessibilityTextFieldInfo() = default;
PDFiumEngine::PDFiumEngine(PDFEngine::Client* client, bool enable_javascript) PDFiumEngine::PDFiumEngine(PDFEngine::Client* client,
PDFiumFormFiller::ScriptOption script_option)
: client_(client), : client_(client),
form_filler_(this, enable_javascript), form_filler_(this, script_option),
mouse_down_state_(PDFiumPage::NONSELECTABLE_AREA, mouse_down_state_(PDFiumPage::NONSELECTABLE_AREA,
PDFiumPage::LinkTarget()), PDFiumPage::LinkTarget()),
print_(this) { print_(this) {
#if defined(PDF_ENABLE_V8) #if defined(PDF_ENABLE_V8)
if (enable_javascript) if (script_option != PDFiumFormFiller::ScriptOption::kNoJavaScript)
DCHECK(IsV8Initialized()); DCHECK(IsV8Initialized());
#endif // defined(PDF_ENABLE_V8) #endif // defined(PDF_ENABLE_V8)
@ -2837,10 +2838,11 @@ void PDFiumEngine::LoadForm() {
ScopedUnsupportedFeature scoped_unsupported_feature(this); ScopedUnsupportedFeature scoped_unsupported_feature(this);
document_->InitializeForm(&form_filler_); document_->InitializeForm(&form_filler_);
} }
#if defined(PDF_ENABLE_XFA)
FPDF_LoadXFA(doc());
#endif
if (form_filler_.script_option() ==
PDFiumFormFiller::ScriptOption::kJavaScriptAndXFA) {
FPDF_LoadXFA(doc());
}
FPDF_SetFormFieldHighlightColor(form(), FPDF_FORMFIELD_UNKNOWN, FPDF_SetFormFieldHighlightColor(form(), FPDF_FORMFIELD_UNKNOWN,
kFormHighlightColor); kFormHighlightColor);
FPDF_SetFormFieldHighlightAlpha(form(), kFormHighlightAlpha); FPDF_SetFormFieldHighlightAlpha(form(), kFormHighlightAlpha);

@ -62,8 +62,9 @@ class PDFiumEngine : public PDFEngine,
// Exposed for testing. // Exposed for testing.
enum class FocusElementType { kNone, kDocument, kPage }; enum class FocusElementType { kNone, kDocument, kPage };
// NOTE: |enable_javascript| is ignored when PDF_ENABLE_V8 is not defined. // NOTE: |script_option| is ignored when PDF_ENABLE_V8 is not defined.
PDFiumEngine(PDFEngine::Client* client, bool enable_javascript); PDFiumEngine(PDFEngine::Client* client,
PDFiumFormFiller::ScriptOption script_option);
PDFiumEngine(const PDFiumEngine&) = delete; PDFiumEngine(const PDFiumEngine&) = delete;
PDFiumEngine& operator=(const PDFiumEngine&) = delete; PDFiumEngine& operator=(const PDFiumEngine&) = delete;
~PDFiumEngine() override; ~PDFiumEngine() override;

@ -28,8 +28,9 @@ std::string WideStringToString(FPDF_WIDESTRING wide_string) {
} // namespace } // namespace
PDFiumFormFiller::PDFiumFormFiller(PDFiumEngine* engine, bool enable_javascript) PDFiumFormFiller::PDFiumFormFiller(PDFiumEngine* engine,
: engine_(engine) { ScriptOption script_option)
: engine_(engine), script_option_(script_option) {
// Initialize FPDF_FORMFILLINFO member variables. Deriving from this struct // Initialize FPDF_FORMFILLINFO member variables. Deriving from this struct
// allows the static callbacks to be able to cast the FPDF_FORMFILLINFO in // allows the static callbacks to be able to cast the FPDF_FORMFILLINFO in
// callbacks to ourself instead of maintaining a map of them to // callbacks to ourself instead of maintaining a map of them to
@ -72,7 +73,7 @@ PDFiumFormFiller::PDFiumFormFiller(PDFiumEngine* engine, bool enable_javascript)
FPDF_FORMFILLINFO::m_pJsPlatform = nullptr; FPDF_FORMFILLINFO::m_pJsPlatform = nullptr;
#if defined(PDF_ENABLE_V8) #if defined(PDF_ENABLE_V8)
if (enable_javascript) { if (script_option != ScriptOption::kNoJavaScript) {
FPDF_FORMFILLINFO::m_pJsPlatform = this; FPDF_FORMFILLINFO::m_pJsPlatform = this;
IPDF_JSPLATFORM::version = 3; IPDF_JSPLATFORM::version = 3;
IPDF_JSPLATFORM::app_alert = Form_Alert; IPDF_JSPLATFORM::app_alert = Form_Alert;
@ -86,22 +87,24 @@ PDFiumFormFiller::PDFiumFormFiller(PDFiumEngine* engine, bool enable_javascript)
IPDF_JSPLATFORM::Field_browse = nullptr; IPDF_JSPLATFORM::Field_browse = nullptr;
} }
#if defined(PDF_ENABLE_XFA) #if defined(PDF_ENABLE_XFA)
FPDF_FORMFILLINFO::xfa_disabled = false; if (script_option == ScriptOption::kJavaScriptAndXFA) {
FPDF_FORMFILLINFO::FFI_EmailTo = Form_EmailTo; FPDF_FORMFILLINFO::xfa_disabled = false;
FPDF_FORMFILLINFO::FFI_DisplayCaret = Form_DisplayCaret; FPDF_FORMFILLINFO::FFI_EmailTo = Form_EmailTo;
FPDF_FORMFILLINFO::FFI_SetCurrentPage = Form_SetCurrentPage; FPDF_FORMFILLINFO::FFI_DisplayCaret = Form_DisplayCaret;
FPDF_FORMFILLINFO::FFI_GetCurrentPageIndex = Form_GetCurrentPageIndex; FPDF_FORMFILLINFO::FFI_SetCurrentPage = Form_SetCurrentPage;
FPDF_FORMFILLINFO::FFI_GetPageViewRect = Form_GetPageViewRect; FPDF_FORMFILLINFO::FFI_GetCurrentPageIndex = Form_GetCurrentPageIndex;
FPDF_FORMFILLINFO::FFI_GetPlatform = Form_GetPlatform; FPDF_FORMFILLINFO::FFI_GetPageViewRect = Form_GetPageViewRect;
FPDF_FORMFILLINFO::FFI_PageEvent = Form_PageEvent; FPDF_FORMFILLINFO::FFI_GetPlatform = Form_GetPlatform;
FPDF_FORMFILLINFO::FFI_PopupMenu = Form_PopupMenu; FPDF_FORMFILLINFO::FFI_PageEvent = Form_PageEvent;
FPDF_FORMFILLINFO::FFI_PostRequestURL = Form_PostRequestURL; FPDF_FORMFILLINFO::FFI_PopupMenu = Form_PopupMenu;
FPDF_FORMFILLINFO::FFI_PutRequestURL = Form_PutRequestURL; FPDF_FORMFILLINFO::FFI_PostRequestURL = Form_PostRequestURL;
FPDF_FORMFILLINFO::FFI_UploadTo = Form_UploadTo; FPDF_FORMFILLINFO::FFI_PutRequestURL = Form_PutRequestURL;
FPDF_FORMFILLINFO::FFI_DownloadFromURL = Form_DownloadFromURL; FPDF_FORMFILLINFO::FFI_UploadTo = Form_UploadTo;
FPDF_FORMFILLINFO::FFI_OpenFile = Form_OpenFile; FPDF_FORMFILLINFO::FFI_DownloadFromURL = Form_DownloadFromURL;
FPDF_FORMFILLINFO::FFI_GotoURL = Form_GotoURL; FPDF_FORMFILLINFO::FFI_OpenFile = Form_OpenFile;
FPDF_FORMFILLINFO::FFI_GetLanguage = Form_GetLanguage; FPDF_FORMFILLINFO::FFI_GotoURL = Form_GotoURL;
FPDF_FORMFILLINFO::FFI_GetLanguage = Form_GetLanguage;
}
#endif // defined(PDF_ENABLE_XFA) #endif // defined(PDF_ENABLE_XFA)
#endif // defined(PDF_ENABLE_V8) #endif // defined(PDF_ENABLE_V8)
} }

@ -19,12 +19,16 @@ class PDFiumEngine;
class PDFiumFormFiller : public FPDF_FORMFILLINFO, public IPDF_JSPLATFORM { class PDFiumFormFiller : public FPDF_FORMFILLINFO, public IPDF_JSPLATFORM {
public: public:
// NOTE: |enable_javascript| is ignored when PDF_ENABLE_V8 is not defined. enum class ScriptOption { kNoJavaScript, kJavaScript, kJavaScriptAndXFA };
PDFiumFormFiller(PDFiumEngine* engine, bool enable_javascript);
// NOTE: |script_option| is ignored when PDF_ENABLE_V8 is not defined.
PDFiumFormFiller(PDFiumEngine* engine, ScriptOption script_option);
PDFiumFormFiller(const PDFiumFormFiller&) = delete; PDFiumFormFiller(const PDFiumFormFiller&) = delete;
PDFiumFormFiller& operator=(const PDFiumFormFiller&) = delete; PDFiumFormFiller& operator=(const PDFiumFormFiller&) = delete;
~PDFiumFormFiller(); ~PDFiumFormFiller();
ScriptOption script_option() const { return script_option_; }
private: private:
friend class FormFillerTest; friend class FormFillerTest;
@ -191,7 +195,7 @@ class PDFiumFormFiller : public FPDF_FORMFILLINFO, public IPDF_JSPLATFORM {
void KillTimer(int timer_id); void KillTimer(int timer_id);
PDFiumEngine* const engine_; PDFiumEngine* const engine_;
const ScriptOption script_option_;
std::map<int, std::unique_ptr<base::RepeatingTimer>> timers_; std::map<int, std::unique_ptr<base::RepeatingTimer>> timers_;
}; };

@ -12,6 +12,7 @@
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "pdf/pdfium/pdfium_engine.h" #include "pdf/pdfium/pdfium_engine.h"
#include "pdf/pdfium/pdfium_form_filler.h"
#include "pdf/ppapi_migration/url_loader.h" #include "pdf/ppapi_migration/url_loader.h"
#include "pdf/test/test_client.h" #include "pdf/test/test_client.h"
#include "pdf/test/test_document_loader.h" #include "pdf/test/test_document_loader.h"
@ -85,8 +86,8 @@ PDFiumTestBase::InitializeEngineWithoutLoading(
const base::FilePath::CharType* pdf_name) { const base::FilePath::CharType* pdf_name) {
InitializeEngineResult result; InitializeEngineResult result;
result.engine = result.engine = std::make_unique<PDFiumEngine>(
std::make_unique<PDFiumEngine>(client, /*enable_javascript=*/false); client, PDFiumFormFiller::ScriptOption::kNoJavaScript);
client->set_engine(result.engine.get()); client->set_engine(result.engine.get());
auto test_loader = auto test_loader =