diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-09-30 21:46:10 +0200 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-10-05 12:03:21 +0000 |
commit | 30570c933fce70af5a492587660a752b398140c2 (patch) | |
tree | 42f9b4006a3d284dea11e37bebce9d17d0d28f24 | |
parent | c89a12ce788db2829ef25f4da967cc62efdb42e8 (diff) | |
download | qtwebengine-chromium-30570c933fce70af5a492587660a752b398140c2.tar.gz |
[Backport] Security issue 1098860
M85: Correctly retrieve the plugin when printing.
The logic in PrintRenderFrameHelper to retrieve a plugin is out of sync
with the logic in WebLocalFrameImpl::PrintBegin(). If
PrintRenderFrameHelper thinks it is printing a webpage, while
WebLocalFrameImpl thinks it is printing a plugin, bad things happen.
Fix this by adding WebLocalFrame::GetPluginToPrint(), to expose the
plugin finding logic in WebLocalFrameImpl. With GetPluginToPrint()
available, PrintRenderFrameHelper can delete its own GetPlugin() helper,
and switch the GetPlugin() callers to use GetPluginToPrint() instead.
Once synchronized, some use cases for printing Flash now work correctly.
(cherry picked from commit f8d7d428b1549ff1f87e3d34c5ca0b53d6ce4e84)
Tbr: japhet@chromium.org
Bug: 1098860
Change-Id: I9500db9ed2d6da0f87dad84c197f738d3a1e3c84
Reviewed-by: Nate Chapin <japhet@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#791564}
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/branch-heads/4183@{#1009}
Cr-Branched-From: 740e9e8a40505392ba5c8e022a8024b3d018ca65-refs/heads/master@{#782793}
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
5 files changed, 48 insertions, 34 deletions
diff --git a/chromium/components/printing/renderer/print_render_frame_helper.cc b/chromium/components/printing/renderer/print_render_frame_helper.cc index 32a331b2d66..09a0bfbd6e6 100644 --- a/chromium/components/printing/renderer/print_render_frame_helper.cc +++ b/chromium/components/printing/renderer/print_render_frame_helper.cc @@ -54,7 +54,6 @@ #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/public/web/web_plugin.h" -#include "third_party/blink/public/web/web_plugin_document.h" #include "third_party/blink/public/web/web_print_params.h" #include "third_party/blink/public/web/web_print_preset_options.h" #include "third_party/blink/public/web/web_script_source.h" @@ -327,17 +326,9 @@ void ComputeWebKitPrintParamsInDesiredDpi( webkit_print_params->pages_per_sheet = print_params.pages_per_sheet; } -blink::WebPlugin* GetPlugin(const blink::WebLocalFrame* frame) { - return frame->GetDocument().IsPluginDocument() - ? frame->GetDocument().To<blink::WebPluginDocument>().Plugin() - : nullptr; -} - -bool PrintingNodeOrPdfFrame(const blink::WebLocalFrame* frame, +bool PrintingNodeOrPdfFrame(blink::WebLocalFrame* frame, const blink::WebNode& node) { - if (!node.IsNull()) - return true; - blink::WebPlugin* plugin = GetPlugin(frame); + blink::WebPlugin* plugin = frame->GetPluginToPrint(node); return plugin && plugin->SupportsPaginatedPrint(); } @@ -2100,7 +2091,7 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type) { // 2. PrintHostMsg_ShowScriptedPrintPreview shows preview once the // document has been loaded. is_scripted_preview_delayed_ = true; - if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) { + if (is_loading_ && print_preview_context_.IsPlugin()) { // Wait for DidStopLoading. Plugins may not know the correct // |is_modifiable| value until they are fully loaded, which occurs when // DidStopLoading() is called. Defer showing the preview until then. @@ -2127,7 +2118,7 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type) { // Wait for DidStopLoading. Continuing with this function while // |is_loading_| is true will cause print preview to hang when try to // print a PDF document. - if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) { + if (is_loading_ && print_preview_context_.IsPlugin()) { on_stop_loading_closure_ = base::Bind(&PrintRenderFrameHelper::RequestPrintPreview, weak_ptr_factory_.GetWeakPtr(), type); @@ -2138,12 +2129,12 @@ void PrintRenderFrameHelper::RequestPrintPreview(PrintPreviewRequestType type) { } case PRINT_PREVIEW_USER_INITIATED_SELECTION: { DCHECK(has_selection); - DCHECK(!GetPlugin(print_preview_context_.source_frame())); + DCHECK(!print_preview_context_.IsPlugin()); params.selection_only = has_selection; break; } case PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE: { - if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) { + if (is_loading_ && print_preview_context_.IsPlugin()) { on_stop_loading_closure_ = base::Bind(&PrintRenderFrameHelper::RequestPrintPreview, weak_ptr_factory_.GetWeakPtr(), type); @@ -2218,7 +2209,7 @@ void PrintRenderFrameHelper::PrintPreviewContext::InitWithFrame( state_ = INITIALIZED; source_frame_.Reset(web_frame); source_node_.Reset(); - CalculateIsModifiable(); + CalculatePluginAttributes(); } void PrintRenderFrameHelper::PrintPreviewContext::InitWithNode( @@ -2229,7 +2220,7 @@ void PrintRenderFrameHelper::PrintPreviewContext::InitWithNode( state_ = INITIALIZED; source_frame_.Reset(web_node.GetDocument().GetFrame()); source_node_ = web_node; - CalculateIsModifiable(); + CalculatePluginAttributes(); } void PrintRenderFrameHelper::PrintPreviewContext::OnPrintPreview() { @@ -2348,6 +2339,11 @@ bool PrintRenderFrameHelper::PrintPreviewContext::IsRendering() const { return state_ == RENDERING || state_ == DONE; } +bool PrintRenderFrameHelper::PrintPreviewContext::IsPlugin() const { + DCHECK(state_ != UNINITIALIZED); + return is_plugin_; +} + bool PrintRenderFrameHelper::PrintPreviewContext::IsModifiable() const { DCHECK(state_ != UNINITIALIZED); return is_modifiable_; @@ -2418,9 +2414,9 @@ void PrintRenderFrameHelper::PrintPreviewContext::ClearContext() { error_ = PREVIEW_ERROR_NONE; } -void PrintRenderFrameHelper::PrintPreviewContext::CalculateIsModifiable() { - // The only kind of node we can print right now is a PDF node. - is_modifiable_ = !PrintingNodeOrPdfFrame(source_frame(), source_node_); +void PrintRenderFrameHelper::PrintPreviewContext::CalculatePluginAttributes() { + is_plugin_ = !!source_frame()->GetPluginToPrint(source_node_); + is_modifiable_ = !PrintingNodeOrPdfFrame(source_frame(), source_node_); } void PrintRenderFrameHelper::SetPrintPagesParams( diff --git a/chromium/components/printing/renderer/print_render_frame_helper.h b/chromium/components/printing/renderer/print_render_frame_helper.h index 6e2d7e1467b..ce56acfd323 100644 --- a/chromium/components/printing/renderer/print_render_frame_helper.h +++ b/chromium/components/printing/renderer/print_render_frame_helper.h @@ -433,6 +433,7 @@ class PrintRenderFrameHelper // Helper functions int GetNextPageNumber(); bool IsRendering() const; + bool IsPlugin() const; bool IsModifiable() const; bool HasSelection(); bool IsLastPageOfPrintReadyMetafile() const; @@ -469,7 +470,7 @@ class PrintRenderFrameHelper // Reset some of the internal rendering context. void ClearContext(); - void CalculateIsModifiable(); + void CalculatePluginAttributes(); // Specifies what to render for print preview. FrameReference source_frame_; @@ -487,6 +488,9 @@ class PrintRenderFrameHelper // List of page indices that need to be rendered. std::vector<int> pages_to_render_; + // True, if the document source is a plugin. + bool is_plugin_ = false; + // True, if the document source is modifiable. e.g. HTML and not PDF. bool is_modifiable_; diff --git a/chromium/third_party/blink/public/web/web_local_frame.h b/chromium/third_party/blink/public/web/web_local_frame.h index 6c228c25f99..4b0c755062a 100644 --- a/chromium/third_party/blink/public/web/web_local_frame.h +++ b/chromium/third_party/blink/public/web/web_local_frame.h @@ -774,13 +774,16 @@ class WebLocalFrame : public WebFrame { // This function should be called before pairs of PrintBegin() and PrintEnd(). virtual void DispatchBeforePrintEvent() = 0; + // Get the plugin to print, if any. The |constrain_to_node| parameter is the + // same as the one for PrintBegin() below. + virtual WebPlugin* GetPluginToPrint(const WebNode& constrain_to_node) = 0; + // Reformats the WebFrame for printing. WebPrintParams specifies the printable // content size, paper size, printable area size, printer DPI and print - // scaling option. If constrainToNode node is specified, then only the given + // scaling option. If |constrain_to_node| is specified, then only the given // node is printed (for now only plugins are supported), instead of the entire // frame. - // Returns the number of pages that can be printed at the given - // page size. + // Returns the number of pages that can be printed at the given page size. virtual int PrintBegin(const WebPrintParams&, const WebNode& constrain_to_node = WebNode()) = 0; diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 0226d3c31c1..7e49028d641 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc @@ -1501,20 +1501,27 @@ void WebLocalFrameImpl::DispatchPrintEventRecursively( } } -int WebLocalFrameImpl::PrintBegin(const WebPrintParams& print_params, - const WebNode& constrain_to_node) { - DCHECK(!GetFrame()->GetDocument()->IsFrameSet()); - WebPluginContainerImpl* plugin_container = nullptr; +WebPluginContainerImpl* WebLocalFrameImpl::GetPluginToPrintHelper( + const WebNode& constrain_to_node) { if (constrain_to_node.IsNull()) { // If this is a plugin document, check if the plugin supports its own - // printing. If it does, we will delegate all printing to that. - plugin_container = GetFrame()->GetWebPluginContainer(); - } else { - // We only support printing plugin nodes for now. - plugin_container = - ToWebPluginContainerImpl(constrain_to_node.PluginContainer()); + // printing. If it does, we will delegate all printing to that.a + return GetFrame()->GetWebPluginContainer(); } + return ToWebPluginContainerImpl(constrain_to_node.PluginContainer()); +} + +WebPlugin* WebLocalFrameImpl::GetPluginToPrint( + const WebNode& constrain_to_node) { + WebPluginContainerImpl* plugin_container = + GetPluginToPrintHelper(constrain_to_node); + return plugin_container ? plugin_container->Plugin() : nullptr; +} +int WebLocalFrameImpl::PrintBegin(const WebPrintParams& print_params, + const WebNode& constrain_to_node) { + WebPluginContainerImpl* plugin_container = + GetPluginToPrintHelper(constrain_to_node); if (plugin_container && plugin_container->SupportsPaginatedPrint()) { print_context_ = new ChromePluginPrintContext(GetFrame(), plugin_container, print_params); diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 72bead5b301..7b393b6ee9b 100644 --- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h @@ -214,6 +214,7 @@ class CORE_EXPORT WebLocalFrameImpl final void DeleteSurroundingTextInCodePoints(int before, int after) override; void SetCaretVisible(bool) override; void DispatchBeforePrintEvent() override; + WebPlugin* GetPluginToPrint(const WebNode& constrain_to_node) override; int PrintBegin(const WebPrintParams&, const WebNode& constrain_to_node) override; float PrintPage(int page_to_print, cc::PaintCanvas*) override; @@ -470,6 +471,9 @@ class CORE_EXPORT WebLocalFrameImpl final // A helper for DispatchBeforePrintEvent() and DispatchAfterPrintEvent(). void DispatchPrintEventRecursively(const AtomicString& event_type); + WebPluginContainerImpl* GetPluginToPrintHelper( + const WebNode& constrain_to_node); + Node* ContextMenuNodeInner() const; void BindDevToolsAgentRequest(mojom::blink::DevToolsAgentAssociatedRequest); |