0

[unseasoned-pdf] Merge common plugin initialization logic

Consolidates plugin initialization logic shared between the Pepper and
the unseasoned PDF plugins into PdfViewPluginBase::InitializeBase(). The
duplication here is a perennial source of bugs, including a few that are
blocking unseasoned Print Preview (crbug.com/1253984).

This change also tries to be more consistent about the order of
initialization between the Pepper and the unseasoned plugins.

Bug: 1232152, 1253984
Change-Id: I65e472c808b2a0ea89e884e5c744a9db1ec8a3c7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3212727
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Commit-Queue: K. Moon <kmoon@chromium.org>
Cr-Commit-Position: refs/heads/main@{#929468}
This commit is contained in:
K. Moon
2021-10-07 22:59:46 +00:00
committed by Chromium LUCI CQ
parent 23be872650
commit 32e98087f2
8 changed files with 147 additions and 130 deletions

@ -334,7 +334,6 @@ if (enable_pdf) {
"//base",
"//build:chromeos_buildflags",
"//net",
"//pdf:buildflags",
"//ppapi/cpp:objects",
"//ppapi/cpp/private:internal_module",
"//skia",
@ -342,6 +341,7 @@ if (enable_pdf) {
"//third_party/blink/public/common:headers",
"//ui/base",
"//ui/base/cursor/mojom:cursor_type",
"//url",
]
}

@ -22,6 +22,7 @@
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/values.h"
@ -30,7 +31,6 @@
#include "net/base/escape.h"
#include "pdf/accessibility.h"
#include "pdf/accessibility_structs.h"
#include "pdf/buildflags.h"
#include "pdf/document_attachment_info.h"
#include "pdf/document_metadata.h"
#include "pdf/pdfium/pdfium_engine.h"
@ -72,6 +72,7 @@
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
#include "pdf/ppapi_migration/pdfium_font_linux.h"
@ -441,44 +442,33 @@ bool OutOfProcessInstance::Init(uint32_t argc,
pp::Var document_url_var = pp::URLUtil_Dev::Get()->GetDocumentURL(this);
if (!document_url_var.is_string())
return false;
// Check if the PDF is being loaded in the PDF chrome extension. We only allow
// the plugin to be loaded in the extension and print preview to avoid
// exposing sensitive APIs directly to external websites.
//
// This is enforced before launching the plugin process (see
// ChromeContentBrowserClient::ShouldAllowPluginCreation), so below we just do
// a CHECK as a defense-in-depth.
std::string document_url = document_url_var.AsString();
base::StringPiece document_url_piece(document_url);
set_is_print_preview(IsPrintPreviewUrl(document_url_piece));
ValidateDocumentUrl(document_url_piece);
GURL document_url(document_url_var.AsString());
// Allow the plugin to handle find requests.
SetPluginToHandleFindRequests();
text_input_ = std::make_unique<pp::TextInput_Dev>(this);
PDFiumFormFiller::ScriptOption script_option =
PDFiumFormFiller::DefaultScriptOption();
bool has_edits = false;
const char* src_url = nullptr;
const char* original_url = nullptr;
const char* top_level_url = nullptr;
bool full_frame = false;
SkColor background_color = SK_ColorTRANSPARENT;
PDFiumFormFiller::ScriptOption script_option =
PDFiumFormFiller::DefaultScriptOption();
bool has_edits = false;
for (uint32_t i = 0; i < argc; ++i) {
if (strcmp(argn[i], "original-url") == 0) {
original_url = argv[i];
} else if (strcmp(argn[i], "src") == 0) {
if (strcmp(argn[i], "src") == 0) {
src_url = argv[i];
} else if (strcmp(argn[i], "original-url") == 0) {
original_url = argv[i];
} else if (strcmp(argn[i], "top-level-url") == 0) {
top_level_url = argv[i];
} else if (strcmp(argn[i], "full-frame") == 0) {
set_full_frame(true);
full_frame = true;
} else if (strcmp(argn[i], "background-color") == 0) {
SkColor background_color;
if (!base::StringToUint(argv[i], &background_color))
return false;
SetBackgroundColor(background_color);
} else if (strcmp(argn[i], "javascript") == 0) {
if (strcmp(argv[i], "allow") != 0)
script_option = PDFiumFormFiller::ScriptOption::kNoJavaScript;
@ -493,27 +483,14 @@ bool OutOfProcessInstance::Init(uint32_t argc,
if (!original_url)
original_url = src_url;
InitializeEngine(std::make_unique<PDFiumEngine>(this, script_option));
// 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
// it know the url to load. By not loading here we avoid loading the same
// document twice.
if (IsPrintPreview())
return true;
LoadUrl(src_url, /*is_print_preview=*/false);
set_url(original_url);
// Not all edits go through the PDF plugin's form filler. The plugin instance
// can be restarted by exiting annotation mode on ChromeOS, which can set the
// document to an edited state.
set_edit_mode(has_edits);
#if !BUILDFLAG(ENABLE_INK)
DCHECK(!edit_mode());
#endif // !BUILDFLAG(ENABLE_INK)
pp::PDF::SetCrashData(this, original_url, top_level_url);
InitializeBase(std::make_unique<PDFiumEngine>(this, script_option),
/*embedder_origin=*/document_url.GetOrigin().spec(),
/*src_url=*/src_url,
/*original_url=*/original_url,
/*full_frame=*/full_frame,
/*background_color=*/background_color,
/*has_edits=*/has_edits);
return true;
}

@ -85,7 +85,7 @@ constexpr base::TimeDelta kFindResultCooldown = base::Milliseconds(100);
constexpr char kChromePrintHost[] = "chrome://print/";
constexpr char kChromeExtensionHost[] =
"chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai";
"chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/";
// Same value as printing::COMPLETE_PREVIEW_DOCUMENT_INDEX.
constexpr int kCompletePDFIndex = -1;
@ -116,6 +116,10 @@ base::Value PrepareReplyMessage(base::StringPiece reply_type,
return reply;
}
bool IsPrintPreviewUrl(base::StringPiece url) {
return base::StartsWith(url, kChromePrintHost);
}
int ExtractPrintPreviewPageIndex(base::StringPiece src_url) {
// Sample `src_url` format: chrome://print/id/page_index/print.pdf
// The page_index is zero-based, but can be negative with special meanings.
@ -144,6 +148,48 @@ PdfViewPluginBase::PdfViewPluginBase() = default;
PdfViewPluginBase::~PdfViewPluginBase() = default;
void PdfViewPluginBase::InitializeBase(std::unique_ptr<PDFiumEngine> engine,
base::StringPiece embedder_origin,
base::StringPiece src_url,
base::StringPiece original_url,
bool full_frame,
SkColor background_color,
bool has_edits) {
// Check if the PDF is being loaded in the PDF chrome extension. We only allow
// the plugin to be loaded in the extension and print preview to avoid
// exposing sensitive APIs directly to external websites.
//
// This is enforced before launching the plugin process (see
// ChromeContentBrowserClient::ShouldAllowPluginCreation), so below we just do
// a CHECK as a defense-in-depth.
is_print_preview_ = IsPrintPreviewUrl(embedder_origin);
CHECK(IsPrintPreview() || embedder_origin == kChromeExtensionHost);
full_frame_ = full_frame;
background_color_ = background_color;
DCHECK(engine);
engine_ = std::move(engine);
// 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
// it know the url to load. By not loading here we avoid loading the same
// document twice.
if (IsPrintPreview())
return;
LoadUrl(src_url, /*is_print_preview=*/false);
url_ = std::string(original_url);
// Not all edits go through the PDF plugin's form filler. The plugin instance
// can be restarted by exiting annotation mode on ChromeOS, which can set the
// document to an edited state.
edit_mode_ = has_edits;
#if !BUILDFLAG(ENABLE_INK)
DCHECK(!edit_mode_);
#endif // !BUILDFLAG(ENABLE_INK)
}
void PdfViewPluginBase::ProposeDocumentLayout(const DocumentLayout& layout) {
base::Value message(base::Value::Type::DICTIONARY);
message.SetStringKey("type", "documentDimensions");
@ -693,7 +739,8 @@ bool PdfViewPluginBase::UnsupportedFeatureIsReportedForTesting(
return base::Contains(unsupported_features_reported_, feature);
}
void PdfViewPluginBase::InitializeEngine(std::unique_ptr<PDFiumEngine> engine) {
void PdfViewPluginBase::InitializeEngineForTesting(
std::unique_ptr<PDFiumEngine> engine) {
DCHECK(engine);
engine_ = std::move(engine);
}
@ -706,16 +753,11 @@ void PdfViewPluginBase::DestroyPreviewEngine() {
preview_engine_.reset();
}
void PdfViewPluginBase::ValidateDocumentUrl(base::StringPiece document_url) {
CHECK(base::StartsWith(document_url, kChromeExtensionHost) ||
IsPrintPreview());
}
void PdfViewPluginBase::LoadUrl(const std::string& url, bool is_print_preview) {
void PdfViewPluginBase::LoadUrl(base::StringPiece url, bool is_print_preview) {
last_progress_sent_ = 0;
UrlRequest request;
request.url = url;
request.url = std::string(url);
request.method = "GET";
request.ignore_redirects = true;
@ -989,11 +1031,6 @@ void PdfViewPluginBase::SetZoom(double scale) {
OnGeometryChanged(old_zoom, device_scale_);
}
// static
bool PdfViewPluginBase::IsPrintPreviewUrl(base::StringPiece url) {
return base::StartsWith(url, kChromePrintHost);
}
// static
base::Value::DictStorage PdfViewPluginBase::DictFromRect(
const gfx::Rect& rect) {
@ -1109,8 +1146,8 @@ void PdfViewPluginBase::HandleResetPrintPreviewModeMessage(
document_load_state_ = DocumentLoadState::kLoading;
LoadUrl(GetURL(), /*is_print_preview=*/false);
preview_engine_.reset();
InitializeEngine(std::make_unique<PDFiumEngine>(
this, PDFiumFormFiller::ScriptOption::kNoJavaScript));
engine_ = std::make_unique<PDFiumEngine>(
this, PDFiumFormFiller::ScriptOption::kNoJavaScript);
engine()->SetGrayscale(is_grayscale);
paint_manager_.InvalidateRect(gfx::Rect(plugin_rect().size()));
@ -1180,9 +1217,8 @@ void PdfViewPluginBase::HandleSelectAllMessage(const base::Value& /*message*/) {
void PdfViewPluginBase::HandleSetBackgroundColorMessage(
const base::Value& message) {
const SkColor background_color =
background_color_ =
base::checked_cast<SkColor>(message.FindDoubleKey("color").value());
SetBackgroundColor(background_color);
}
void PdfViewPluginBase::HandleSetReadOnlyMessage(const base::Value& message) {

@ -17,6 +17,7 @@
#include "base/containers/queue.h"
#include "base/i18n/rtl.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece_forward.h"
#include "base/values.h"
#include "pdf/accessibility_structs.h"
#include "pdf/paint_manager.h"
@ -160,10 +161,16 @@ class PdfViewPluginBase : public PDFEngine::Client,
return notified_browser_about_unsupported_feature_;
}
void InitializeEngineForTesting(std::unique_ptr<PDFiumEngine> engine);
void set_full_frame_for_testing(bool full_frame) { full_frame_ = full_frame; }
DocumentLoadState document_load_state_for_testing() const {
return document_load_state_;
}
bool edit_mode_for_testing() const { return edit_mode_; }
protected:
struct BackgroundPart {
gfx::Rect location;
@ -173,9 +180,17 @@ class PdfViewPluginBase : public PDFEngine::Client,
PdfViewPluginBase();
~PdfViewPluginBase() override;
// Initializes the main `PDFiumEngine` with `engine`. Any existing engine will
// be replaced. `engine` must not be nullptr.
void InitializeEngine(std::unique_ptr<PDFiumEngine> engine);
// Performs initialization common to all implementations of this plugin.
// `engine` should be an appropriately-configured PDF engine, and
// `embedder_origin` should be the origin of the plugin's embedder. The other
// parameters come from the corresponding plugin attributes.
void InitializeBase(std::unique_ptr<PDFiumEngine> engine,
base::StringPiece embedder_origin,
base::StringPiece src_url,
base::StringPiece original_url,
bool full_frame,
SkColor background_color,
bool has_edits);
// Destroys the main `PDFiumEngine`. Subclasses should call this method in
// their destructor to ensure the engine is destroyed first.
@ -188,11 +203,9 @@ class PdfViewPluginBase : public PDFEngine::Client,
const PDFiumEngine* engine() const { return engine_.get(); }
PDFiumEngine* engine() { return engine_.get(); }
void ValidateDocumentUrl(base::StringPiece document_url);
// Starts loading `url`. If `is_print_preview` is `true`, load for print
// preview instead of normal PDF viewing.
void LoadUrl(const std::string& url, bool is_print_preview);
void LoadUrl(base::StringPiece url, bool is_print_preview);
// Gets a weak pointer with a lifetime matching the derived class.
virtual base::WeakPtr<PdfViewPluginBase> GetWeakPtr() = 0;
@ -355,8 +368,6 @@ class PdfViewPluginBase : public PDFEngine::Client,
// Records user actions.
virtual void UserMetricsRecordAction(const std::string& action) = 0;
void set_url(const std::string& url) { url_ = url; }
ui::mojom::CursorType cursor_type() const { return cursor_type_; }
void set_cursor_type(ui::mojom::CursorType cursor_type) {
cursor_type_ = cursor_type;
@ -365,7 +376,6 @@ class PdfViewPluginBase : public PDFEngine::Client,
const std::string& link_under_cursor() const { return link_under_cursor_; }
bool full_frame() const { return full_frame_; }
void set_full_frame(bool full_frame) { full_frame_ = full_frame; }
SkBitmap& mutable_image_data() { return image_data_; }
@ -375,10 +385,6 @@ class PdfViewPluginBase : public PDFEngine::Client,
const gfx::Rect& plugin_rect() const { return plugin_rect_; }
void SetBackgroundColor(SkColor background_color) {
background_color_ = background_color;
}
// Sets the new zoom scale.
void SetZoom(double scale);
@ -390,15 +396,6 @@ class PdfViewPluginBase : public PDFEngine::Client,
return accessibility_state_;
}
bool edit_mode() const { return edit_mode_; }
void set_edit_mode(bool edit_mode) { edit_mode_ = edit_mode; }
void set_is_print_preview(bool is_print_preview) {
is_print_preview_ = is_print_preview;
}
static bool IsPrintPreviewUrl(base::StringPiece url);
static constexpr bool IsSaveDataSizeValid(size_t size) {
return size > 0 && size <= kMaximumSavedFileSize;
}

@ -136,13 +136,10 @@ class FakePdfViewPluginBase : public PdfViewPluginBase {
public:
// Public for testing.
using PdfViewPluginBase::accessibility_state;
using PdfViewPluginBase::edit_mode;
using PdfViewPluginBase::engine;
using PdfViewPluginBase::full_frame;
using PdfViewPluginBase::HandleMessage;
using PdfViewPluginBase::InitializeEngine;
using PdfViewPluginBase::LoadUrl;
using PdfViewPluginBase::set_full_frame;
using PdfViewPluginBase::SetZoom;
using PdfViewPluginBase::UpdateGeometryOnPluginRectChanged;
using PdfViewPluginBase::UpdateScroll;
@ -383,7 +380,7 @@ class PdfViewPluginBaseWithEngineTest : public PdfViewPluginBaseTest {
void SetUp() override {
auto engine =
std::make_unique<testing::NiceMock<TestPDFiumEngine>>(&fake_plugin_);
fake_plugin_.InitializeEngine(std::move(engine));
fake_plugin_.InitializeEngineForTesting(std::move(engine));
}
protected:
@ -417,7 +414,7 @@ class PdfViewPluginBaseWithDocInfoTest
void SetUp() override {
std::unique_ptr<TestPDFiumEngineWithDocInfo> engine =
std::make_unique<TestPDFiumEngineWithDocInfo>(&fake_plugin_);
fake_plugin_.InitializeEngine(std::move(engine));
fake_plugin_.InitializeEngineForTesting(std::move(engine));
// Initialize some arbitrary document information for the engine.
static_cast<TestPDFiumEngineWithDocInfo*>(fake_plugin_.engine())
@ -499,7 +496,7 @@ TEST_F(PdfViewPluginBaseTest, DocumentLoadProgressResetByLoadUrl) {
}
TEST_F(PdfViewPluginBaseTest, CreateUrlLoaderInFullFrame) {
fake_plugin_.set_full_frame(true);
fake_plugin_.set_full_frame_for_testing(true);
ASSERT_TRUE(fake_plugin_.full_frame());
EXPECT_FALSE(fake_plugin_.GetDidCallStartLoadingForTesting());
@ -527,7 +524,7 @@ TEST_F(PdfViewPluginBaseTest, CreateUrlLoaderWithoutFullFrame) {
TEST_F(PdfViewPluginBaseWithDocInfoTest,
DocumentLoadCompleteInFullFramePdfViewerWithAccessibilityEnabled) {
// Notify the render frame about document loading.
fake_plugin_.set_full_frame(true);
fake_plugin_.set_full_frame_for_testing(true);
ASSERT_TRUE(fake_plugin_.full_frame());
fake_plugin_.CreateUrlLoader();
@ -570,7 +567,7 @@ TEST_F(PdfViewPluginBaseWithDocInfoTest,
TEST_F(PdfViewPluginBaseWithDocInfoTest,
DocumentLoadCompleteInFullFramePdfViewerWithAccessibilityDisabled) {
// Notify the render frame about document loading.
fake_plugin_.set_full_frame(true);
fake_plugin_.set_full_frame_for_testing(true);
ASSERT_TRUE(fake_plugin_.full_frame());
fake_plugin_.CreateUrlLoader();
@ -663,7 +660,7 @@ TEST_F(PdfViewPluginBaseWithoutDocInfoTest, DocumentLoadCompletePostMessages) {
TEST_F(PdfViewPluginBaseTest, DocumentLoadFailedWithNotifiedRenderFrame) {
// Notify the render frame about document loading.
fake_plugin_.set_full_frame(true);
fake_plugin_.set_full_frame_for_testing(true);
ASSERT_TRUE(fake_plugin_.full_frame());
fake_plugin_.CreateUrlLoader();
@ -697,7 +694,7 @@ TEST_F(PdfViewPluginBaseTest, DocumentLoadFailedWithoutNotifiedRenderFrame) {
}
TEST_F(PdfViewPluginBaseTest, DocumentHasUnsupportedFeatureInFullFrame) {
fake_plugin_.set_full_frame(true);
fake_plugin_.set_full_frame_for_testing(true);
ASSERT_TRUE(fake_plugin_.full_frame());
// Arbitrary feature names and their matching metric names.
@ -763,7 +760,7 @@ TEST_F(PdfViewPluginBaseTest, EnteredEditMode) {
base::Value expected_response(base::Value::Type::DICTIONARY);
expected_response.SetStringKey("type", "setIsEditing");
EXPECT_TRUE(fake_plugin_.edit_mode());
EXPECT_TRUE(fake_plugin_.edit_mode_for_testing());
ASSERT_EQ(1u, fake_plugin_.sent_messages().size());
EXPECT_EQ(expected_response, fake_plugin_.sent_messages()[0]);
}
@ -772,7 +769,7 @@ using PdfViewPluginBaseSaveTest = PdfViewPluginBaseWithEngineTest;
#if BUILDFLAG(ENABLE_INK)
TEST_F(PdfViewPluginBaseSaveTest, SaveAnnotationInNonEditMode) {
ASSERT_FALSE(fake_plugin_.edit_mode());
ASSERT_FALSE(fake_plugin_.edit_mode_for_testing());
static constexpr char kSaveAnnotInNonEditModeToken[] =
"save-annot-in-non-edit-mode-token";
@ -791,7 +788,7 @@ TEST_F(PdfViewPluginBaseSaveTest, SaveAnnotationInNonEditMode) {
TEST_F(PdfViewPluginBaseSaveTest, SaveAnnotationInEditMode) {
fake_plugin_.EnteredEditMode();
ASSERT_TRUE(fake_plugin_.edit_mode());
ASSERT_TRUE(fake_plugin_.edit_mode_for_testing());
static constexpr char kSaveAnnotInEditModeToken[] =
"save-annot-in-edit-mode-token";
@ -810,7 +807,7 @@ TEST_F(PdfViewPluginBaseSaveTest, SaveAnnotationInEditMode) {
#endif // BUILDFLAG(ENABLE_INK)
TEST_F(PdfViewPluginBaseSaveTest, SaveOriginalInNonEditMode) {
ASSERT_FALSE(fake_plugin_.edit_mode());
ASSERT_FALSE(fake_plugin_.edit_mode_for_testing());
static constexpr char kSaveOriginalInNonEditModeToken[] =
"save-original-in-non-edit-mode-token";
@ -831,7 +828,7 @@ TEST_F(PdfViewPluginBaseSaveTest, SaveOriginalInNonEditMode) {
TEST_F(PdfViewPluginBaseSaveTest, SaveOriginalInEditMode) {
fake_plugin_.EnteredEditMode();
ASSERT_TRUE(fake_plugin_.edit_mode());
ASSERT_TRUE(fake_plugin_.edit_mode_for_testing());
static constexpr char kSaveOriginalInEditModeToken[] =
"save-original-in-edit-mode-token";
@ -853,7 +850,7 @@ TEST_F(PdfViewPluginBaseSaveTest, SaveOriginalInEditMode) {
#if BUILDFLAG(ENABLE_INK)
TEST_F(PdfViewPluginBaseSaveTest, SaveEditedInNonEditMode) {
ASSERT_FALSE(fake_plugin_.edit_mode());
ASSERT_FALSE(fake_plugin_.edit_mode_for_testing());
static constexpr char kSaveEditedInNonEditModeToken[] =
"save-edited-in-non-edit-mode";
@ -872,7 +869,7 @@ TEST_F(PdfViewPluginBaseSaveTest, SaveEditedInNonEditMode) {
TEST_F(PdfViewPluginBaseSaveTest, SaveEditedInEditMode) {
fake_plugin_.EnteredEditMode();
ASSERT_TRUE(fake_plugin_.edit_mode());
ASSERT_TRUE(fake_plugin_.edit_mode_for_testing());
static constexpr char kSaveEditedInEditModeToken[] =
"save-edited-in-edit-mode-token";

@ -48,6 +48,7 @@
#include "third_party/blink/public/common/metrics/document_update_reason.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-shared.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_text_input_type.h"
#include "third_party/blink/public/platform/web_url.h"
@ -57,6 +58,7 @@
#include "third_party/blink/public/web/web_associated_url_loader.h"
#include "third_party/blink/public/web/web_associated_url_loader_options.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
@ -65,6 +67,7 @@
#include "third_party/blink/public/web/web_print_preset_options.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/base/cursor/cursor.h"
@ -220,6 +223,18 @@ class BlinkContainerWrapper final : public PdfViewWebPlugin::ContainerWrapper {
widget->UpdateSelectionBounds();
}
std::string GetEmbedderOriginString() override {
auto* frame = GetFrame();
if (!frame)
return {};
auto* parent_frame = frame->Parent();
if (!parent_frame)
return {};
return GURL(parent_frame->GetSecurityOrigin().ToString().Utf8()).spec();
}
blink::WebLocalFrame* GetFrame() override {
return container_->GetDocument().GetFrame();
}
@ -275,26 +290,15 @@ bool PdfViewWebPlugin::InitializeCommon(
std::unique_ptr<ContainerWrapper> container_wrapper,
std::unique_ptr<PDFiumEngine> engine) {
container_wrapper_ = std::move(container_wrapper);
post_message_sender_.set_container(Container());
// Check if the PDF is being loaded in the PDF chrome extension. We only allow
// the plugin to be loaded in the extension and print preview to avoid
// exposing sensitive APIs directly to external websites.
std::string document_url;
auto* container = Container();
if (container) {
GURL maybe_url(container->GetDocument().Url());
if (maybe_url.is_valid())
document_url = maybe_url.possibly_invalid_spec();
}
base::StringPiece document_url_piece(document_url);
set_is_print_preview(IsPrintPreviewUrl(document_url_piece));
// TODO(crbug.com/1123621): Consider calling ValidateDocumentUrl() or
// something like it once the process model has been finalized.
// Allow the plugin to handle touch events.
container_wrapper_->RequestTouchEventType(
blink::WebPluginContainer::kTouchEventRequestTypeRaw);
// Allow the plugin to handle find requests.
if (container)
container->UsePluginAsFindHandler();
if (Container())
Container()->UsePluginAsFindHandler();
absl::optional<ParsedParams> params = ParseWebPluginParams(initial_params_);
@ -304,21 +308,19 @@ bool PdfViewWebPlugin::InitializeCommon(
if (!params.has_value())
return false;
set_full_frame(params->full_frame);
if (params->background_color.has_value())
SetBackgroundColor(params->background_color.value());
PerProcessInitializer::GetInstance().Acquire();
InitializeEngine(
// TODO(crbug.com/1257666): Implement "has-edits" support.
InitializeBase(
engine ? std::move(engine)
: std::make_unique<PDFiumEngine>(this, params->script_option));
LoadUrl(params->src_url, /*is_print_preview=*/false);
set_url(params->original_url);
post_message_sender_.set_container(Container());
container_wrapper_->RequestTouchEventType(
blink::WebPluginContainer::kTouchEventRequestTypeRaw);
: std::make_unique<PDFiumEngine>(this, params->script_option),
/*embedder_origin=*/container_wrapper_->GetEmbedderOriginString(),
/*src_url=*/params->src_url,
/*original_url=*/params->original_url,
/*full_frame=*/params->full_frame,
/*background_color=*/
params->background_color.value_or(SK_ColorTRANSPARENT),
/*has_edits=*/false);
return true;
}
@ -329,8 +331,8 @@ void PdfViewWebPlugin::Destroy() {
DestroyPreviewEngine();
DestroyEngine();
PerProcessInitializer::GetInstance().Release();
container_wrapper_.reset();
post_message_sender_.set_container(nullptr);
container_wrapper_.reset();
}
delete this;

@ -8,6 +8,7 @@
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/weak_ptr.h"
@ -112,6 +113,9 @@ class PdfViewWebPlugin final : public PdfViewPluginBase,
// Notifies the frame widget about the selection bound change.
virtual void UpdateSelectionBounds() = 0;
// Gets the embedder's origin as a serialized string.
virtual std::string GetEmbedderOriginString() = 0;
// Returns the local frame to which the web plugin container belongs.
virtual blink::WebLocalFrame* GetFrame() = 0;

@ -182,6 +182,10 @@ class FakeContainerWrapper : public PdfViewWebPlugin::ContainerWrapper {
MOCK_METHOD(void, UpdateSelectionBounds, (), (override));
std::string GetEmbedderOriginString() override {
return "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/";
}
blink::WebLocalFrame* GetFrame() override { return nullptr; }
blink::WebLocalFrameClient* GetWebLocalFrameClient() override {