| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium 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 #include "extensions/renderer/script_context_set.h" | 5 #include "extensions/renderer/script_context_set.h" |
| 6 | 6 |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "content/public/common/url_constants.h" | 8 #include "content/public/common/url_constants.h" |
| 9 #include "content/public/renderer/render_frame.h" | 9 #include "content/public/renderer/render_frame.h" |
| 10 #include "extensions/common/extension.h" | 10 #include "extensions/common/extension.h" |
| 11 #include "extensions/renderer/extension_groups.h" | 11 #include "extensions/renderer/extension_groups.h" |
| 12 #include "extensions/renderer/script_context.h" | 12 #include "extensions/renderer/script_context.h" |
| 13 #include "extensions/renderer/script_injection.h" | 13 #include "extensions/renderer/script_injection.h" |
| 14 #include "third_party/WebKit/public/web/WebDocument.h" | 14 #include "third_party/WebKit/public/web/WebDocument.h" |
| 15 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 15 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 16 #include "v8/include/v8.h" | 16 #include "v8/include/v8.h" |
| 17 | 17 |
| 18 namespace extensions { | 18 namespace extensions { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 // There is only ever one instance of the ScriptContextSet. | 21 // There is only ever one instance of the ScriptContextSet. |
| 22 ScriptContextSet* g_context_set = nullptr; | 22 ScriptContextSet* g_context_set = nullptr; |
| 23 } | 23 } |
| 24 | 24 |
| 25 ScriptContextSet::ScriptContextSet(ExtensionSet* extensions, | 25 ScriptContextSet::ScriptContextSet(ExtensionIdSet* active_extension_ids) |
| 26 ExtensionIdSet* active_extension_ids) | 26 : active_extension_ids_(active_extension_ids) { |
| 27 : extensions_(extensions), active_extension_ids_(active_extension_ids) { | |
| 28 DCHECK(!g_context_set); | 27 DCHECK(!g_context_set); |
| 29 g_context_set = this; | 28 g_context_set = this; |
| 30 } | 29 } |
| 31 | 30 |
| 32 ScriptContextSet::~ScriptContextSet() { | 31 ScriptContextSet::~ScriptContextSet() { |
| 33 g_context_set = nullptr; | 32 g_context_set = nullptr; |
| 34 } | 33 } |
| 35 | 34 |
| 36 ScriptContext* ScriptContextSet::Register( | 35 ScriptContext* ScriptContextSet::Register( |
| 37 blink::WebLocalFrame* frame, | 36 blink::WebLocalFrame* frame, |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 std::string extension_id; | 138 std::string extension_id; |
| 140 if (world_id != 0) { | 139 if (world_id != 0) { |
| 141 // Isolated worlds (content script). | 140 // Isolated worlds (content script). |
| 142 extension_id = ScriptInjection::GetHostIdForIsolatedWorld(world_id); | 141 extension_id = ScriptInjection::GetHostIdForIsolatedWorld(world_id); |
| 143 } else if (!frame->document().securityOrigin().isUnique()) { | 142 } else if (!frame->document().securityOrigin().isUnique()) { |
| 144 // TODO(kalman): Delete the above check. | 143 // TODO(kalman): Delete the above check. |
| 145 // Extension pages (chrome-extension:// URLs). | 144 // Extension pages (chrome-extension:// URLs). |
| 146 GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame); | 145 GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame); |
| 147 frame_url = ScriptContext::GetEffectiveDocumentURL(frame, frame_url, | 146 frame_url = ScriptContext::GetEffectiveDocumentURL(frame, frame_url, |
| 148 use_effective_url); | 147 use_effective_url); |
| 149 extension_id = extensions_->GetExtensionOrAppIDByURL(frame_url); | 148 extension_id = |
| 149 RendererExtensionRegistry::Get()->GetExtensionOrAppIDByURL(frame_url); |
| 150 } | 150 } |
| 151 | 151 |
| 152 // There are conditions where despite a context being associated with an | 152 // There are conditions where despite a context being associated with an |
| 153 // extension, no extension actually gets found. Ignore "invalid" because CSP | 153 // extension, no extension actually gets found. Ignore "invalid" because CSP |
| 154 // blocks extension page loading by switching the extension ID to "invalid". | 154 // blocks extension page loading by switching the extension ID to "invalid". |
| 155 const Extension* extension = extensions_->GetByID(extension_id); | 155 const Extension* extension = |
| 156 RendererExtensionRegistry::Get()->GetByID(extension_id); |
| 156 if (!extension && !extension_id.empty() && extension_id != "invalid") { | 157 if (!extension && !extension_id.empty() && extension_id != "invalid") { |
| 157 // TODO(kalman): Do something here? | 158 // TODO(kalman): Do something here? |
| 158 } | 159 } |
| 159 return extension; | 160 return extension; |
| 160 } | 161 } |
| 161 | 162 |
| 162 Feature::Context ScriptContextSet::ClassifyJavaScriptContext( | 163 Feature::Context ScriptContextSet::ClassifyJavaScriptContext( |
| 163 const Extension* extension, | 164 const Extension* extension, |
| 164 int extension_group, | 165 int extension_group, |
| 165 const GURL& url, | 166 const GURL& url, |
| 166 const blink::WebSecurityOrigin& origin) { | 167 const blink::WebSecurityOrigin& origin) { |
| 167 // WARNING: This logic must match ProcessMap::GetContextType, as much as | 168 // WARNING: This logic must match ProcessMap::GetContextType, as much as |
| 168 // possible. | 169 // possible. |
| 169 | 170 |
| 170 DCHECK_GE(extension_group, 0); | 171 DCHECK_GE(extension_group, 0); |
| 171 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { | 172 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { |
| 172 return extension ? // TODO(kalman): when does this happen? | 173 return extension ? // TODO(kalman): when does this happen? |
| 173 Feature::CONTENT_SCRIPT_CONTEXT | 174 Feature::CONTENT_SCRIPT_CONTEXT |
| 174 : Feature::UNSPECIFIED_CONTEXT; | 175 : Feature::UNSPECIFIED_CONTEXT; |
| 175 } | 176 } |
| 176 | 177 |
| 177 // We have an explicit check for sandboxed pages before checking whether the | 178 // We have an explicit check for sandboxed pages before checking whether the |
| 178 // extension is active in this process because: | 179 // extension is active in this process because: |
| 179 // 1. Sandboxed pages run in the same process as regular extension pages, so | 180 // 1. Sandboxed pages run in the same process as regular extension pages, so |
| 180 // the extension is considered active. | 181 // the extension is considered active. |
| 181 // 2. ScriptContext creation (which triggers bindings injection) happens | 182 // 2. ScriptContext creation (which triggers bindings injection) happens |
| 182 // before the SecurityContext is updated with the sandbox flags (after | 183 // before the SecurityContext is updated with the sandbox flags (after |
| 183 // reading the CSP header), so the caller can't check if the context's | 184 // reading the CSP header), so the caller can't check if the context's |
| 184 // security origin is unique yet. | 185 // security origin is unique yet. |
| 185 if (ScriptContext::IsSandboxedPage(*extensions_, url)) | 186 if (ScriptContext::IsSandboxedPage(url)) |
| 186 return Feature::WEB_PAGE_CONTEXT; | 187 return Feature::WEB_PAGE_CONTEXT; |
| 187 | 188 |
| 188 if (extension && active_extension_ids_->count(extension->id()) > 0) { | 189 if (extension && active_extension_ids_->count(extension->id()) > 0) { |
| 189 // |extension| is active in this process, but it could be either a true | 190 // |extension| is active in this process, but it could be either a true |
| 190 // extension process or within the extent of a hosted app. In the latter | 191 // extension process or within the extent of a hosted app. In the latter |
| 191 // case this would usually be considered a (blessed) web page context, | 192 // case this would usually be considered a (blessed) web page context, |
| 192 // unless the extension in question is a component extension, in which case | 193 // unless the extension in question is a component extension, in which case |
| 193 // we cheat and call it blessed. | 194 // we cheat and call it blessed. |
| 194 return (extension->is_hosted_app() && | 195 return (extension->is_hosted_app() && |
| 195 extension->location() != Manifest::COMPONENT) | 196 extension->location() != Manifest::COMPONENT) |
| 196 ? Feature::BLESSED_WEB_PAGE_CONTEXT | 197 ? Feature::BLESSED_WEB_PAGE_CONTEXT |
| 197 : Feature::BLESSED_EXTENSION_CONTEXT; | 198 : Feature::BLESSED_EXTENSION_CONTEXT; |
| 198 } | 199 } |
| 199 | 200 |
| 200 // TODO(kalman): This isUnique() check is wrong, it should be performed as | 201 // TODO(kalman): This isUnique() check is wrong, it should be performed as |
| 201 // part of ScriptContext::IsSandboxedPage(). | 202 // part of ScriptContext::IsSandboxedPage(). |
| 202 if (!origin.isUnique() && extensions_->ExtensionBindingsAllowed(url)) { | 203 if (!origin.isUnique() && |
| 204 RendererExtensionRegistry::Get()->ExtensionBindingsAllowed(url)) { |
| 203 if (!extension) // TODO(kalman): when does this happen? | 205 if (!extension) // TODO(kalman): when does this happen? |
| 204 return Feature::UNSPECIFIED_CONTEXT; | 206 return Feature::UNSPECIFIED_CONTEXT; |
| 205 return extension->is_hosted_app() ? Feature::BLESSED_WEB_PAGE_CONTEXT | 207 return extension->is_hosted_app() ? Feature::BLESSED_WEB_PAGE_CONTEXT |
| 206 : Feature::UNBLESSED_EXTENSION_CONTEXT; | 208 : Feature::UNBLESSED_EXTENSION_CONTEXT; |
| 207 } | 209 } |
| 208 | 210 |
| 209 if (!url.is_valid()) | 211 if (!url.is_valid()) |
| 210 return Feature::UNSPECIFIED_CONTEXT; | 212 return Feature::UNSPECIFIED_CONTEXT; |
| 211 | 213 |
| 212 if (url.SchemeIs(content::kChromeUIScheme)) | 214 if (url.SchemeIs(content::kChromeUIScheme)) |
| 213 return Feature::WEBUI_CONTEXT; | 215 return Feature::WEBUI_CONTEXT; |
| 214 | 216 |
| 215 return Feature::WEB_PAGE_CONTEXT; | 217 return Feature::WEB_PAGE_CONTEXT; |
| 216 } | 218 } |
| 217 | 219 |
| 218 void ScriptContextSet::DispatchOnUnloadEventAndRemove( | 220 void ScriptContextSet::DispatchOnUnloadEventAndRemove( |
| 219 std::set<ScriptContext*>* out, | 221 std::set<ScriptContext*>* out, |
| 220 ScriptContext* context) { | 222 ScriptContext* context) { |
| 221 context->DispatchOnUnloadEvent(); | 223 context->DispatchOnUnloadEvent(); |
| 222 Remove(context); // deleted asynchronously | 224 Remove(context); // deleted asynchronously |
| 223 out->insert(context); | 225 out->insert(context); |
| 224 } | 226 } |
| 225 | 227 |
| 226 } // namespace extensions | 228 } // namespace extensions |
| OLD | NEW |