LayoutTests:
authorkmccullo <kmccullo@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Mar 2007 02:18:43 +0000 (02:18 +0000)
committerkmccullo <kmccullo@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Mar 2007 02:18:43 +0000 (02:18 +0000)
        Reviewed by Geoff.

        - rdar://problem/4922454
        - This fixes a security issue by making remote referrers not able to access local
        resources, unless they register their schemes to be treated as local. The result is
        that those schemes can access local resources and cannot be accessed by remote
        referrers.
        Because this behavior is new a link-on-or-after check is made to determine if the
        app should use the older, less safe, behavior.

        * fast/loader/local-CSS-from-local-expected.txt: Added.
        * fast/loader/local-CSS-from-local.html: Added.
        * fast/loader/local-JavaScript-from-local-expected.txt: Added.
        * fast/loader/local-JavaScript-from-local.html: Added.
        * fast/loader/local-iFrame-source-from-local-expected.txt: Added.
        * fast/loader/local-iFrame-source-from-local.html: Added.
        * fast/loader/local-image-from-local-expected.txt: Added.
        * fast/loader/local-image-from-local.html: Added.
        * http/tests/security/local-CSS-from-remote-expected.txt: Added.
        * http/tests/security/local-CSS-from-remote.html: Added.
        * http/tests/security/local-JavaScript-from-remote-expected.txt: Added.
        * http/tests/security/local-JavaScript-from-remote.html: Added.
        * http/tests/security/local-iFrame-from-remote-expected.txt: Added.
        * http/tests/security/local-iFrame-from-remote.html: Added.
        * http/tests/security/local-image-from-remote-expected.txt: Added.
        * http/tests/security/local-image-from-remote.html: Added.
        * http/tests/security/resources/compass.jpg: Added.
        * http/tests/security/resources/cssStyle.css: Added.
        * http/tests/security/resources/localPage.html: Added.
        * http/tests/security/resources/localScript.js: Added.

WebCore:

        Reviewed by Geoff.

        - rdar://problem/4922454
        - This fixes a security issue by making remote referrers not able to access local
        resources, unless they register their schemes to be treated as local. The result is
        that those schemes can access local resources and cannot be accessed by remote
        referrers.
        Because this behavior is new a link-on-or-after check is made to determine if the
        app should use the older, less safe, behavior.

        * WebCore.exp: added exported functions
        * bindings/objc/DOM.mm: consolodated function to base class
        (-[DOMElement image]):
        (-[DOMElement _imageTIFFRepresentation]):
        * dom/Document.cpp: Cache the document's ability to load local resources.
        (WebCore::Document::Document):
        (WebCore::Document::setURL):
        (WebCore::Document::shouldBeAllowedToLoadLocalResources):
        (WebCore::Document::stylesheetLoaded):
        * dom/Document.h: Cache the docuent's ability to load local resources.
        (WebCore::Document::getPendingSheet):
        (WebCore::Document::isAllowedToLoadLocalResources):
        * html/HTMLImageLoader.cpp: Moved functionality into base class.
        (WebCore::HTMLImageLoader::updateFromElement):
        (WebCore::HTMLImageLoader::dispatchLoadEvent):
        * html/HTMLLinkElement.cpp: Handles null returns correctly now.
        * html/HTMLTokenizer.cpp: Moved functionality into base class.
        (WebCore::HTMLTokenizer::notifyFinished):
        * ksvg2/misc/SVGImageLoader.cpp: Moved functionality into base class.
        (WebCore::SVGImageLoader::dispatchLoadEvent):
        * loader/Cache.cpp: Checks if the cached resource can be loaded.
        (WebCore::Cache::requestResource):
        * loader/CachedCSSStyleSheet.cpp: Moved functionality into base class.
        (WebCore::CachedCSSStyleSheet::ref):
        (WebCore::CachedCSSStyleSheet::error):
        * loader/CachedImage.cpp: Moved functionality into base class.
        (WebCore::CachedImage::CachedImage):
        * loader/CachedImage.h: Moved functionality into base class.
        (WebCore::CachedImage::canRender):
        * loader/CachedResource.cpp: Cache if the CachedResource should be treated as local
        (WebCore::CachedResource::CachedResource):
        * loader/CachedResource.h: Moved functionality into base class.
        (WebCore::CachedResource::errorOccurred):
        (WebCore::CachedResource::shouldTreatAsLocal):
        * loader/CachedScript.cpp: Moved functionality into base class.
        (WebCore::CachedScript::CachedScript):
        * loader/CachedScript.h: Moved functionality into base class.
        (WebCore::CachedScript::schedule):
        * loader/CachedXBLDocument.cpp: Moved functionality into base class.
        (WebCore::CachedXBLDocument::error):
        * loader/CachedXSLStyleSheet.cpp: Moved functionality into base class.
        (WebCore::CachedXSLStyleSheet::error):
        * loader/FrameLoader.cpp: See comments for each function below.
        (WebCore::FrameLoader::loadSubframe): Use new canLoad.
        (WebCore::FrameLoader::restrictAccessToLocal): return value of linked-on-or-after check.
        (WebCore::FrameLoader::setRestrictAccessToLocal): set value for linked-on-or-after check.
        (WebCore::localSchemes): Return set of schemes that are to be treated as local.
        (WebCore::FrameLoader::loadPlugin): Use new canLoad.
        (WebCore::FrameLoader::canLoad): Now multiple functions that each do the same work but some can take advantage of the cached values, if they were computed previously.
        (WebCore::FrameLoader::shouldHideReferrer): Extracted out the logic to determine if the referrer should be hidden so it is only calculated when needed.
        (WebCore::FrameLoader::loadResourceSynchronously): No longer calls canLoad to get hideReferrer info.
        (WebCore::FrameLoader::registerSchemeAsLocal): Functionality to register a scheme to be treated as local.
        (WebCore::FrameLoader::treatURLAsLocal): Given a URL this function determines if it should be treated as local.
        * loader/FrameLoader.h: Declared functions for this security fix.  See above.
        * loader/MainResourceLoader.cpp: Optized order of bools to regain performance.
        (WebCore::MainResourceLoader::continueAfterContentPolicy):
        * loader/SubresourceLoader.cpp: Now restricts remote from loading local resources.
        (WebCore::SubresourceLoader::create):
        * page/EventHandler.cpp: Moved functionality into base class.
        (WebCore::selectCursor):
        * platform/KURL.cpp: KURLs need to check all the registered schemes now.
        (WebCore::KURL::isLocalFile):
        * rendering/HitTestResult.cpp: Moved functionality into base class.
        (WebCore::HitTestResult::image):
        * rendering/RenderImage.cpp: Moved functionality into base class.
        (WebCore::RenderImage::setCachedImage):
        (WebCore::RenderImage::imageChanged):
        (WebCore::RenderImage::paint):
        (WebCore::RenderImage::layout):
        (WebCore::RenderImage::calcAspectRatioWidth):
        (WebCore::RenderImage::calcAspectRatioHeight):
        * rendering/RenderImage.h: Moved functionality into base class.
        (WebCore::RenderImage::errorOccurred):
        * rendering/RenderListItem.cpp: Moved functionality into base class.
        (WebCore::RenderListItem::setStyle):
        * rendering/RenderListMarker.cpp: Moved functionality into base class.
        (WebCore::RenderListMarker::isImage):
        * xml/xmlhttprequest.cpp: Check doc's cached value instead of determining independently.
        (WebCore::XMLHttpRequest::urlMatchesDocumentDomain):

WebKit:

        Reviewed by Geoff.

        - rdar://problem/4922454
        - This fixes a security issue by making remote referrers not able to access local
        resources, unless they register their schemes to be treated as local. The result is
        that those schemes can access local resources and cannot be accessed by remote
        referrers.
        Because this behavior is new a link-on-or-after check is made to determine if the
        app should use the older, less safe, behavior.

        * Misc/WebKitVersionChecks.h: added linked-on-or-after check
        * Misc/WebNSAttributedStringExtras.mm: Moved functionalit into the base class.
        (fileWrapperForElement):
        * Plugins/WebNetscapePluginStream.mm: uses new canLoad functions
        * Plugins/WebPluginContainerCheck.mm: uses new canLoad functions
        (-[WebPluginContainerCheck _isForbiddenFileLoad]):
        * WebView/WebView.mm: make linked-on-or-after check and cache value, exposes SPI
        for registering a scheme as local.
        (-[WebView _commonInitializationWithFrameName:groupName:]):
        (+[WebView registerSchemeAsLocal:]):
        * WebView/WebViewPrivate.h: exposes SPI for registering a scheme as local.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@19952 268f45cc-cd09-0410-ab3c-d52691b4dbfc

