diff options
author | benm@google.com <benm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-11 16:26:37 +0000 |
---|---|---|
committer | benm@google.com <benm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-11 16:26:37 +0000 |
commit | 951a6483b7bbe715ad8cda7cb2263b172ac96bcb (patch) | |
tree | 5a3e9fd7e3eea0e949c0d46b71381da012fbea39 | |
parent | 3a74304c6b47cb9647b0d3e4d061a7f4d79b6bf2 (diff) | |
download | chromium_src-951a6483b7bbe715ad8cda7cb2263b172ac96bcb.zip chromium_src-951a6483b7bbe715ad8cda7cb2263b172ac96bcb.tar.gz chromium_src-951a6483b7bbe715ad8cda7cb2263b172ac96bcb.tar.bz2 |
This change is motivated by the need to implement the Android WebView.loadDataWithBaseURL API[1], which allows access to local file:// resources (depending on AwSettings.getAllowFileAccess) as long as the base URL provided is not "data:".
When AwSettings.getAllowFileAccess returns false, data URIs loaded with a non-data base URL should be able to access file:///android_asset and file:///android_res/, but not the wider filesystem.
We grant the WebView process access to file:// via ChildProcessSecurityPolicy (as WebView is single process we do this on process startup) and add a field to ViewMsg_NavigateParams that indicates if the URL being loaded should have access to local loads. This is bit is checked when the provisional load commits and if set, grants the SecurityOrigin access to local resources. The bit defaults to false and is only set in android_webview when AwContents loads a data URL with a non-data base URL, so there should be no behavior change outside of android_webview.
Once the SecurityOrigin allows local loads, code already present in android_webview controls whether the URL should be able to load either only android_asset and android_res or any file:// URL (see https://codereview.chromium.org/11090003/).
[1]
http://developer.android.com/reference/android/webkit/WebView.html#loadDataWithBaseURL(java.lang.String,
java.lang.String, java.lang.String, java.lang.String, java.lang.String)
BUG=152223
Review URL: https://codereview.chromium.org/10990056
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161355 0039d316-1c4b-4281-b951-d872f2087c98
23 files changed, 223 insertions, 31 deletions
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 2a7377b..2124a1f 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -194,6 +194,13 @@ public class AwContents { * @param pararms Parameters for this load. */ public void loadUrl(LoadUrlParams params) { + if (params.getLoadUrlType() == LoadUrlParams.LOAD_TYPE_DATA && + !params.isBaseUrlDataScheme()) { + // This allows data URLs with a non-data base URL access to file:///android_asset/ and + // file:///android_res/ URLs. If AwSettings.getAllowFileAccess permits, it will also + // allow access to file:// URLs (subject to OS level permission checks). + params.setCanLoadLocalResources(true); + } mContentViewCore.loadUrl(params); } diff --git a/android_webview/javatests/assets/asset_icon.png b/android_webview/javatests/assets/asset_icon.png Binary files differnew file mode 100644 index 0000000..f381f86 --- /dev/null +++ b/android_webview/javatests/assets/asset_icon.png diff --git a/android_webview/javatests/res/raw/resource_icon.png b/android_webview/javatests/res/raw/resource_icon.png Binary files differnew file mode 100644 index 0000000..f381f86 --- /dev/null +++ b/android_webview/javatests/res/raw/resource_icon.png diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java index 7f6e72d..c10b735 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java @@ -4,19 +4,25 @@ package org.chromium.android_webview.test; +import android.graphics.Bitmap; import android.test.suitebuilder.annotation.SmallTest; +import org.chromium.android_webview.AndroidProtocolHandler; import org.chromium.android_webview.AwContents; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.TestWebServer; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.ContentSettings; import org.chromium.content.browser.ContentViewCore; import org.chromium.content.browser.LoadUrlParams; import org.chromium.content.browser.test.util.HistoryUtils; import org.chromium.content.browser.test.util.TestCallbackHelperContainer; +import java.io.File; +import java.io.FileOutputStream; import java.util.concurrent.TimeUnit; public class LoadDataWithBaseUrlTest extends AndroidWebViewTestBase { @@ -212,28 +218,6 @@ public class LoadDataWithBaseUrlTest extends AndroidWebViewTestBase { @SmallTest @Feature({"Android-WebView"}) - public void testAccessToLocalFile() throws Throwable { - getContentSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true); - final String baseUrl = UrlUtils.getTestFileUrl("webview/"); - final String scriptFile = baseUrl + "script.js"; - final String pageHtml = getScriptFileTestPageHtml(scriptFile); - loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, null); - assertEquals(SCRIPT_LOADED, getTitleOnUiThread(mAwContents)); - } - - @SmallTest - @Feature({"Android-WebView"}) - public void testFailedAccessToLocalFile() throws Throwable { - getContentSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true); - final String scriptFile = UrlUtils.getTestFileUrl("webview/script.js"); - final String pageHtml = getScriptFileTestPageHtml(scriptFile); - final String baseUrl = "http://example.com"; - loadDataWithBaseUrlSync(pageHtml, "text/html", false, baseUrl, null); - assertEquals(SCRIPT_NOT_LOADED, getTitleOnUiThread(mAwContents)); - } - - @SmallTest - @Feature({"Android-WebView"}) public void testHistoryUrlNavigation() throws Throwable { TestWebServer webServer = null; try { @@ -265,4 +249,97 @@ public class LoadDataWithBaseUrlTest extends AndroidWebViewTestBase { if (webServer != null) webServer.shutdown(); } } + + /** + * @return true if |fileUrl| was accessible from a data url with |baseUrl| as it's + * base URL. + */ + private boolean canAccessFileFromData(String baseUrl, String fileUrl) throws Throwable { + final String IMAGE_LOADED = "LOADED"; + final String IMAGE_NOT_LOADED = "NOT_LOADED"; + String data = "<html><body>" + + "<img src=\"" + fileUrl + "\" " + + "onload=\"document.title=\'" + IMAGE_LOADED + "\';\" " + + "onerror=\"document.title=\'" + IMAGE_NOT_LOADED + "\';\" />" + + "</body></html>"; + + loadDataWithBaseUrlSync(data, "text/html", false, baseUrl, null); + + CriteriaHelper.pollForCriteria(new Criteria() { + @Override + public boolean isSatisfied() { + try { + String title = getTitleOnUiThread(mAwContents); + return IMAGE_LOADED.equals(title) || IMAGE_NOT_LOADED.equals(title); + } catch (Throwable t) { + return false; + } + } + }); + + return IMAGE_LOADED.equals(getTitleOnUiThread(mAwContents)); + } + + @SmallTest + @Feature({"Android-WebView"}) + public void testLoadDataWithBaseUrlAccessingFile() throws Throwable { + // Create a temporary file on the filesystem we can try to read. + File cacheDir = getActivity().getCacheDir(); + File tempImage = File.createTempFile("test_image", ".png", cacheDir); + Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565); + FileOutputStream fos = new FileOutputStream(tempImage); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); + String imagePath = tempImage.getAbsolutePath(); + + ContentSettings contentSettings = getContentSettingsOnUiThread(mAwContents); + contentSettings.setImagesEnabled(true); + contentSettings.setJavaScriptEnabled(true); + + try { + final String DATA_BASE_URL = "data:"; + final String NON_DATA_BASE_URL = "http://example.com"; + + AndroidProtocolHandler.setResourceContextForTesting(getInstrumentation().getContext()); + mAwContents.getSettings().setAllowFileAccess(false); + String token = "" + System.currentTimeMillis(); + // All access to file://, including android_asset and android_res is blocked + // with a data: base URL, regardless of AwSettings.getAllowFileAccess(). + assertFalse(canAccessFileFromData(DATA_BASE_URL, + "file:///android_asset/asset_icon.png?" + token)); + assertFalse(canAccessFileFromData(DATA_BASE_URL, + "file:///android_res/raw/resource_icon.png?" + token)); + assertFalse(canAccessFileFromData(DATA_BASE_URL, "file://" + imagePath + "?" + token)); + + // WebView always has access to android_asset and android_res for non-data + // base URLs and can access other file:// URLs based on the value of + // AwSettings.getAllowFileAccess(). + assertTrue(canAccessFileFromData(NON_DATA_BASE_URL, + "file:///android_asset/asset_icon.png?" + token)); + assertTrue(canAccessFileFromData(NON_DATA_BASE_URL, + "file:///android_res/raw/resource_icon.png?" + token)); + assertFalse(canAccessFileFromData(NON_DATA_BASE_URL, + "file://" + imagePath + "?" + token)); + + token += "a"; + mAwContents.getSettings().setAllowFileAccess(true); + // We should still be unable to access any file:// with when loading with a + // data: base URL, but we should now be able to access the wider file system + // (still restricted by OS-level permission checks) with a non-data base URL. + assertFalse(canAccessFileFromData(DATA_BASE_URL, + "file:///android_asset/asset_icon.png?" + token)); + assertFalse(canAccessFileFromData(DATA_BASE_URL, + "file:///android_res/raw/resource_icon.png?" + token)); + assertFalse(canAccessFileFromData(DATA_BASE_URL, "file://" + imagePath + "?" + token)); + + assertTrue(canAccessFileFromData(NON_DATA_BASE_URL, + "file:///android_asset/asset_icon.png?" + token)); + assertTrue(canAccessFileFromData(NON_DATA_BASE_URL, + "file:///android_res/raw/resource_icon.png?" + token)); + assertTrue(canAccessFileFromData(NON_DATA_BASE_URL, + "file://" + imagePath + "?" + token)); + } finally { + tempImage.delete(); + AndroidProtocolHandler.setResourceContextForTesting(null); + } + } } diff --git a/android_webview/lib/aw_content_browser_client.cc b/android_webview/lib/aw_content_browser_client.cc index d8de283..539f5c2 100644 --- a/android_webview/lib/aw_content_browser_client.cc +++ b/android_webview/lib/aw_content_browser_client.cc @@ -9,6 +9,7 @@ #include "android_webview/common/url_constants.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/render_process_host.h" +#include "content/public/common/url_constants.h" namespace android_webview { @@ -22,10 +23,20 @@ AwContentBrowserClient::~AwContentBrowserClient() { void AwContentBrowserClient::RenderProcessHostCreated( content::RenderProcessHost* host) { ChromeContentBrowserClient::RenderProcessHostCreated(host); - // Grant content: scheme to the whole process, since we impose per-view - // access checks. + + // If WebView becomes multi-process capable, this may be insecure. + // More benefit can be derived from the ChildProcessSecurotyPolicy by + // deferring the GrantScheme calls until we know that a given child process + // really does need that priviledge. Check here to ensure we rethink this + // when the time comes. + CHECK(content::RenderProcessHost::run_renderer_in_process()); + + // Grant content: and file: scheme to the whole process, since we impose + // per-view access checks. content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme( host->GetID(), android_webview::kContentScheme); + content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme( + host->GetID(), chrome::kFileScheme); } void AwContentBrowserClient::ResourceDispatcherHostCreated() { diff --git a/android_webview/renderer/aw_render_view_ext.cc b/android_webview/renderer/aw_render_view_ext.cc index 7f0825c..2196ffe 100644 --- a/android_webview/renderer/aw_render_view_ext.cc +++ b/android_webview/renderer/aw_render_view_ext.cc @@ -6,12 +6,15 @@ #include "android_webview/common/render_view_messages.h" #include "content/public/common/url_constants.h" +#include "content/public/renderer/document_state.h" #include "content/public/renderer/render_view.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" namespace android_webview { @@ -66,4 +69,14 @@ bool AwRenderViewExt::allowImage(WebKit::WebFrame* frame, url.SchemeIs(chrome::kFtpScheme)); } +void AwRenderViewExt::DidCommitProvisionalLoad(WebKit::WebFrame* frame, + bool is_new_navigation) { + content::DocumentState* document_state = + content::DocumentState::FromDataSource(frame->dataSource()); + if (document_state->can_load_local_resources()) { + WebKit::WebSecurityOrigin origin = frame->document().securityOrigin(); + origin.grantLoadLocalResources(); + } +} + } // namespace android_webview diff --git a/android_webview/renderer/aw_render_view_ext.h b/android_webview/renderer/aw_render_view_ext.h index 79a1a74..d2ff20c 100644 --- a/android_webview/renderer/aw_render_view_ext.h +++ b/android_webview/renderer/aw_render_view_ext.h @@ -32,6 +32,8 @@ class AwRenderViewExt : public content::RenderViewObserver, // RenderView::Observer: virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void DidCommitProvisionalLoad(WebKit::WebFrame* frame, + bool is_new_navigation) OVERRIDE; void OnDocumentHasImagesRequest(int id); diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index a3b39a2..273fd5f 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc @@ -433,7 +433,8 @@ void ContentViewCoreImpl::LoadUrl( jstring extra_headers, jbyteArray post_data, jstring base_url_for_data_url, - jstring virtual_url_for_data_url) { + jstring virtual_url_for_data_url, + jboolean can_load_local_resources) { DCHECK(url); NavigationController::LoadURLParams params( GURL(ConvertJavaStringToUTF8(env, url))); @@ -465,6 +466,8 @@ void ContentViewCoreImpl::LoadUrl( GURL(ConvertJavaStringToUTF8(env, virtual_url_for_data_url)); } + params.can_load_local_resources = can_load_local_resources; + LoadUrl(params); } diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index 99b0625..5ba4a661 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h @@ -67,7 +67,8 @@ class ContentViewCoreImpl : public ContentViewCore, jstring extra_headers, jbyteArray post_data, jstring base_url_for_data_url, - jstring virtual_url_for_data_url); + jstring virtual_url_for_data_url, + jboolean can_load_local_resources); void SetAllUserAgentOverridesInHistory( JNIEnv* env, jobject obj, diff --git a/content/browser/android/load_url_params.cc b/content/browser/android/load_url_params.cc index 0086731..c5e2966 100644 --- a/content/browser/android/load_url_params.cc +++ b/content/browser/android/load_url_params.cc @@ -6,7 +6,10 @@ #include <jni.h> +#include "base/android/jni_string.h" #include "content/public/browser/navigation_controller.h" +#include "content/public/common/url_constants.h" +#include "googleurl/src/gurl.h" #include "jni/LoadUrlParams_jni.h" namespace { @@ -34,4 +37,9 @@ bool RegisterLoadUrlParams(JNIEnv* env) { return true; } +jboolean IsDataScheme(JNIEnv* env, jclass clazz, jstring jurl) { + GURL url(base::android::ConvertJavaStringToUTF8(env, jurl)); + return url.SchemeIs(chrome::kDataScheme); +} + } // namespace content diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc index e8f8bff..150c5dc 100644 --- a/content/browser/web_contents/navigation_controller_impl.cc +++ b/content/browser/web_contents/navigation_controller_impl.cc @@ -690,6 +690,7 @@ void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) { case LOAD_TYPE_DATA: entry->SetBaseURLForDataURL(params.base_url_for_data_url); entry->SetVirtualURL(params.virtual_url_for_data_url); + entry->SetCanLoadLocalResources(params.can_load_local_resources); break; default: NOTREACHED(); diff --git a/content/browser/web_contents/navigation_entry_impl.cc b/content/browser/web_contents/navigation_entry_impl.cc index a3f6b90..b6aea9d 100644 --- a/content/browser/web_contents/navigation_entry_impl.cc +++ b/content/browser/web_contents/navigation_entry_impl.cc @@ -47,7 +47,8 @@ NavigationEntryImpl::NavigationEntryImpl() restore_type_(RESTORE_NONE), is_overriding_user_agent_(false), is_renderer_initiated_(false), - is_cross_site_reload_(false) { + is_cross_site_reload_(false), + can_load_local_resources_(false) { } NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance, @@ -263,4 +264,12 @@ base::Time NavigationEntryImpl::GetTimestamp() const { return timestamp_; } +void NavigationEntryImpl::SetCanLoadLocalResources(bool allow) { + can_load_local_resources_ = allow; +} + +bool NavigationEntryImpl::GetCanLoadLocalResources() const { + return can_load_local_resources_; +} + } // namespace content diff --git a/content/browser/web_contents/navigation_entry_impl.h b/content/browser/web_contents/navigation_entry_impl.h index 8a2ca90..795dafa 100644 --- a/content/browser/web_contents/navigation_entry_impl.h +++ b/content/browser/web_contents/navigation_entry_impl.h @@ -71,6 +71,8 @@ class CONTENT_EXPORT NavigationEntryImpl virtual bool GetIsOverridingUserAgent() const OVERRIDE; virtual void SetTimestamp(base::Time timestamp) OVERRIDE; virtual base::Time GetTimestamp() const OVERRIDE; + virtual void SetCanLoadLocalResources(bool allow) OVERRIDE; + virtual bool GetCanLoadLocalResources() const OVERRIDE; void set_unique_id(int unique_id) { unique_id_ = unique_id; @@ -232,6 +234,10 @@ class CONTENT_EXPORT NavigationEntryImpl // and is not needed after the entry commits. bool is_cross_site_reload_; + // Set when this entry should be able to access local file:// resources. This + // value is not needed after the entry commits and is not persisted. + bool can_load_local_resources_; + // Copy and assignment is explicitly allowed for this class. }; diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 6ef49c9..779a386 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -268,6 +268,8 @@ void MakeNavigateParams(const NavigationEntryImpl& entry, params->url = entry.GetURL(); } + params->can_load_local_resources = entry.GetCanLoadLocalResources(); + if (delegate) delegate->AddNavigationHeaders(params->url, ¶ms->extra_headers); } diff --git a/content/common/view_messages.h b/content/common/view_messages.h index d8780b2..09eb4d4 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -738,6 +738,10 @@ IPC_STRUCT_BEGIN(ViewMsg_Navigate_Params) // If is_post is true, holds the post_data information from browser. Empty // otherwise. IPC_STRUCT_MEMBER(std::vector<unsigned char>, browser_initiated_post_data) + + // Whether or not this url should be allowed to access local file:// + // resources. + IPC_STRUCT_MEMBER(bool, can_load_local_resources) IPC_STRUCT_END() IPC_STRUCT_BEGIN(ViewMsg_New_Params) diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 0ad997d..12888be 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java @@ -662,7 +662,8 @@ public class ContentViewCore implements MotionEventDelegate { params.getExtraHeadersString(), params.mPostData, params.mBaseUrlForDataUrl, - params.mVirtualUrlForDataUrl); + params.mVirtualUrlForDataUrl, + params.mCanLoadLocalResources); } void setAllUserAgentOverridesInHistory() { @@ -2112,7 +2113,8 @@ public class ContentViewCore implements MotionEventDelegate { String extraHeaders, byte[] postData, String baseUrlForDataUrl, - String virtualUrlForDataUrl); + String virtualUrlForDataUrl, + boolean canLoadLocalResources); private native void nativeSetAllUserAgentOverridesInHistory(int nativeContentViewCoreImpl, String userAgentOverride); diff --git a/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java b/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java index 88d6200..72a2fb1 100644 --- a/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java +++ b/content/public/android/java/src/org/chromium/content/browser/LoadUrlParams.java @@ -41,6 +41,7 @@ public class LoadUrlParams { byte[] mPostData; String mBaseUrlForDataUrl; String mVirtualUrlForDataUrl; + boolean mCanLoadLocalResources; public LoadUrlParams(String url) { // Check initializeConstants was called. @@ -200,6 +201,27 @@ public class LoadUrlParams { mVirtualUrlForDataUrl = virtualUrl; } + /** + * Set whether the load should be able to access local resources. This + * defaults to false. + */ + public void setCanLoadLocalResources(boolean canLoad) { + mCanLoadLocalResources = canLoad; + } + + public int getLoadUrlType() { + return mLoadUrlType; + } + + public boolean isBaseUrlDataScheme() { + // If there's no base url set, but this is a data load then + // treat the scheme as data:. + if (mBaseUrlForDataUrl == null && mLoadUrlType == LOAD_TYPE_DATA) { + return true; + } + return nativeIsDataScheme(mBaseUrlForDataUrl); + } + @SuppressWarnings("unused") @CalledByNative private static void initializeConstants( @@ -216,4 +238,10 @@ public class LoadUrlParams { UA_OVERRIDE_FALSE = ua_override_false; UA_OVERRIDE_TRUE = ua_override_true; } + + /** + * Parses |url| as a GURL on the native side, and + * returns true if it's scheme is data:. + */ + private static native boolean nativeIsDataScheme(String url); } diff --git a/content/public/browser/navigation_controller.cc b/content/public/browser/navigation_controller.cc index a7f7bf6..4c9ba58 100644 --- a/content/public/browser/navigation_controller.cc +++ b/content/public/browser/navigation_controller.cc @@ -14,7 +14,8 @@ NavigationController::LoadURLParams::LoadURLParams(const GURL& url) transition_type(PAGE_TRANSITION_LINK), is_renderer_initiated(false), override_user_agent(UA_OVERRIDE_INHERIT), - browser_initiated_post_data(NULL) { + browser_initiated_post_data(NULL), + can_load_local_resources(false) { } NavigationController::LoadURLParams::~LoadURLParams() { diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index 893887c..8a64d48 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h @@ -148,6 +148,9 @@ class NavigationController { // after LoadURLWithParams call. scoped_refptr<base::RefCountedMemory> browser_initiated_post_data; + // True if this URL should be able to access local resources. + bool can_load_local_resources; + explicit LoadURLParams(const GURL& url); ~LoadURLParams(); diff --git a/content/public/browser/navigation_entry.h b/content/public/browser/navigation_entry.h index c907045..63af687 100644 --- a/content/public/browser/navigation_entry.h +++ b/content/public/browser/navigation_entry.h @@ -177,6 +177,11 @@ class NavigationEntry { // - or this navigation was copied from a foreign session. virtual void SetTimestamp(base::Time timestamp) = 0; virtual base::Time GetTimestamp() const = 0; + + // Used to specify if this entry should be able to access local file:// + // resources. + virtual void SetCanLoadLocalResources(bool allow) = 0; + virtual bool GetCanLoadLocalResources() const = 0; }; } // namespace content diff --git a/content/public/renderer/document_state.cc b/content/public/renderer/document_state.cc index 2aa9ffb..231c9d6 100644 --- a/content/public/renderer/document_state.cc +++ b/content/public/renderer/document_state.cc @@ -27,7 +27,8 @@ DocumentState::DocumentState() cache_policy_override_set_(false), cache_policy_override_(WebKit::WebURLRequest::UseProtocolCachePolicy), referrer_policy_set_(false), - referrer_policy_(WebKit::WebReferrerPolicyDefault) { + referrer_policy_(WebKit::WebReferrerPolicyDefault), + can_load_local_resources_(false) { } DocumentState::~DocumentState() {} diff --git a/content/public/renderer/document_state.h b/content/public/renderer/document_state.h index d9dbb89..a07f113 100644 --- a/content/public/renderer/document_state.h +++ b/content/public/renderer/document_state.h @@ -258,6 +258,11 @@ class DocumentState : public WebKit::WebDataSource::ExtraData { NavigationState* navigation_state() { return navigation_state_.get(); } void set_navigation_state(NavigationState* navigation_state); + bool can_load_local_resources() const { return can_load_local_resources_; } + void set_can_load_local_resources(bool can_load) { + can_load_local_resources_ = can_load; + } + private: base::Time request_time_; base::Time start_load_time_; @@ -300,6 +305,8 @@ class DocumentState : public WebKit::WebDataSource::ExtraData { scoped_ptr<webkit_glue::AltErrorPageResourceFetcher> alt_error_page_fetcher_; scoped_ptr<NavigationState> navigation_state_; + + bool can_load_local_resources_; }; #endif // CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_ diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index cf18e69..da8a9ac 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -3127,6 +3127,7 @@ void RenderViewImpl::PopulateDocumentStateFromPending( document_state->set_must_reset_scroll_and_scale_state( params.navigation_type == ViewMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL); + document_state->set_can_load_local_resources(params.can_load_local_resources); } NavigationState* RenderViewImpl::CreateNavigationStateFromPending() { |