summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authormnaganov <mnaganov@chromium.org>2015-08-13 09:33:32 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-13 16:34:34 +0000
commitb58eaaad66463aba894d5c92589e260245e63de2 (patch)
tree464bffabbae9666e4d17894ab557b637f1ae3844 /android_webview
parent32eb5395a9ce0ac6115d66d6c0482c5009ee5e37 (diff)
downloadchromium_src-b58eaaad66463aba894d5c92589e260245e63de2.zip
chromium_src-b58eaaad66463aba894d5c92589e260245e63de2.tar.gz
chromium_src-b58eaaad66463aba894d5c92589e260245e63de2.tar.bz2
Implement AwContentBrowserClient::IsHandledURL
Implemented similarly to ChromeContentBrowserClient. The only trick is that 'false' is still returned for "special" Android file URLs (file:///android_asset/* and file:///android_res/) that should work even if file access is disabled. By returning 'false' from IsHandledURL we bypass the scheme check in ChildProcessSecurityPolicy. Access to 'file:' scheme is granted to child processes after the first call to WebView.loadDataWithBaseUrl with non-data: base URL. Access to 'content:' scheme is always granted, as access to it is enabled by default in WebSettings. BUG=516546 Review URL: https://codereview.chromium.org/1275163004 Cr-Commit-Position: refs/heads/master@{#343214}
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/browser/aw_content_browser_client.cc37
-rw-r--r--android_webview/browser/aw_content_browser_client.h1
-rw-r--r--android_webview/browser/net/aw_url_request_context_getter.cc2
-rw-r--r--android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc9
-rw-r--r--android_webview/common/url_constants.cc11
-rw-r--r--android_webview/common/url_constants.h4
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java5
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java4
-rw-r--r--android_webview/native/android_protocol_handler.cc31
-rw-r--r--android_webview/native/aw_contents.cc6
-rw-r--r--android_webview/native/aw_contents.h2
11 files changed, 74 insertions, 38 deletions
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 1f59823..fb16ceb 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -168,6 +168,12 @@ AwContentBrowserClient::GetWebContentsViewDelegate(
void AwContentBrowserClient::RenderProcessWillLaunch(
content::RenderProcessHost* host) {
+ // Grant content: scheme access to the whole renderer process, since we impose
+ // per-view access checks, and access is granted by default (see
+ // AwSettings.mAllowContentUrlAccess).
+ content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
+ host->GetID(), url::kContentScheme);
+
host->AddFilter(new AwContentsMessageFilter(host->GetID()));
host->AddFilter(new cdm::CdmMessageFilterAndroid());
host->AddFilter(new AwPrintingMessageFilter(host->GetID()));
@@ -197,6 +203,37 @@ AwContentBrowserClient::CreateRequestContextForStoragePartition(
request_interceptors.Pass());
}
+bool AwContentBrowserClient::IsHandledURL(const GURL& url) {
+ if (!url.is_valid()) {
+ // We handle error cases.
+ return true;
+ }
+
+ const std::string scheme = url.scheme();
+ DCHECK_EQ(scheme, base::ToLowerASCII(scheme));
+ // See CreateJobFactory in aw_url_request_context_getter.cc for the
+ // list of protocols that are handled.
+ // TODO(mnaganov): Make this automatic.
+ static const char* const kProtocolList[] = {
+ url::kDataScheme,
+ url::kBlobScheme,
+ url::kFileSystemScheme,
+ content::kChromeUIScheme,
+ content::kChromeDevToolsScheme,
+ url::kContentScheme,
+ };
+ if (scheme == url::kFileScheme) {
+ // Return false for the "special" file URLs, so they can be loaded
+ // even if access to file: scheme is not granted to the child process.
+ return !IsAndroidSpecialFileUrl(url);
+ }
+ for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
+ if (scheme == kProtocolList[i])
+ return true;
+ }
+ return net::URLRequest::IsHandledProtocol(scheme);
+}
+
std::string AwContentBrowserClient::GetCanonicalEncodingNameByAliasName(
const std::string& alias_name) {
return alias_name;
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 2f0e472..45e9f86 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -48,6 +48,7 @@ class AwContentBrowserClient : public content::ContentBrowserClient {
bool in_memory,
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) override;
+ bool IsHandledURL(const GURL& url) override;
std::string GetCanonicalEncodingNameByAliasName(
const std::string& alias_name) override;
void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index b2058c4..68ba631 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -112,6 +112,8 @@ scoped_ptr<net::URLRequestJobFactory> CreateJobFactory(
content::ProtocolHandlerMap* protocol_handlers,
content::URLRequestInterceptorScopedVector request_interceptors) {
scoped_ptr<AwURLRequestJobFactory> aw_job_factory(new AwURLRequestJobFactory);
+ // Note that the registered schemes must also be specified in
+ // AwContentBrowserClient::IsHandledURL.
bool set_protocol = aw_job_factory->SetProtocolHandler(
url::kFileScheme,
new net::FileProtocolHandler(
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
index 577c355..1d9e585 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -160,13 +160,8 @@ bool IoThreadClientThrottle::ShouldBlockRequest() {
// Part of implementation of WebSettings.allowFileAccess.
if (request_->url().SchemeIsFile() &&
io_client->ShouldBlockFileUrls()) {
- const GURL& url = request_->url();
- if (!url.has_path() ||
- // Application's assets and resources are always available.
- (url.path().find(android_webview::kAndroidResourcePath) != 0 &&
- url.path().find(android_webview::kAndroidAssetPath) != 0)) {
- return true;
- }
+ // Application's assets and resources are always available.
+ return !IsAndroidSpecialFileUrl(request_->url());
}
if (io_client->ShouldBlockNetworkLoads()) {
diff --git a/android_webview/common/url_constants.cc b/android_webview/common/url_constants.cc
index 89a32bb..ff870ac 100644
--- a/android_webview/common/url_constants.cc
+++ b/android_webview/common/url_constants.cc
@@ -4,6 +4,8 @@
#include "android_webview/common/url_constants.h"
+#include "base/strings/string_util.h"
+
namespace android_webview {
// These are special paths used with the file: scheme to access application
@@ -15,4 +17,13 @@ const char kAndroidResourcePath[] = "/android_res/";
// This scheme is used to display a default HTML5 video poster.
const char kAndroidWebViewVideoPosterScheme[] = "android-webview-video-poster";
+bool IsAndroidSpecialFileUrl(const GURL& url) {
+ if (!url.is_valid() || !url.SchemeIsFile() || !url.has_path())
+ return false;
+ return base::StartsWith(url.path(), kAndroidAssetPath,
+ base::CompareCase::SENSITIVE) ||
+ base::StartsWith(url.path(), kAndroidResourcePath,
+ base::CompareCase::SENSITIVE);
+}
+
} // namespace android_webview
diff --git a/android_webview/common/url_constants.h b/android_webview/common/url_constants.h
index 80c3571..2d0e316 100644
--- a/android_webview/common/url_constants.h
+++ b/android_webview/common/url_constants.h
@@ -7,11 +7,15 @@
#ifndef ANDROID_WEBVIEW_COMMON_URL_CONSTANTS_H_
#define ANDROID_WEBVIEW_COMMON_URL_CONSTANTS_H_
+#include "url/gurl.h"
+
namespace android_webview {
// Special Android file paths.
extern const char kAndroidAssetPath[];
extern const char kAndroidResourcePath[];
+// Returns whether the given URL is for loading a file from a special path.
+bool IsAndroidSpecialFileUrl(const GURL& url);
extern const char kAndroidWebViewVideoPosterScheme[];
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index bdcbd37..a486243 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -1414,6 +1414,9 @@ public class AwContents implements SmartClipProvider,
Log.wtf(TAG, "Unable to load data string " + data, e);
return;
}
+ // When loading data with a non-data: base URL, WebView must allow renderers
+ // to access file: URLs.
+ nativeGrantFileSchemeAccesstoChildProcess(mNativeAwContents);
}
loadUrl(loadUrlParams);
}
@@ -3149,4 +3152,6 @@ public class AwContents implements SmartClipProvider,
String message, String targetOrigin, int[] msgPorts);
private native void nativeCreateMessageChannel(long nativeAwContents, AwMessagePort[] ports);
+
+ private native void nativeGrantFileSchemeAccesstoChildProcess(long nativeAwContents);
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
index 25cfa8d..994f002 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
@@ -251,8 +251,8 @@ public class AwTestBase
runTestOnUiThread(new Runnable() {
@Override
public void run() {
- awContents.loadUrl(LoadUrlParams.createLoadDataParamsWithBaseUrl(
- data, mimeType, isBase64Encoded, baseUrl, historyUrl));
+ awContents.loadDataWithBaseURL(
+ baseUrl, data, mimeType, isBase64Encoded ? "base64" : null, historyUrl);
}
});
}
diff --git a/android_webview/native/android_protocol_handler.cc b/android_webview/native/android_protocol_handler.cc
index dd4db90..be3376c 100644
--- a/android_webview/native/android_protocol_handler.cc
+++ b/android_webview/native/android_protocol_handler.cc
@@ -11,7 +11,6 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/jni_weak_ref.h"
-#include "base/strings/string_util.h"
#include "content/public/common/url_constants.h"
#include "jni/AndroidProtocolHandler_jni.h"
#include "net/base/io_buffer.h"
@@ -95,15 +94,7 @@ class AndroidRequestInterceptorBase : public net::URLRequestInterceptor {
class AssetFileRequestInterceptor : public AndroidRequestInterceptorBase {
public:
AssetFileRequestInterceptor();
-
- ~AssetFileRequestInterceptor() override;
bool ShouldHandleRequest(const net::URLRequest* request) const override;
-
- private:
- // file:///android_asset/
- const std::string asset_prefix_;
- // file:///android_res/
- const std::string resource_prefix_;
};
// Protocol handler for content:// scheme requests.
@@ -235,30 +226,12 @@ net::URLRequestJob* AndroidRequestInterceptorBase::MaybeInterceptRequest(
// AssetFileRequestInterceptor ------------------------------------------------
-AssetFileRequestInterceptor::AssetFileRequestInterceptor()
- : asset_prefix_(std::string(url::kFileScheme) +
- std::string(url::kStandardSchemeSeparator) +
- android_webview::kAndroidAssetPath),
- resource_prefix_(std::string(url::kFileScheme) +
- std::string(url::kStandardSchemeSeparator) +
- android_webview::kAndroidResourcePath) {
-}
-
-AssetFileRequestInterceptor::~AssetFileRequestInterceptor() {
+AssetFileRequestInterceptor::AssetFileRequestInterceptor() {
}
bool AssetFileRequestInterceptor::ShouldHandleRequest(
const net::URLRequest* request) const {
- if (!request->url().SchemeIsFile())
- return false;
-
- const std::string& url = request->url().spec();
- if (!base::StartsWith(url, asset_prefix_, base::CompareCase::SENSITIVE) &&
- !base::StartsWith(url, resource_prefix_, base::CompareCase::SENSITIVE)) {
- return false;
- }
-
- return true;
+ return android_webview::IsAndroidSpecialFileUrl(request->url());
}
// ContentSchemeRequestInterceptor --------------------------------------------
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 7d34034..84c2457 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -53,6 +53,7 @@
#include "content/public/browser/android/synchronous_compositor.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cert_store.h"
+#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/message_port_provider.h"
#include "content/public/browser/navigation_entry.h"
@@ -1205,6 +1206,11 @@ void AwContents::CreateMessageChannel(JNIEnv* env, jobject obj,
GetMessagePortMessageFilter());
}
+void AwContents::GrantFileSchemeAccesstoChildProcess(JNIEnv* env, jobject obj) {
+ content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
+ web_contents_->GetRenderProcessHost()->GetID(), url::kFileScheme);
+}
+
void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) {
g_should_download_favicons = true;
}
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index 7600051..cbdb8b2 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -237,6 +237,8 @@ class AwContents : public FindHelper::Listener,
jstring message, jstring target_origin, jintArray sent_ports);
void CreateMessageChannel(JNIEnv* env, jobject obj, jobjectArray ports);
+ void GrantFileSchemeAccesstoChildProcess(JNIEnv* env, jobject obj);
+
private:
void InitDataReductionProxyIfNecessary();
void InitAutofillIfNecessary(bool enabled);