59 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/loader/local-CSS-from-local-expected.txt [new file with mode: 0644]
LayoutTests/fast/loader/local-CSS-from-local.html [new file with mode: 0644]
LayoutTests/fast/loader/local-JavaScript-from-local-expected.txt [new file with mode: 0644]
LayoutTests/fast/loader/local-JavaScript-from-local.html [new file with mode: 0644]
LayoutTests/fast/loader/local-iFrame-source-from-local-expected.txt [new file with mode: 0644]
LayoutTests/fast/loader/local-iFrame-source-from-local.html [new file with mode: 0644]
LayoutTests/fast/loader/local-image-from-local-expected.txt [new file with mode: 0644]
LayoutTests/fast/loader/local-image-from-local.html [new file with mode: 0644]
LayoutTests/http/tests/security/local-CSS-from-remote-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/local-CSS-from-remote.html [new file with mode: 0644]
LayoutTests/http/tests/security/local-JavaScript-from-remote-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/local-JavaScript-from-remote.html [new file with mode: 0644]
LayoutTests/http/tests/security/local-iFrame-from-remote-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/local-iFrame-from-remote.html [new file with mode: 0644]
LayoutTests/http/tests/security/local-image-from-remote-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/local-image-from-remote.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/compass.jpg [new file with mode: 0644]
LayoutTests/http/tests/security/resources/cssStyle.css [new file with mode: 0644]
LayoutTests/http/tests/security/resources/localPage.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/localScript.js [new file with mode: 0644]
WebCore/ChangeLog
WebCore/WebCore.exp
WebCore/bindings/objc/DOM.mm
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/html/HTMLImageLoader.cpp
WebCore/html/HTMLLinkElement.cpp
WebCore/ksvg2/misc/SVGImageLoader.cpp
WebCore/loader/Cache.cpp
WebCore/loader/CachedCSSStyleSheet.cpp
WebCore/loader/CachedImage.cpp
WebCore/loader/CachedImage.h
WebCore/loader/CachedResource.cpp
WebCore/loader/CachedResource.h
WebCore/loader/CachedScript.cpp
WebCore/loader/CachedScript.h
WebCore/loader/CachedXBLDocument.cpp
WebCore/loader/CachedXSLStyleSheet.cpp
WebCore/loader/FrameLoader.cpp
WebCore/loader/FrameLoader.h
WebCore/loader/MainResourceLoader.cpp
WebCore/loader/SubresourceLoader.cpp
WebCore/page/DragController.cpp
WebCore/page/EventHandler.cpp
WebCore/platform/KURL.cpp
WebCore/rendering/HitTestResult.cpp
WebCore/rendering/RenderImage.cpp
WebCore/rendering/RenderImage.h
WebCore/rendering/RenderListItem.cpp
WebCore/rendering/RenderListMarker.cpp
WebCore/xml/xmlhttprequest.cpp
WebKit/ChangeLog
WebKit/Misc/WebKitVersionChecks.h
WebKit/Misc/WebNSAttributedStringExtras.mm
WebKit/Plugins/WebNetscapePluginStream.mm
WebKit/Plugins/WebPluginContainerCheck.mm
WebKit/WebView/WebView.mm
WebKit/WebView/WebViewPrivate.h

index c20ae2ed80635ee9ba94b337453a77efbb09f4e5..1efaaaf100e4af776cba765b46cdef5a09184669 100644 (file)
@@ -1,3 +1,36 @@
+2007-03-02  Kevin McCullough  <kmccullough@apple.com>
+
+        Reviewed by Geoff.
+
+        - rdar://problem/4922454
+        - This fixes a security issue by making remote referrers not able to access local
+        resources, unless they register their schemes to be treated as local. The result is
+        that those schemes can access local resources and cannot be accessed by remote
+        referrers.
+        Because this behavior is new a link-on-or-after check is made to determine if the
+        app should use the older, less safe, behavior.
+
+        * fast/loader/local-CSS-from-local-expected.txt: Added.
+        * fast/loader/local-CSS-from-local.html: Added.
+        * fast/loader/local-JavaScript-from-local-expected.txt: Added.
+        * fast/loader/local-JavaScript-from-local.html: Added.
+        * fast/loader/local-iFrame-source-from-local-expected.txt: Added.
+        * fast/loader/local-iFrame-source-from-local.html: Added.
+        * fast/loader/local-image-from-local-expected.txt: Added.
+        * fast/loader/local-image-from-local.html: Added.
+        * http/tests/security/local-CSS-from-remote-expected.txt: Added.
+        * http/tests/security/local-CSS-from-remote.html: Added.
+        * http/tests/security/local-JavaScript-from-remote-expected.txt: Added.
+        * http/tests/security/local-JavaScript-from-remote.html: Added.
+        * http/tests/security/local-iFrame-from-remote-expected.txt: Added.
+        * http/tests/security/local-iFrame-from-remote.html: Added.
+        * http/tests/security/local-image-from-remote-expected.txt: Added.
+        * http/tests/security/local-image-from-remote.html: Added.
+        * http/tests/security/resources/compass.jpg: Added.
+        * http/tests/security/resources/cssStyle.css: Added.
+        * http/tests/security/resources/localPage.html: Added.
+        * http/tests/security/resources/localScript.js: Added.
+
 2007-03-02  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by kevin
