Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Unified Diff: extensions/renderer/programmatic_script_injector.cc

Issue 1216453002: [Extensions] Handle some funny cases in script injection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Ben's Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/programmatic_script_injector.cc
diff --git a/extensions/renderer/programmatic_script_injector.cc b/extensions/renderer/programmatic_script_injector.cc
index bc94d043b27c9b756061ec694b95e1c9af7e45de..3c9b938f27968c8aad806ceab25b73e300c99c0b 100644
--- a/extensions/renderer/programmatic_script_injector.cc
+++ b/extensions/renderer/programmatic_script_injector.cc
@@ -9,6 +9,7 @@
#include "base/values.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_frame_observer.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/manifest_constants.h"
@@ -22,13 +23,33 @@
namespace extensions {
+// Watches for the deletion of a RenderFrame, after which is_valid will return
+// false.
+class ProgrammaticScriptInjector::FrameWatcher
+ : public content::RenderFrameObserver {
+ public:
+ explicit FrameWatcher(content::RenderFrame* render_frame)
+ : content::RenderFrameObserver(render_frame), is_valid_(true) {}
+ ~FrameWatcher() override {}
+
+ bool is_frame_valid() const { return is_valid_; }
+
+ private:
+ void FrameDetached() override { is_valid_ = false; }
+ void OnDestruct() override { is_valid_ = false; }
+
+ bool is_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameWatcher);
+};
+
ProgrammaticScriptInjector::ProgrammaticScriptInjector(
const ExtensionMsg_ExecuteCode_Params& params,
content::RenderFrame* render_frame)
: params_(new ExtensionMsg_ExecuteCode_Params(params)),
- url_(ScriptContext::GetDataSourceURLForFrame(
- render_frame->GetWebFrame())),
- render_frame_(render_frame),
+ url_(
+ ScriptContext::GetDataSourceURLForFrame(render_frame->GetWebFrame())),
+ frame_watcher_(new FrameWatcher(render_frame)),
finished_(false) {
effective_url_ = ScriptContext::GetEffectiveDocumentURL(
render_frame->GetWebFrame(), url_, params.match_about_blank);
@@ -150,12 +171,15 @@ void ProgrammaticScriptInjector::Finish(const std::string& error) {
DCHECK(!finished_);
finished_ = true;
- render_frame_->Send(new ExtensionHostMsg_ExecuteCodeFinished(
- render_frame_->GetRoutingID(),
- params_->request_id,
- error,
- url_,
- results_));
+ // It's possible that the render frame was destroyed in the course of
+ // injecting scripts. Don't respond if it was (the browser side watches for
+ // frame deletions so nothing is left hanging).
+ if (frame_watcher_->is_frame_valid()) {
+ frame_watcher_->render_frame()->Send(
+ new ExtensionHostMsg_ExecuteCodeFinished(
+ frame_watcher_->render_frame()->GetRoutingID(), params_->request_id,
+ error, url_, results_));
+ }
}
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698