diff --git a/LayoutTests/fast/loader/local-CSS-from-local-expected.txt b/LayoutTests/fast/loader/local-CSS-from-local-expected.txt
new file mode 100644 (file)
index 0000000..5f5d91b
--- /dev/null
@@ -0,0 +1,5 @@
+This test is to see if a local file can include a local CSS style. 
+If the background is yellow then the CSS was loaded.
+
+Test Passed.
+
diff --git a/LayoutTests/fast/loader/local-CSS-from-local.html b/LayoutTests/fast/loader/local-CSS-from-local.html
new file mode 100644 (file)
index 0000000..5f14bfb
--- /dev/null
@@ -0,0 +1,33 @@
+<html>
+<head>
+    <link rel="stylesheet" type="text/css" href="file:///tmp/LayoutTests/http/tests/security/resources/cssStyle.css" />
+    <script>
+        if (window.layoutTestController) {
+            layoutTestController.dumpAsText();
+        }
+    
+        function backgroundCheck() {
+            var result = document.getElementById("result");
+            var myBody = document.getElementById("myBody");
+            var style = document.defaultView.getComputedStyle(myBody, null);
+            var bgColor = style.getPropertyValue("background-color");
+            if (bgColor[4] == 2) {
+                result.innerHTML = "Test Passed.";
+            } else {
+                result.innerHTML = "Test Failed: Local CSS not remotely loaded.";
+            }
+        }
+    </script>
+</head>
+<body id="myBody" onload="backgroundCheck()">
+    <div id="div0">
+        This test is to see if a local file can include a local CSS style.
+        <br/>
+        If the background is yellow then the CSS was loaded.
+    </div>
+    </br>
+    <div id="result">
+        Test not run correctly.
+    </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/fast/loader/local-JavaScript-from-local-expected.txt b/LayoutTests/fast/loader/local-JavaScript-from-local-expected.txt
new file mode 100644 (file)
index 0000000..1efbfb6
--- /dev/null
@@ -0,0 +1,4 @@
+This test is to see if a local file can run a local script.
+
+Test Passed.
+
diff --git a/LayoutTests/fast/loader/local-JavaScript-from-local.html b/LayoutTests/fast/loader/local-JavaScript-from-local.html
new file mode 100644 (file)
index 0000000..04e0602
--- /dev/null
@@ -0,0 +1,29 @@
+<html>
+<head>
+        <script>
+            var secretness = 0;
+        </script>
+        <script src="file:///tmp/LayoutTests/http/tests/security/resources/localScript.js"/>
+        <script>
+            function test() {
+                if (window.layoutTestController)
+                    layoutTestController.dumpAsText();
+
+                    var tag = document.getElementById("result");
+                    if (secretness == 13)
+                        tag.innerHTML = "Test Passed.";
+                    else
+                        tag.innerHTML = "Test Failed: Local script not run by local file.";
+            }
+        </script>
+</head>
+<body onload="test()">
+    <div id="div0">
+        This test is to see if a local file can run a local script.
+    </div>
+    </br>
+    <div id="result">
+        Test not run correctly.
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/fast/loader/local-iFrame-source-from-local-expected.txt b/LayoutTests/fast/loader/local-iFrame-source-from-local-expected.txt
new file mode 100644 (file)
index 0000000..9080b41
--- /dev/null
@@ -0,0 +1,4 @@
+This test is to see if a local file can include a local page in an iFrame.
+
+Test Passed.
+
diff --git a/LayoutTests/fast/loader/local-iFrame-source-from-local.html b/LayoutTests/fast/loader/local-iFrame-source-from-local.html
new file mode 100644 (file)
index 0000000..ee359c1
--- /dev/null
@@ -0,0 +1,33 @@
+<html>
+<head>
+    <script>
+        if (window.layoutTestController) {
+            layoutTestController.dumpAsText();
+        }
+    
+        function iFrameTest() {
+            if (window.layoutTestController)
+                layoutTestController.dumpAsText();
+
+            var result = document.getElementById("result");
+
+            var myFrameDocument = document.getElementById("myFrame").contentDocument;
+            if (myFrameDocument) {
+                result.innerHTML = "Test Passed.";
+            } else {
+                result.innerHTML = "Test Failed: Local page not locally loaded into iFrame.";
+            }
+        }
+    </script>
+</head>
+<body>
+    <div id="div0">
+        This test is to see if a local file can include a local page in an iFrame.
+    </div>
+    </br>
+    <div id="result">
+        Test not run correctly.
+    </div>
+    <iFrame id="myFrame" onload="iFrameTest()" src="file:///tmp/LayoutTests/http/tests/security/resources/localPage.html" />
+</body>
+</html>
diff --git a/LayoutTests/fast/loader/local-image-from-local-expected.txt b/LayoutTests/fast/loader/local-image-from-local-expected.txt
new file mode 100644 (file)
index 0000000..5fed28f
--- /dev/null
@@ -0,0 +1,5 @@
+This test is to see if a remote file can include a local image.
+
+Test Passed.
+
+
diff --git a/LayoutTests/fast/loader/local-image-from-local.html b/LayoutTests/fast/loader/local-image-from-local.html
new file mode 100644 (file)
index 0000000..e53e3dd
--- /dev/null
@@ -0,0 +1,29 @@
+<html>
+<head>
+    <script>        
+        if (window.layoutTestController)
+            layoutTestController.dumpAsText();
+
+        function imgError() {
+            var result = document.getElementById("result");
+            result.innerHTML = "Test Failed: Image Load Error.";
+        }
+
+        function imgLoad() {
+            var result = document.getElementById("result");
+            result.innerHTML = "Test Passed.";
+        }
+    </script>
+</head>
+<body>
+    <div id="div0">
+        This test is to see if a remote file can include a local image.
+    </div>
+    </br>
+    <div id="result">
+        Test has not run.
+    </div>
+    </br>
+    <img id="myImg" src="file:///tmp/LayoutTests/http/tests/security/resources/compass.jpg" onError="imgError()" onLoad="imgLoad()"/>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/local-CSS-from-remote-expected.txt b/LayoutTests/http/tests/security/local-CSS-from-remote-expected.txt
new file mode 100644 (file)
index 0000000..1af2a7e
--- /dev/null
@@ -0,0 +1,5 @@
+This test is to see if a remote file can include a local CSS style. 
+If the background is yellow then the CSS was loaded.
+
+Test Passed.
+
diff --git a/LayoutTests/http/tests/security/local-CSS-from-remote.html b/LayoutTests/http/tests/security/local-CSS-from-remote.html
new file mode 100644 (file)
index 0000000..341b1d0
--- /dev/null
@@ -0,0 +1,33 @@
+<html>
+<head>
+    <link rel="stylesheet" type="text/css" href="file:///tmp/LayoutTests/http/tests/security/resources/cssStyle.css" />
+    <script>
+        if (window.layoutTestController) {
+            layoutTestController.dumpAsText();
+        }
+
+        function backgroundCheck() {
+            var result = document.getElementById("result");
+            var myBody = document.getElementById("myBody");
+            var style = document.defaultView.getComputedStyle(myBody, null);
+            var bgColor = style.getPropertyValue("background-color");
+            if (bgColor[4] == 2) {
+                result.innerHTML = "Test Failed: Local CSS remotely loaded.";
+            } else {
+                result.innerHTML = "Test Passed.";
+            }
+        }
+    </script>
+</head>
+<body id="myBody" onload="backgroundCheck()">
+    <div id="other">
+        This test is to see if a remote file can include a local CSS style.
+        <br/>
+        If the background is yellow then the CSS was loaded.
+    </div>
+    </br>
+    <div id="result">
+        Test not run correctly.
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/local-JavaScript-from-remote-expected.txt b/LayoutTests/http/tests/security/local-JavaScript-from-remote-expected.txt
new file mode 100644 (file)
index 0000000..8e4308e
--- /dev/null
@@ -0,0 +1,4 @@
+This test is to see if a remote file can run a local script.
+
+Test Passed.
+
diff --git a/LayoutTests/http/tests/security/local-JavaScript-from-remote.html b/LayoutTests/http/tests/security/local-JavaScript-from-remote.html
new file mode 100644 (file)
index 0000000..d193060
--- /dev/null
@@ -0,0 +1,29 @@
+<html>
+<head>
+        <script>
+            var secretness = 0;
+        </script>
+        <script src="file:///tmp/LayoutTests/http/tests/security/resources/localScript.js"/>
+        <script>
+            function test() {
+                if (window.layoutTestController)
+                    layoutTestController.dumpAsText();
+
+                var tag = document.getElementById("result");
+                if (secretness == 13)
+                    tag.innerHTML = "Test Failed: Local script run remotely.";
+                else
+                    tag.innerHTML = "Test Passed.";
+            }
+        </script>
+</head>
+<body onload="test()">
+    <div id="div0">
+        This test is to see if a remote file can run a local script.
+    </div>
+    </br>
+    <div id="result">
+        Test not run correctly.
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/local-iFrame-from-remote-expected.txt b/LayoutTests/http/tests/security/local-iFrame-from-remote-expected.txt
new file mode 100644 (file)
index 0000000..cd4b7c8
--- /dev/null
@@ -0,0 +1,4 @@
+This test is to see if a remote file can include a local page in an iFrame.
+
+Test Passed.
+
diff --git a/LayoutTests/http/tests/security/local-iFrame-from-remote.html b/LayoutTests/http/tests/security/local-iFrame-from-remote.html
new file mode 100644 (file)
index 0000000..340a6cd
--- /dev/null
@@ -0,0 +1,31 @@
+<html>
+<head>
+    <script>
+        if (window.layoutTestController) {
+            layoutTestController.dumpAsText();
+        }
+    
+        function iFrameTest() {
+            var result = document.getElementById("result");
+
+            var myFrameDocument = document.getElementById("myFrame").contentDocument;
+            if (myFrameDocument) {
+                result.innerHTML = "Test Failed: Local page remotely loaded into iFrame.";
+            } else {
+                result.innerHTML = "Test Passed.";
+            }
+            
+        }
+    </script>
+</head>
+<body onload="iFrameTest()">
+    <div id="div0">
+        This test is to see if a remote file can include a local page in an iFrame.
+    </div>
+    </br>
+    <div id="result">
+        Test not run correctly.
+    </div>
+    <iFrame id="myFrame" src="file:///tmp/LayoutTests/http/tests/security/resources/localPage.html" />
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/local-image-from-remote-expected.txt b/LayoutTests/http/tests/security/local-image-from-remote-expected.txt
new file mode 100644 (file)
index 0000000..5fed28f
--- /dev/null
@@ -0,0 +1,5 @@
+This test is to see if a remote file can include a local image.
+
+Test Passed.
+
+
diff --git a/LayoutTests/http/tests/security/local-image-from-remote.html b/LayoutTests/http/tests/security/local-image-from-remote.html
new file mode 100644 (file)
index 0000000..610eb22
--- /dev/null
@@ -0,0 +1,31 @@
+<html>
+<head>
+    <script>        
+        if (window.layoutTestController)
+            layoutTestController.dumpAsText();
+        
+        function imageTest() {
+            var result = document.getElementById("result");
+
+            var myImg = document.getElementById("myImg");
+            if (myImg.height == 0 && myImg.width == 0) {
+                result.innerHTML = "Test Passed.";
+            } else {
+                result.innerHTML = "Test Failed: Local image loaded remotely.";
+            }
+            
+        }
+    </script>
+</head>
+<body onLoad="imageTest()">
+    <div id="div0">
+        This test is to see if a remote file can include a local image.
+    </div>
+    </br>
+    <div id="result">
+        Test has not run.
+    </div>
+    </br>
+    <img id="myImg" src="file:///tmp/LayoutTests/http/tests/security/resources/compass.jpg" />
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/resources/compass.jpg b/LayoutTests/http/tests/security/resources/compass.jpg
new file mode 100644 (file)
index 0000000..671f7b1
Binary files /dev/null and b/LayoutTests/http/tests/security/resources/compass.jpg differ
diff --git a/LayoutTests/http/tests/security/resources/cssStyle.css b/LayoutTests/http/tests/security/resources/cssStyle.css
new file mode 100644 (file)
index 0000000..30dcc09
--- /dev/null
@@ -0,0 +1,4 @@
+body {
+    background-color: yellow;
+}
+
diff --git a/LayoutTests/http/tests/security/resources/localPage.html b/LayoutTests/http/tests/security/resources/localPage.html
new file mode 100644 (file)
index 0000000..b73e31f
--- /dev/null
@@ -0,0 +1,3 @@
+<div id="innerDiv">
+    You can see the contents of this file.
+</div>
diff --git a/LayoutTests/http/tests/security/resources/localScript.js b/LayoutTests/http/tests/security/resources/localScript.js
new file mode 100644 (file)
index 0000000..ef3db19
--- /dev/null
@@ -0,0 +1 @@
+var secretness = 13;
index 3f0c8cfe89016981a9d474c762126f3337ed03c2..e384964fa859401916e1d3536d651fc7d6eb9106 100644 (file)
@@ -1,3 +1,95 @@
+2007-03-02  Kevin McCullough  <kmccullough@apple.com>
+
+        Reviewed by Geoff.
+
+        - rdar://problem/4922454
+        - This fixes a security issue by making remote referrers not able to access local
+        resources, unless they register their schemes to be treated as local. The result is
+        that those schemes can access local resources and cannot be accessed by remote
+        referrers.
+        Because this behavior is new a link-on-or-after check is made to determine if the
+        app should use the older, less safe, behavior.
+
+        * WebCore.exp: added exported functions
+        * bindings/objc/DOM.mm: consolodated function to base class
+        (-[DOMElement image]):
+        (-[DOMElement _imageTIFFRepresentation]):
+        * dom/Document.cpp: Cache the document's ability to load local resources.
+        (WebCore::Document::Document):
+        (WebCore::Document::setURL):
+        (WebCore::Document::shouldBeAllowedToLoadLocalResources):
+        (WebCore::Document::stylesheetLoaded):
+        * dom/Document.h: Cache the docuent's ability to load local resources.
+        (WebCore::Document::getPendingSheet):
+        (WebCore::Document::isAllowedToLoadLocalResources):
+        * html/HTMLImageLoader.cpp: Moved functionality into base class.
+        (WebCore::HTMLImageLoader::updateFromElement):
+        (WebCore::HTMLImageLoader::dispatchLoadEvent):
+        * html/HTMLLinkElement.cpp: Handles null returns correctly now.
+        * html/HTMLTokenizer.cpp: Moved functionality into base class.
+        (WebCore::HTMLTokenizer::notifyFinished):
+        * ksvg2/misc/SVGImageLoader.cpp: Moved functionality into base class.
+        (WebCore::SVGImageLoader::dispatchLoadEvent):
+        * loader/Cache.cpp: Checks if the cached resource can be loaded.
+        (WebCore::Cache::requestResource):
+        * loader/CachedCSSStyleSheet.cpp: Moved functionality into base class.
+        (WebCore::CachedCSSStyleSheet::ref):
+        (WebCore::CachedCSSStyleSheet::error):
+        * loader/CachedImage.cpp: Moved functionality into base class.
+        (WebCore::CachedImage::CachedImage):
+        * loader/CachedImage.h: Moved functionality into base class.
+        (WebCore::CachedImage::canRender):
+        * loader/CachedResource.cpp: Cache if the CachedResource should be treated as local
+        (WebCore::CachedResource::CachedResource):
+        * loader/CachedResource.h: Moved functionality into base class.
+        (WebCore::CachedResource::errorOccurred):
+        (WebCore::CachedResource::shouldTreatAsLocal):
+        * loader/CachedScript.cpp: Moved functionality into base class.
+        (WebCore::CachedScript::CachedScript):
+        * loader/CachedScript.h: Moved functionality into base class.
+        (WebCore::CachedScript::schedule):
+        * loader/CachedXBLDocument.cpp: Moved functionality into base class.
+        (WebCore::CachedXBLDocument::error):
+        * loader/CachedXSLStyleSheet.cpp: Moved functionality into base class.
+        (WebCore::CachedXSLStyleSheet::error):
+        * loader/FrameLoader.cpp: See comments for each function below.
+        (WebCore::FrameLoader::loadSubframe): Use new canLoad.
+        (WebCore::FrameLoader::restrictAccessToLocal): return value of linked-on-or-after check.
+        (WebCore::FrameLoader::setRestrictAccessToLocal): set value for linked-on-or-after check.
+        (WebCore::localSchemes): Return set of schemes that are to be treated as local.
+        (WebCore::FrameLoader::loadPlugin): Use new canLoad.
+        (WebCore::FrameLoader::canLoad): Now multiple functions that each do the same work but some can take advantage of the cached values, if they were computed previously.
+        (WebCore::FrameLoader::shouldHideReferrer): Extracted out the logic to determine if the referrer should be hidden so it is only calculated when needed.
+        (WebCore::FrameLoader::loadResourceSynchronously): No longer calls canLoad to get hideReferrer info.
+        (WebCore::FrameLoader::registerSchemeAsLocal): Functionality to register a scheme to be treated as local.
+        (WebCore::FrameLoader::treatURLAsLocal): Given a URL this function determines if it should be treated as local.
+        * loader/FrameLoader.h: Declared functions for this security fix.  See above.
+        * loader/MainResourceLoader.cpp: Optized order of bools to regain performance.
+        (WebCore::MainResourceLoader::continueAfterContentPolicy):
+        * loader/SubresourceLoader.cpp: Now restricts remote from loading local resources.
+        (WebCore::SubresourceLoader::create):
+        * page/EventHandler.cpp: Moved functionality into base class.
+        (WebCore::selectCursor):
+        * platform/KURL.cpp: KURLs need to check all the registered schemes now.
+        (WebCore::KURL::isLocalFile):
+        * rendering/HitTestResult.cpp: Moved functionality into base class.
+        (WebCore::HitTestResult::image):
+        * rendering/RenderImage.cpp: Moved functionality into base class.
+        (WebCore::RenderImage::setCachedImage):
+        (WebCore::RenderImage::imageChanged):
+        (WebCore::RenderImage::paint):
+        (WebCore::RenderImage::layout):
+        (WebCore::RenderImage::calcAspectRatioWidth):
+        (WebCore::RenderImage::calcAspectRatioHeight):
+        * rendering/RenderImage.h: Moved functionality into base class.
+        (WebCore::RenderImage::errorOccurred):
+        * rendering/RenderListItem.cpp: Moved functionality into base class.
+        (WebCore::RenderListItem::setStyle):
+        * rendering/RenderListMarker.cpp: Moved functionality into base class.
+        (WebCore::RenderListMarker::isImage):
+        * xml/xmlhttprequest.cpp: Check doc's cached value instead of determining independently.
+        (WebCore::XMLHttpRequest::urlMatchesDocumentDomain):
+
 2007-03-02  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by kevin
index 4473f908b753ea3fd449c6f9cb9e1cbd29e545cc..471a44e346a2057f5a100a8b1d0ee75a109ace7b 100644 (file)
@@ -145,13 +145,16 @@ __ZN7WebCore11FrameLoader14scrollToAnchorERKNS_4KURLE
 __ZN7WebCore11FrameLoader14stopAllLoadersEv
 __ZN7WebCore11FrameLoader16detachFromParentEv
 __ZN7WebCore11FrameLoader18currentHistoryItemEv
+__ZN7WebCore11FrameLoader18shouldHideReferrerERKNS_4KURLERKNS_6StringE
 __ZN7WebCore11FrameLoader20continueLoadWithDataEPNS_12SharedBufferERKNS_6StringES5_RKNS_4KURLE
 __ZN7WebCore11FrameLoader21addPlugInStreamLoaderEPNS_14ResourceLoaderE
+__ZN7WebCore11FrameLoader21registerSchemeAsLocalERKNS_6StringE
 __ZN7WebCore11FrameLoader21setCurrentHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
 __ZN7WebCore11FrameLoader22setPreviousHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
 __ZN7WebCore11FrameLoader23reloadAllowingStaleDataERKNS_6StringE
 __ZN7WebCore11FrameLoader23timeOfLastCompletedLoadEv
 __ZN7WebCore11FrameLoader24removePlugInStreamLoaderEPNS_14ResourceLoaderE
+__ZN7WebCore11FrameLoader24setRestrictAccessToLocalEb
 __ZN7WebCore11FrameLoader25provisionalDocumentLoaderEv
 __ZN7WebCore11FrameLoader25setProvisionalHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
 __ZN7WebCore11FrameLoader26saveDocumentAndScrollStateEv
@@ -166,7 +169,7 @@ __ZN7WebCore11FrameLoader4loadERKNS_4KURLEPNS_5EventE
 __ZN7WebCore11FrameLoader4loadERKNS_4KURLERKNS_6StringENS_13FrameLoadTypeES6_PNS_5EventEPNS_15HTMLFormElementERKN3WTF7HashMapIS4_S4_NSC_7StrHashIS4_EENSC_10HashTraitsIS4_EESH_EE
 __ZN7WebCore11FrameLoader5clearEb
 __ZN7WebCore11FrameLoader6reloadEv
-__ZN7WebCore11FrameLoader7canLoadERKNS_4KURLERKNS_6StringERb
+__ZN7WebCore11FrameLoader7canLoadERKNS_4KURLEPKNS_8DocumentE
 __ZN7WebCore11HistoryItem12addChildItemEN3WTF10PassRefPtrIS0_EE
 __ZN7WebCore11HistoryItem12setURLStringERKNS_6StringE
 __ZN7WebCore11HistoryItem12setViewStateEP11objc_object
index 37d5721e0100dcb6a909fe5bb4721c7b1df98e94..c4b071089b340d237fea3dab83d62d81337541f0 100644 (file)
@@ -491,7 +491,7 @@ static NSArray *kit(const Vector<IntRect>& rects)
     WebCore::RenderObject* renderer = [self _element]->renderer();
     if (renderer && renderer->isImage()) {
         WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer);
-        if (img->cachedImage() && !img->cachedImage()->isErrorImage())
+        if (img->cachedImage() && !img->cachedImage()->errorOccurred())
             return img->cachedImage()->image()->getNSImage();
     }
     return nil;
@@ -516,7 +516,7 @@ static NSArray *kit(const Vector<IntRect>& rects)
     WebCore::RenderObject* renderer = [self _element]->renderer();
     if (renderer && renderer->isImage()) {
         WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer);
-        if (img->cachedImage() && !img->cachedImage()->isErrorImage())
+        if (img->cachedImage() && !img->cachedImage()->errorOccurred())
             return (NSData*)(img->cachedImage()->image()->getTIFFRepresentation());
     }
     return nil;
index a559841bd05f6a0f50e8f88795952f62d38fcce1..d1bc187c3d250bb84f6e89814d0b2ce0c01ce5af 100644 (file)
@@ -299,6 +299,7 @@ Document::Document(DOMImplementation* impl, FrameView *v)
     , m_accessKeyMapValid(false)
     , m_createRenderers(true)
     , m_inPageCache(false)
+    , m_isAllowedToLoadLocalResources(false)
 {
     m_document.resetSkippingRef(this);
 
@@ -1251,8 +1252,6 @@ void Document::open()
         setURL(parent->baseURL());
         setBaseURL(parent->baseURL());
     }
-    else
-        setURL(m_url);
 
     if ((frame() && frame()->loader()->isLoadingMainResource()) || (tokenizer() && tokenizer()->executingScript()))
         return;
@@ -1512,9 +1511,30 @@ void Document::clear()
 
 void Document::setURL(const DeprecatedString& url)
 {
+    if (url == m_url)
+        return;
+
     m_url = url;
     if (m_styleSelector)
         m_styleSelector->setEncodedURL(m_url);
+
+    m_isAllowedToLoadLocalResources = shouldBeAllowedToLoadLocalResources();
+ }
+bool Document::shouldBeAllowedToLoadLocalResources() const
+{
+    if (FrameLoader::shouldTreatURLAsLocal(m_url))
+        return true;
+
+    Frame* frame = this->frame();
+    if (!frame)
+        return false;
+    
+    DocumentLoader* documentLoader = frame->loader()->documentLoader();
+    if (!documentLoader)
+        return false;
+    
+    return documentLoader->substituteData().isValid();
 }
 
 void Document::setBaseURL(const DeprecatedString& baseURL) 
@@ -1880,7 +1900,7 @@ void Document::stylesheetLoaded()
         printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
 #endif
 
-    updateStyleSelector();    
+    updateStyleSelector();
 }
 
 void Document::updateStyleSelector()
index 4e0b597a83330e02ed058dfc440063c5a617da34..cbe2852741e45b28c28fa135af2c8183e3d5446f 100644 (file)
@@ -618,6 +618,9 @@ public:
 
     String iconURL();
     void setIconURL(const String& iconURL, const String& type);
+
+    bool isAllowedToLoadLocalResources() const { return m_isAllowedToLoadLocalResources; }
+
 protected:
     CSSStyleSelector* m_styleSelector;
     FrameView* m_view;
@@ -628,7 +631,7 @@ protected:
     DeprecatedString m_url;
     DeprecatedString m_baseURL;
     String m_baseTarget;
-    
+
     RefPtr<DocumentType> m_docType;
     RefPtr<DOMImplementation> m_implementation;
 
@@ -783,6 +786,8 @@ public:
 #endif
 
 private:
+    bool shouldBeAllowedToLoadLocalResources() const;
+
     void updateTitle();
     void removeAllDisconnectedNodeEventListeners();
     void imageLoadEventTimerFired(Timer<Document>*);
@@ -830,6 +835,8 @@ private:
     bool m_createRenderers;
     bool m_inPageCache;
     String m_iconURL;
+
+    bool m_isAllowedToLoadLocalResources;
 };
 
 } //namespace
index 301ea9d3eb75d58c6396ed4b7938dbba2f447e5d..122c3113f3215412958be8377851a6326555071d 100644 (file)
@@ -123,7 +123,7 @@ void HTMLImageLoader::dispatchLoadEvent()
 {
     if (!haveFiredLoadEvent() && image()) {
         setHaveFiredLoadEvent(true);
-        element()->dispatchHTMLEvent(image()->isErrorImage() ? errorEvent : loadEvent, false, false);
+        element()->dispatchHTMLEvent(image()->errorOccurred() ? errorEvent : loadEvent, false, false);
     }
 }
 
index 4daeb722213b7a6c0e3df155f260c55ba0c4a060..60bad6bf1648035fdc9ac10966cfe1a193327316 100644 (file)
@@ -179,7 +179,7 @@ void HTMLLinkElement::process()
             // stylesheet.  Alternate stylesheets don't hold up render tree construction.
             if (!isAlternate())
                 document()->addPendingSheet();
-            
+
             String chset = getAttribute(charsetAttr);
             if (chset.isEmpty() && document()->frame())
                 chset = document()->frame()->loader()->encoding();
@@ -194,6 +194,10 @@ void HTMLLinkElement::process()
             m_cachedSheet = document()->docLoader()->requestCSSStyleSheet(m_url, chset);
             if (m_cachedSheet)
                 m_cachedSheet->ref(this);
+            else if (!isAlternate()) { // request may have been denied if stylesheet is local and document is remote.
+                m_loading = false;
+                document()->stylesheetLoaded();
+            }
         }
     } else if (m_sheet) {
         // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
index ae39542279ebefd4e7ab3fbc178901fe8835cdd7..a57055f56048b86087d3d8322ead6dac1a9debf0 100644 (file)
@@ -70,7 +70,7 @@ void SVGImageLoader::dispatchLoadEvent()
 {
     if (!haveFiredLoadEvent() && image()) {
         setHaveFiredLoadEvent(true);
-        if (image()->isErrorImage()) {
+        if (image()->errorOccurred()) {
             // FIXME: We're supposed to put the document in an "error state" per the spec.
         } else
             static_cast<SVGElement*>(element())->sendSVGLoadEventIfPossible(true);
index ca357d105f05a97cc95cf5850b4fefba3d7a4f20..d5c049e86a01cefaa1b3b2226026d4b474e2e7c8 100644 (file)
@@ -34,6 +34,7 @@
 #include "CachedXSLStyleSheet.h"
 #include "DocLoader.h"
 #include "Document.h"
+#include "FrameLoader.h"
 #include "Image.h"
 #include "ResourceHandle.h"
 
@@ -87,7 +88,15 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
     // Look up the resource in our map.
     CachedResource* resource = m_resources.get(url.url());
 
-    if (!resource) {
+    if (resource) {
+        if (FrameLoader::restrictAccessToLocal()
+         && !FrameLoader::canLoad(*resource, docLoader->doc()))
+            return 0;
+    } else {
+        if (FrameLoader::restrictAccessToLocal()
+         && !FrameLoader::canLoad(url, docLoader->doc()))
+            return 0;
+
         // The resource does not exist.  Create it.
         resource = createResource(type, docLoader, url, expireDate, charset);
         ASSERT(resource);
index b5e1eef543c9ce9257f0f2b8d46309ae241c102f..ee61c5301b6bd6bcfbaec5020981980ef70233ac 100644 (file)
@@ -59,7 +59,7 @@ void CachedCSSStyleSheet::ref(CachedResourceClient *c)
     CachedResource::ref(c);
 
     if (!m_loading)
-        c->setCSSStyleSheet(m_url, m_decoder->encoding().name(), m_sheet);
+        c->setCSSStyleSheet(m_url, m_decoder->encoding().name(), errorOccurred() ? "" : m_sheet);
 }
 
 void CachedCSSStyleSheet::setEncoding(const String& chs)
@@ -92,6 +92,7 @@ void CachedCSSStyleSheet::checkNotify()
 void CachedCSSStyleSheet::error()
 {
     m_loading = false;
+    m_errorOccurred = true;
     checkNotify();
 }
 
index c4e10a2364397924abc2c92aee7d14d0625ab110..4db0ef1a0741c037e606995925ea1c996738f790 100644 (file)
@@ -56,7 +56,6 @@ CachedImage::CachedImage(DocLoader* docLoader, const String& url, CachePolicy ca
     , m_dataSize(0)
 {
     m_image = 0;
-    m_errorOccurred = false;
     m_status = Unknown;
     if (!docLoader || docLoader->autoLoadImages())  {
         m_loading = true;
@@ -70,7 +69,6 @@ CachedImage::CachedImage(Image* image)
     , m_dataSize(0)
 {
     m_image = image;
-    m_errorOccurred = false;
     m_status = Cached;
     m_loading = false;
 }
index 80bcc621c5c7c1f219d1278bd3439f9fcb5fbf99..07e5363aa8987c52cb13d6c274dfec4b255bd790 100644 (file)
@@ -47,7 +47,7 @@ public:
 
     Image* image() const;
 
-    bool canRender() const { return !isErrorImage() && imageSize().width() > 0 && imageSize().height() > 0; }
+    bool canRender() const { return !errorOccurred() && imageSize().width() > 0 && imageSize().height() > 0; }
 
     IntSize imageSize() const;  // returns the size of the complete image
     IntRect imageRect() const;  // The size of the image.
@@ -58,8 +58,6 @@ public:
     virtual void data(Vector<char>&, bool allDataReceived);
     virtual void error();
 
-    bool isErrorImage() const { return m_errorOccurred; }
-
     virtual bool schedule() const { return true; }
 
     void checkNotify();
@@ -80,8 +78,6 @@ private:
 
     Image* m_image;
     int m_dataSize;
-    
-    bool m_errorOccurred : 1;
 
     friend class Cache;
 };
index 5b33a1532c3634b169bd6a43fac7b00a1ed96ea0..6a2b51b0bff36e96373930e22f4d1fad265a9311 100644 (file)
@@ -30,6 +30,7 @@
 #include "CachedResource.h"
 
 #include "Cache.h"
+#include "FrameLoader.h"
 #include "Request.h"
 #include <KURL.h>
 #include <wtf/Vector.h>
@@ -54,6 +55,8 @@ CachedResource::CachedResource(const String& URL, Type type, CachePolicy cachePo
     m_deleted = false;
     m_lruIndex = 0;
 #endif
+    m_errorOccurred = false;
+    m_shouldTreatAsLocal = FrameLoader::shouldTreatURLAsLocal(m_url);
 }
 
 CachedResource::~CachedResource()
index dc241bacfe9a8af17701e6df95f6ddc0d8810755..4bae871dd4a33aefbd6b63255c938846534a99ff 100644 (file)
@@ -127,6 +127,9 @@ public:
     String accept() const { return m_accept; }
     void setAccept(const String& accept) { m_accept = accept; }
 
+    bool errorOccurred() const { return m_errorOccurred; }
+    bool treatAsLocal() const { return m_shouldTreatAsLocal; }
+
 protected:
     void setSize(unsigned size);
 
@@ -142,6 +145,8 @@ protected:
     Type m_type;
     Status m_status;
 
+    bool m_errorOccurred;
+
 private:
     unsigned m_size;
     unsigned m_accessCount;
@@ -160,6 +165,8 @@ private:
     CachedResource* m_nextInLRUList;
     CachedResource* m_prevInLRUList;
     friend class Cache;
+    
+    bool m_shouldTreatAsLocal;
 };
 
 }
index dc40cbd26ac1077a7d5047fad599861b74a5b67d..1be29ad49edff1f3e25bca729ef0f32007d621f9 100644 (file)
@@ -45,7 +45,6 @@ CachedScript::CachedScript(DocLoader* dl, const String& url, CachePolicy cachePo
     // But some websites think their scripts are <some wrong mimetype here>
     // and refuse to serve them if we only accept application/x-javascript.
     setAccept("*/*");
-    m_errorOccurred = false;
     // load the file
     cache()->loader()->load(dl, this, false);
     m_loading = true;
index 4f7f7900fa0aaf623d0d2257a1604c6d342b3c97..f8b7f7fd85ae96b6bef981232110424b10e1e6f3 100644 (file)
@@ -49,15 +49,12 @@ namespace WebCore {
         virtual void error();
 
         virtual bool schedule() const { return false; }
-        
-        bool errorOccurred() const { return m_errorOccurred; }
 
         void checkNotify();
 
     private:
         String m_script;
         TextEncoding m_encoding;
-        bool m_errorOccurred;
     };
 }
 
index 2a47820f9ca6da44f62ee54cebc39e625692f17f..aee5c811284db212e362e7ec285d0668c7294419 100644 (file)
@@ -103,6 +103,7 @@ void CachedXBLDocument::checkNotify()
 void CachedXBLDocument::error()
 {
     m_loading = false;
+    m_errorOccurred = true;
     checkNotify();
 }
 
index 15a43f481cea7310fd2100b6ebc0f2c458407db1..bdd88e42c9ebe7cc665efa1aefa6b32ecfd3e251 100644 (file)
@@ -92,6 +92,7 @@ void CachedXSLStyleSheet::checkNotify()
 void CachedXSLStyleSheet::error()
 {
     m_loading = false;
+    m_errorOccurred = true;
     checkNotify();
 }
 
index 7a74d783e4984df1ed81f389ec0a9b7dc0bd5944..40d32cf612d381f499c15fa1f276820efea3dfe2 100644 (file)
@@ -82,7 +82,9 @@
 #include <kjs/JSLock.h>
 #include <kjs/object.h>
 
-using namespace KJS;
+using KJS::UString;
+using KJS::JSLock;
+using KJS::JSValue;
 
 namespace WebCore {
 
@@ -155,6 +157,7 @@ struct ScheduledRedirection {
 };
 
 static double storedTimeOfLastCompletedLoad;
+static bool m_restrictAccessToLocal = false;
 
 static bool getString(JSValue* result, String& string)
 {
@@ -952,6 +955,28 @@ void FrameLoader::startIconLoader()
     m_iconLoader->startLoading();
 }
 
+bool FrameLoader::restrictAccessToLocal()
+{
+    return m_restrictAccessToLocal;
+}
+
+void FrameLoader::setRestrictAccessToLocal(bool access)
+{
+    m_restrictAccessToLocal = access;
+}
+
+static HashSet<String, CaseInsensitiveHash<String> >& localSchemes()
+{
+    static HashSet<String, CaseInsensitiveHash<String> > localSchemes;
+
+    if (localSchemes.isEmpty()) {
+        localSchemes.add("file");
+        localSchemes.add("applewebdata");
+    }
+
+    return localSchemes;
+}
+
 void FrameLoader::commitIconURLToIconDatabase(const KURL& icon)
 {
     IconDatabase* iconDB = IconDatabase::sharedIconDatabase();
@@ -1347,8 +1372,7 @@ bool FrameLoader::loadPlugin(RenderPart* renderer, const KURL& url, const String
         if (renderer->node() && renderer->node()->isElementNode())
             pluginElement = static_cast<Element*>(renderer->node());
 
-        bool hideReferrer;
-        if (!canLoad(url, outgoingReferrer(), hideReferrer))
+        if (!canLoad(url, frame()->document()))
             return false;
 
         widget = m_client->createPlugin(pluginElement, url, paramNames, paramValues, mimeType,
@@ -1863,14 +1887,44 @@ void FrameLoader::load(DocumentLoader* loader, FrameLoadType type, PassRefPtr<Fo
 
 bool FrameLoader::canLoad(const KURL& url, const String& referrer, bool& hideReferrer)
 {
-    bool referrerIsWebURL = referrer.startsWith("http:", false) || referrer.startsWith("https:", false);
-    bool referrerIsLocalURL = referrer.startsWith("file:", false) || referrer.startsWith("applewebdata:");
-    bool URLIsFileURL = url.protocol().startsWith("file", false);
+    hideReferrer = shouldHideReferrer(url, referrer);
+
+    if (!shouldTreatURLAsLocal(url.url()))
+        return true;
+
+    return shouldTreatURLAsLocal(referrer);
+}
+
+bool FrameLoader::canLoad(const KURL& url, const Document* doc)
+{
+    if (!shouldTreatURLAsLocal(url.url()))
+        return true;
+
+    return doc && doc->isAllowedToLoadLocalResources();
+}
+
+bool FrameLoader::canLoad(const CachedResource& resource, const Document* doc)
+{
+    if (!resource.treatAsLocal())
+        return true;
+
+    return doc && doc->isAllowedToLoadLocalResources();
+}
+
+bool FrameLoader::shouldHideReferrer(const KURL& url, const String& referrer)
+{
     bool referrerIsSecureURL = referrer.startsWith("https:", false);
-    bool URLIsSecureURL = url.protocol().startsWith("https", false);
-    
-    hideReferrer = !referrerIsWebURL || (referrerIsSecureURL && !URLIsSecureURL);
-    return !URLIsFileURL || referrerIsLocalURL;
+    bool referrerIsWebURL = referrerIsSecureURL || referrer.startsWith("http:", false);
+
+    if (!referrerIsWebURL)
+        return true;
+
+    if (!referrerIsSecureURL)
+        return false;
+
+    bool URLIsSecureURL = url.url().startsWith("https:", false);
+
+    return !URLIsSecureURL;
 }
 
 const ResourceRequest& FrameLoader::initialRequest() const
@@ -2925,9 +2979,7 @@ void FrameLoader::loadResourceSynchronously(const ResourceRequest& request, Reso
     // Since this is a subresource, we can load any URL (we ignore the return value).
     // But we still want to know whether we should hide the referrer or not, so we call the canLoad method.
     String referrer = m_outgoingReferrer;
-    bool hideReferrer;
-    canLoad(request.url(), referrer, hideReferrer);
-    if (hideReferrer)
+    if (shouldHideReferrer(request.url(), referrer))
         referrer = String();
     
     ResourceRequest initialRequest = request;
@@ -4246,4 +4298,29 @@ void FrameLoader::continueLoadWithData(SharedBuffer* buffer, const String& mimeT
     addData(buffer->data(), buffer->size());
 }
 
+void FrameLoader::registerSchemeAsLocal(const String& scheme)
+{
+    localSchemes().add(scheme);
+}
+
+bool FrameLoader::shouldTreatURLAsLocal(const String& url)
+{
+    // This avoids an allocation of another String and the HashSet containts()
+    // call for the file: and http: schemes.
+    if (url.length() >= 5) {
+        const UChar* s = url.characters();
+        if (s[0] == 'h' && s[1] == 't' && s[2] == 't' && s[3] == 'p' && s[4] == ':')
+            return false;
+        if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e' && s[4] == ':')
+            return true;
+    }
+
+    int loc = url.find(':');
+    if (loc == -1)
+        return false;
+
+    String scheme = url.left(loc);
+    return localSchemes().contains(scheme);
+}
+
 } // namespace WebCore
index d67c6e33cbdf1581d969c585fe8fe8f595d4d108..efe145a4371f18a397b5fc8a980aa1961504e3d7 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef FrameLoader_h
 #define FrameLoader_h
 
+#include "CachedResource.h"
 #include "CachePolicy.h"
 #include "FormState.h"
 #include "FrameLoaderTypes.h"
@@ -50,6 +51,7 @@ namespace KJS {
 namespace WebCore {
 
     class AuthenticationChallenge;
+    class Document;
     class DocumentLoader;
     class Element;
     class Event;
@@ -148,7 +150,11 @@ namespace WebCore {
         void load(DocumentLoader*);
         void load(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>);
 
-        bool canLoad(const KURL&, const String& referrer, bool& hideReferrer);
+        static bool canLoad(const KURL&, const String& referrer, bool& hideReferrer);
+        static bool canLoad(const KURL&, const Document*);
+        static bool canLoad(const CachedResource&, const Document*);
+
+        static bool shouldHideReferrer(const KURL& url, const String& referrer);
 
         Frame* createWindow(const FrameLoadRequest&, const WindowFeatures&);
 
@@ -390,7 +396,7 @@ namespace WebCore {
         void updateGlobalHistoryForReload(const KURL&);
         bool shouldGoToHistoryItem(HistoryItem*) const;
         bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
-        
+
         void commitProvisionalLoad(PassRefPtr<PageCache>);
 
         void goToItem(HistoryItem*, FrameLoadType);
@@ -405,8 +411,14 @@ namespace WebCore {
         void setCurrentHistoryItem(PassRefPtr<HistoryItem>);
         void setPreviousHistoryItem(PassRefPtr<HistoryItem>);
         void setProvisionalHistoryItem(PassRefPtr<HistoryItem>);
-        
+
         void continueLoadWithData(SharedBuffer*, const String& mimeType, const String& textEncoding, const KURL&); 
+
+        static void registerSchemeAsLocal(const String& scheme);
+        static bool restrictAccessToLocal();
+        static void setRestrictAccessToLocal(bool);
+        static bool shouldTreatURLAsLocal(const String& url);
+
     private:        
         PassRefPtr<HistoryItem> createHistoryItem(bool useOriginal);
         PassRefPtr<HistoryItem> createHistoryItemTree(Frame* targetFrame, bool clipAtTarget);
index 4f998bcfacaa0fba99676b68c0d0077ea65f283f..23d1f67f46b6cc35386a94c1bb180f3e589f0e8c 100644 (file)
@@ -181,9 +181,7 @@ void MainResourceLoader::continueAfterContentPolicy(PolicyAction contentPolicy,
     switch (contentPolicy) {
     case PolicyUse: {
         // Prevent remote web archives from loading because they can claim to be from any domain and thus avoid cross-domain security checks (4120255).
-        bool isRemote = !url.isLocalFile();
-        isRemote = isRemote && !m_substituteData.isValid();
-        bool isRemoteWebArchive = isRemote && equalIgnoringCase("application/x-webarchive", mimeType);
+        bool isRemoteWebArchive = equalIgnoringCase("application/x-webarchive", mimeType) && !m_substituteData.isValid() && !url.isLocalFile();
         if (!frameLoader()->canShowMIMEType(mimeType) || isRemoteWebArchive) {
             frameLoader()->cannotShowMIMEType(r);
             // Check reachedTerminalState since the load may have already been cancelled inside of _handleUnimplementablePolicyWithErrorCode::.
index d1b4431130d7afc0fc7d52daea5617c0526e617a..9930f091cfe1d0f7e6c9fbd22c619b4f8095533a 100644 (file)
@@ -91,13 +91,13 @@ PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, Subresourc
         return 0;
 
     ResourceRequest newRequest = request;
+
+    // If linked-on-or-after check canLoad
+    if (FrameLoader::restrictAccessToLocal()
+    && !FrameLoader::canLoad(request.url(), frame->document()))
+        return 0;
     
-    // Since this is a subresource, we can load any URL (we ignore the return value).
-    // But we still want to know whether we should hide the referrer or not, so we call the canLoadURL method.
-    // FIXME: is that really the rule we want for subresources?
-    bool hideReferrer;
-    fl->canLoad(request.url(), fl->outgoingReferrer(), hideReferrer);
-    if (hideReferrer)
+    if (FrameLoader::shouldHideReferrer(request.url(), fl->outgoingReferrer()))
         newRequest.clearHTTPReferrer();
     else if (!request.httpReferrer())
         newRequest.setHTTPReferrer(fl->outgoingReferrer());
index b4e1765c674a2b79ab697d96df5ffe663fe0852b..b64075541b9c30e775b84bd7ead4c3796ec63108 100644 (file)
@@ -477,7 +477,7 @@ static Image* getImage(Element* element)
         return 0;
     
     RenderImage* image = static_cast<RenderImage*>(renderer);
-    if (image->cachedImage() && !image->cachedImage()->isErrorImage())
+    if (image->cachedImage() && !image->cachedImage()->errorOccurred())
         return image->cachedImage()->image();
     return 0;
 }
index 48c19f8a7597e3ca020bf18f53034f038fc30239..51b9af5e79a6f234d5a740311a6670125f2dc60c 100644 (file)
@@ -645,9 +645,8 @@ static Cursor selectCursor(const MouseEventWithHitTestResults& event, Frame* fra
                 continue;
             if (cimage->image()->isNull())
                 break;
-            if (!cimage->isErrorImage()) {
+            if (!cimage->errorOccurred())
                 return Cursor(cimage->image(), hotSpot);
-}
         }
     }
 
index b56ffaab7eb05aab788ea1b2a6595b4c152f01fc..740e9c709094fd506e6a7503b5b1bcac703852e5 100644 (file)
@@ -792,7 +792,10 @@ DeprecatedString KURL::decode_string(const DeprecatedString& urlString, const Te
 
 bool KURL::isLocalFile() const
 {
-    // FIXME - include feed: here too?
+    // Including feed here might be a bad idea since drag and drop uses this check
+    // and including feed would allow feeds to potentially let someone's blog
+    // read the contents of the clipboard on a drag, even without a drop.
+    // Likewise with using the FrameLoader::shouldTreatURLAsLocal() function.
     return protocol() == "file";
 }
 
index 52094426e2252f61192c4f44a199c0fa95442954..f4eb4d565e3b115184450de23665d0b2ee418ac7 100644 (file)
@@ -197,7 +197,7 @@ Image* HitTestResult::image() const
     RenderObject* renderer = m_innerNonSharedNode->renderer();
     if (renderer && renderer->isImage()) {
         RenderImage* image = static_cast<WebCore::RenderImage*>(renderer);
-        if (image->cachedImage() && !image->cachedImage()->isErrorImage())
+        if (image->cachedImage() && !image->cachedImage()->errorOccurred())
             return image->cachedImage()->image();
     }
 
index 05da6721cf09fe1b79bfb34cb1cce3fe9e6e51b4..6c9009c98cc740cb77639362817b3fbe9b2f1eee 100644 (file)
@@ -70,7 +70,7 @@ void RenderImage::setCachedImage(CachedImage* newImage)
     m_cachedImage = newImage;
     if (m_cachedImage) {
         m_cachedImage->ref(this);
-        if (m_cachedImage->isErrorImage())
+        if (m_cachedImage->errorOccurred())
             imageChanged(m_cachedImage);
     }
 }
@@ -136,14 +136,14 @@ void RenderImage::imageChanged(CachedImage* newImage)
     bool imageSizeChanged = false;
 
     // Set image dimensions, taking into account the size of the alt text.
-    if (newImage->isErrorImage())
+    if (newImage->errorOccurred())
         imageSizeChanged = setImageSizeForAltText(newImage);
     
     bool ensureLayout = false;
 
     // Image dimensions have been changed, see what needs to be done
     if (newImage->imageSize().width() != intrinsicWidth() || newImage->imageSize().height() != intrinsicHeight() || imageSizeChanged) {
-        if (!newImage->isErrorImage()) {
+        if (!newImage->errorOccurred()) {
             setIntrinsicWidth(newImage->imageSize().width());
             setIntrinsicHeight(newImage->imageSize().height());
         }
@@ -226,12 +226,12 @@ void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
     if (isPrinting && !view()->printImages())
         return;
 
-    if (!m_cachedImage || image()->isNull() || isErrorImage()) {
+    if (!m_cachedImage || image()->isNull() || errorOccurred()) {
         if (paintInfo.phase == PaintPhaseSelection)
             return;
 
         if (cWidth > 2 && cHeight > 2) {
-            if (!isErrorImage()) {
+            if (!errorOccurred()) {
                 context->setStrokeStyle(SolidStroke);
                 context->setStrokeColor(Color::lightGray);
                 context->setFillColor(Color::transparent);
@@ -244,7 +244,7 @@ void RenderImage::paint(PaintInfo& paintInfo, int tx, int ty)
             int usableWidth = cWidth;
             int usableHeight = cHeight;
 
-            if (isErrorImage() && !image()->isNull() && (usableWidth >= image()->width()) && (usableHeight >= image()->height())) {
+            if (errorOccurred() && !image()->isNull() && (usableWidth >= image()->width()) && (usableHeight >= image()->height())) {
                 // Center the error image, accounting for border and padding.
                 int centerX = (usableWidth - image()->width()) / 2;
                 if (centerX < 0)
@@ -310,7 +310,7 @@ void RenderImage::layout()
     }
 
     // minimum height
-    m_height = m_cachedImage && m_cachedImage->isErrorImage() ? intrinsicHeight() : 0;
+    m_height = m_cachedImage && m_cachedImage->errorOccurred() ? intrinsicHeight() : 0;
 
     calcWidth();
     calcHeight();
@@ -415,7 +415,7 @@ int RenderImage::calcAspectRatioWidth() const
 {
     if (!intrinsicHeight())
         return 0;
-    if (!m_cachedImage || m_cachedImage->isErrorImage())
+    if (!m_cachedImage || m_cachedImage->errorOccurred())
         return intrinsicWidth(); // Don't bother scaling.
     return RenderReplaced::calcReplacedHeight() * intrinsicWidth() / intrinsicHeight();
 }
@@ -424,7 +424,7 @@ int RenderImage::calcAspectRatioHeight() const
 {
     if (!intrinsicWidth())
         return 0;
-    if (!m_cachedImage || m_cachedImage->isErrorImage())
+    if (!m_cachedImage || m_cachedImage->errorOccurred())
         return intrinsicHeight(); // Don't bother scaling.
     return RenderReplaced::calcReplacedWidth() * intrinsicHeight() / intrinsicWidth();
 }
index eda221ece853bd1ff3e7a633caca884d51add60e..d886cf01f1ade0458ede8ada0af631d927ccc133 100644 (file)
@@ -78,7 +78,7 @@ private:
     bool isWidthSpecified() const;
     bool isHeightSpecified() const;
 
-    bool isErrorImage() const { return m_cachedImage && m_cachedImage->isErrorImage(); }
+    bool errorOccurred() const { return m_cachedImage && m_cachedImage->errorOccurred(); }
 
     // The image we are rendering.
     CachedImage* m_cachedImage;
index 3702535868e5f60670526b797c039746ed8dd905..2ef0d01ed1f4cf34a9b76db12590f6b2e005b778 100644 (file)
@@ -52,7 +52,7 @@ void RenderListItem::setStyle(RenderStyle* newStyle)
     RenderBlock::setStyle(newStyle);
 
     if (style()->listStyleType() != LNONE ||
-        (style()->listStyleImage() && !style()->listStyleImage()->isErrorImage())) {
+        (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) {
         RenderStyle* newStyle = new (renderArena()) RenderStyle;
         newStyle->ref();
         // The marker always inherits from the list item, regardless of where it might end
index 20f613e23b85ebb41fa76a6f6f209726dcc18f0c..7583d7b93ea3c700cb611937fd923b9946625ed2 100644 (file)
@@ -506,7 +506,7 @@ InlineBox* RenderListMarker::createInlineBox(bool, bool isRootLineBox, bool)
 
 bool RenderListMarker::isImage() const
 {
-    return m_image && !m_image->isErrorImage();
+    return m_image && !m_image->errorOccurred();
 }
 
 void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
index 20886112fe112425b3f498276f247ab5c53d4790..21f0cae73f91951aeb451b9aba0f63ebdbb8fa44 100644 (file)
@@ -325,13 +325,12 @@ void XMLHttpRequest::callReadyStateChangeListener()
 
 bool XMLHttpRequest::urlMatchesDocumentDomain(const KURL& url) const
 {
-    KURL documentURL(m_doc->URL());
-
     // a local file can load anything
-    if (documentURL.protocol().lower() == "file" || documentURL.protocol().lower() == "applewebdata")
+    if (m_doc->isAllowedToLoadLocalResources())
         return true;
 
     // but a remote document can only load from the same port on the server
+    KURL documentURL = m_doc->URL();
     if (documentURL.protocol().lower() == url.protocol().lower()
             && documentURL.host().lower() == url.host().lower()
             && documentURL.port() == url.port())
index 510c190c9c94502ac87a63905b8b332c36864cd2..645e5cb75bc96fe86a8e60d980b19da78d332498 100644 (file)
@@ -1,3 +1,27 @@
+2007-03-02  Kevin McCullough  <kmccullough@apple.com>
+
+        Reviewed by Geoff.
+
+        - rdar://problem/4922454
+        - This fixes a security issue by making remote referrers not able to access local
+        resources, unless they register their schemes to be treated as local. The result is
+        that those schemes can access local resources and cannot be accessed by remote
+        referrers.
+        Because this behavior is new a link-on-or-after check is made to determine if the
+        app should use the older, less safe, behavior.
+
+        * Misc/WebKitVersionChecks.h: added linked-on-or-after check
+        * Misc/WebNSAttributedStringExtras.mm: Moved functionalit into the base class.
+        (fileWrapperForElement):
+        * Plugins/WebNetscapePluginStream.mm: uses new canLoad functions
+        * Plugins/WebPluginContainerCheck.mm: uses new canLoad functions
+        (-[WebPluginContainerCheck _isForbiddenFileLoad]):
+        * WebView/WebView.mm: make linked-on-or-after check and cache value, exposes SPI
+        for registering a scheme as local. 
+        (-[WebView _commonInitializationWithFrameName:groupName:]):
+        (+[WebView registerSchemeAsLocal:]):
+        * WebView/WebViewPrivate.h: exposes SPI for registering a scheme as local.
+
 2007-03-01  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by harrison
index d5626e2c47da96946fd8dee10901ddee2b3f3908..663de22520f309643d9fd9e8d8021dead96c2d83 100644 (file)
@@ -35,6 +35,7 @@
 // FIXME 4927747: We should make the framework version numbers match the info.plist version numbers
 #define WEBKIT_FIRST_VERSION_WITH_3_0_CONTEXT_MENU_TAGS 0x00020000
 #define WEBKIT_FIRST_VERSION_WITHOUT_ACROBAT_QUIRK 0x00020000
+#define WEBKIT_FIRST_VERSION_WITH_LOCAL_RESOURCE_SECURITY_RESTRICTION 0x00020000
 #define WEBKIT_FIRST_VERSION_WITHOUT_APERTURE_QUIRK 0x00020000
 
 #ifdef __cplusplus
index 303cd45847c5f142b4de8e220804fcf08c4670aa..bc58f85d47271c725831d654f36a95d40dced2ba 100644 (file)
@@ -98,7 +98,7 @@ static NSFileWrapper *fileWrapperForElement(Element* e)
     }
     if (!wrapper) {
         RenderImage* renderer = static_cast<RenderImage*>(e->renderer());
-        if (renderer->cachedImage() && !renderer->cachedImage()->isErrorImage()) {
+        if (renderer->cachedImage() && !renderer->cachedImage()->errorOccurred()) {
             wrapper = [[NSFileWrapper alloc] initRegularFileWithContents:(NSData *)(renderer->cachedImage()->image()->getTIFFRepresentation())];
             [wrapper setPreferredFilename:@"image.tiff"];
             [wrapper autorelease];
index e1d166fd1ce266828bc570c7783f56c2111da8fd..ed812fdb47b0ade8097dda66a8fa35ff1d819231 100644 (file)
@@ -63,8 +63,7 @@ using namespace WebCore;
 {   
     WebBaseNetscapePluginView *view = (WebBaseNetscapePluginView *)thePlugin->ndata;
 
-    bool hideReferrer;
-    if (!core([view webFrame])->loader()->canLoad([theRequest URL], core([view webFrame])->loader()->outgoingReferrer(), hideReferrer))
+    if (!core([view webFrame])->loader()->canLoad([theRequest URL], core([view webFrame])->document()))
         return nil;
 
     if ([self initWithRequestURL:[theRequest URL]
@@ -78,7 +77,7 @@ using namespace WebCore;
     isTerminated = YES;
     
     request = [theRequest mutableCopy];
-    if (hideReferrer)
+    if (core([view webFrame])->loader()->shouldHideReferrer([theRequest URL], core([view webFrame])->loader()->outgoingReferrer()))
         [(NSMutableURLRequest *)request _web_setHTTPReferrer:nil];
 
     _loader = NetscapePlugInStreamLoader::create(core([view webFrame]), self).releaseRef();
index b6acbef7e17847edebeaab85571e5f29f8aad358..e784224a3225514956e599bcc86b3646ba355c7f 100644 (file)
@@ -95,10 +95,9 @@ using namespace WebCore;
 
 - (BOOL)_isForbiddenFileLoad
 {
-   bool ignore;
    WebFrameBridge *bridge = [_controller bridge];
    ASSERT(bridge);
-   if (![bridge _frame]->loader()->canLoad([_request URL], [_controller URLPolicyCheckReferrer], ignore)) {
+   if (![bridge _frame]->loader()->canLoad([_request URL], [bridge _frame]->document())) {
        [self _continueWithPolicy:PolicyIgnore];
        return YES;
    }
index 598ad02c33348292e4e46eca058f237f1b5309ba..f68f6fceef071c3ac690650a5e1dd22c5a4c5d32 100644 (file)
@@ -1650,6 +1650,9 @@ NSMutableDictionary *countInvocations;
     // Register to receive notifications whenever preference values change.
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_preferencesChangedNotification:)
                                                  name:WebPreferencesChangedNotification object:[self preferences]];
+
+    if (WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOCAL_RESOURCE_SECURITY_RESTRICTION))
+        FrameLoader::setRestrictAccessToLocal(true);
 }
 
 - (id)initWithFrame:(NSRect)f
@@ -2816,6 +2819,11 @@ static WebFrame *incrementFrame(WebFrame *curr, BOOL forward, BOOL wrapFlag)
     _private->allowsUndo = flag;
 }
 
++ (void)registerSchemeAsLocal:(NSString *)protocol
+{
+    FrameLoader::registerSchemeAsLocal(protocol);
+}
+
 @end
 
 @implementation WebView (WebViewPrintingPrivate)
index a0eb4946e9fef241d0b21ba8dd73fb1e54a6bcba..371265fb50cc54a0df09d0d620173a5809a9629d 100644 (file)
@@ -171,6 +171,8 @@ typedef enum {
 - (BOOL)allowsUndo;
 - (void)setAllowsUndo:(BOOL)flag;
 
++ (void)registerSchemeAsLocal:(NSString *)protocol;
+
 @end
 
 @interface WebView (WebPrivate)