Make document.documentURI readonly from JavaScript
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jun 2012 18:02:56 +0000 (18:02 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jun 2012 18:02:56 +0000 (18:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=65187

Patch by Mike West <mkwst@chromium.org> on 2012-06-12
Reviewed by Alexey Proskuryakov.

Source/WebCore:

The DOM4 working draft marks the documentURI attribute as read only
(http://www.w3.org/TR/dom/#document). Firefox has shipped with this
behavior since https://hg.mozilla.org/mozilla-central/rev/3bc751906409
landed in October 2011, IE9 doesn't support the property, and
Opera throws a NO_MODIFICATION_ALLOWED_ERR. This patch changes WebKit
to silently fail (matching Firefox's behavior) by setting the property
to readonly in the IDL.

Document::setDocumentURI and the m_documentURI property are retained
for compatibility with ObjC clients, and the readonly attribute is
ifdeffed out for ObjC.

This patch adds a single test to verify the behavior, and removes a
variety of tests that depended on the writable behavior. In particular,
potential security issues involving the document.baseURL property are
avoided completely as long as this property can't be changed.

Test: fast/dom/documenturi-readonly.html

* dom/Document.cpp:
(WebCore::Document::setDocumentURI):
    Adds a comment explaining that the fallback is necessary only to
    support ObjC, not for JS calls.
* dom/Document.cpp:
(WebCore::Document::updateBaseURL):
    Ditto.
(Document):
* dom/Document.idl:
    Add readonly to the attribute and drop null value when not in
    LANGUAGE_OBJECTIVE_C.

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/mac/SetDocumentURI.html: Added.
* TestWebKitAPI/Tests/mac/SetDocumentURI.mm: Added.
(-[SetDocumentURITest webView:didFinishLoadForFrame:]):
(TestWebKitAPI):
(TestWebKitAPI::TEST):

LayoutTests:

* dom/xhtml/level3/core/documentsetdocumenturi01-expected.txt: Removed.
* dom/xhtml/level3/core/documentsetdocumenturi01.xhtml-disabled: Renamed from LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi01.xhtml.
* dom/xhtml/level3/core/documentsetdocumenturi02-expected.txt: Removed.
* dom/xhtml/level3/core/documentsetdocumenturi02.xhtml-disabled: Renamed from LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi02.xhtml.
    Disabling these two tests, because they write out documentURI which is a `file:` URL dependent on a local path.
* dom/xhtml/level3/core/documentsetdocumenturi03-expected.txt:
* dom/xhtml/level3/core/nodegetbaseuri02-expected.txt:
    Updating these two tests to match the new, read-only behavior.
* fast/dom/documenturi-affects-relative-paths-expected.txt: Removed.
* fast/dom/documenturi-affects-relative-paths.html: Removed.
* fast/dom/documenturi-assigned-junk-implies-baseuri-null-expected.txt: Removed.
* fast/dom/documenturi-assigned-junk-implies-baseuri-null.html: Removed.
* fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve-expected.txt: Removed.
* fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html: Removed.
* fast/dom/documenturi-can-hold-arbitrary-string-expected.txt: Removed.
* fast/dom/documenturi-can-hold-arbitrary-string.html: Removed.
    Removing now-irrelevant tests.
* fast/dom/documenturi-readonly-expected.txt: Added.
* fast/dom/documenturi-readonly.html: Added.
    Adding a test to verify that document.documentURI is read-only.
* http/tests/security/xss-DENIED-document-baseURI-javascript-expected.txt: Removed.
* http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces-expected.txt: Removed.
* http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces.html: Removed.
* http/tests/security/xss-DENIED-document-baseURI-javascript.html: Removed.
* platform/chromium/dom/xhtml/level3/core/nodegetbaseuri02-expected.txt: Added
    Platform-specific result for Chromium, which doesn't set the `line` property on exceptions.
* storage/domstorage/events/documentURI-expected.txt: Removed.
* storage/domstorage/events/documentURI.html: Removed.
* storage/domstorage/events/script-tests/documentURI.js: Removed.
    Removing now-irrelevant tests.

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

33 files changed:
LayoutTests/ChangeLog
LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi01-expected.txt [deleted file]
LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi01.xhtml-disabled [moved from LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi01.xhtml with 100% similarity]
LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi02-expected.txt [deleted file]
LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi02.xhtml-disabled [moved from LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi02.xhtml with 100% similarity]
LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi03-expected.txt
LayoutTests/dom/xhtml/level3/core/nodegetbaseuri02-expected.txt
LayoutTests/fast/dom/documenturi-affects-relative-paths-expected.txt [deleted file]
LayoutTests/fast/dom/documenturi-affects-relative-paths.html [deleted file]
LayoutTests/fast/dom/documenturi-assigned-junk-implies-baseuri-null-expected.txt [deleted file]
LayoutTests/fast/dom/documenturi-assigned-junk-implies-baseuri-null.html [deleted file]
LayoutTests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve-expected.txt [deleted file]
LayoutTests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html [deleted file]
LayoutTests/fast/dom/documenturi-can-hold-arbitrary-string-expected.txt [deleted file]
LayoutTests/fast/dom/documenturi-can-hold-arbitrary-string.html [deleted file]
LayoutTests/fast/dom/documenturi-readonly-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/documenturi-readonly.html [new file with mode: 0644]
LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-expected.txt [deleted file]
LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces-expected.txt [deleted file]
LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces.html [deleted file]
LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript.html [deleted file]
LayoutTests/platform/chromium/dom/xhtml/level3/core/nodegetbaseuri02-expected.txt [new file with mode: 0644]
LayoutTests/storage/domstorage/events/documentURI-expected.txt [deleted file]
LayoutTests/storage/domstorage/events/documentURI.html [deleted file]
LayoutTests/storage/domstorage/events/script-tests/documentURI.js [deleted file]
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Document.idl
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.html [new file with mode: 0644]
Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.mm [new file with mode: 0644]

index e1f2e3c..f11aed5 100644 (file)
@@ -1,3 +1,41 @@
+2012-06-12  Mike West  <mkwst@chromium.org>
+
+        Make document.documentURI readonly from JavaScript
+        https://bugs.webkit.org/show_bug.cgi?id=65187
+
+        Reviewed by Alexey Proskuryakov.
+
+        * dom/xhtml/level3/core/documentsetdocumenturi01-expected.txt: Removed.
+        * dom/xhtml/level3/core/documentsetdocumenturi01.xhtml-disabled: Renamed from LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi01.xhtml.
+        * dom/xhtml/level3/core/documentsetdocumenturi02-expected.txt: Removed.
+        * dom/xhtml/level3/core/documentsetdocumenturi02.xhtml-disabled: Renamed from LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi02.xhtml.
+            Disabling these two tests, because they write out documentURI which is a `file:` URL dependent on a local path.
+        * dom/xhtml/level3/core/documentsetdocumenturi03-expected.txt:
+        * dom/xhtml/level3/core/nodegetbaseuri02-expected.txt:
+            Updating these two tests to match the new, read-only behavior.
+        * fast/dom/documenturi-affects-relative-paths-expected.txt: Removed.
+        * fast/dom/documenturi-affects-relative-paths.html: Removed.
+        * fast/dom/documenturi-assigned-junk-implies-baseuri-null-expected.txt: Removed.
+        * fast/dom/documenturi-assigned-junk-implies-baseuri-null.html: Removed.
+        * fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve-expected.txt: Removed.
+        * fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html: Removed.
+        * fast/dom/documenturi-can-hold-arbitrary-string-expected.txt: Removed.
+        * fast/dom/documenturi-can-hold-arbitrary-string.html: Removed.
+            Removing now-irrelevant tests.
+        * fast/dom/documenturi-readonly-expected.txt: Added.
+        * fast/dom/documenturi-readonly.html: Added.
+            Adding a test to verify that document.documentURI is read-only.
+        * http/tests/security/xss-DENIED-document-baseURI-javascript-expected.txt: Removed.
+        * http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces-expected.txt: Removed.
+        * http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces.html: Removed.
+        * http/tests/security/xss-DENIED-document-baseURI-javascript.html: Removed.
+        * platform/chromium/dom/xhtml/level3/core/nodegetbaseuri02-expected.txt: Added
+            Platform-specific result for Chromium, which doesn't set the `line` property on exceptions.
+        * storage/domstorage/events/documentURI-expected.txt: Removed.
+        * storage/domstorage/events/documentURI.html: Removed.
+        * storage/domstorage/events/script-tests/documentURI.js: Removed.
+            Removing now-irrelevant tests.
+
 2012-06-12  Christophe Dumez  <christophe.dumez@intel.com>
 
         [EFL] enable LEGACY_WEBKIT_BLOB_BUILDER flag
diff --git a/LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi01-expected.txt b/LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi01-expected.txt
deleted file mode 100644 (file)
index 5052bd5..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Test   http://www.w3.org/2001/DOM-Test-Suite/level3/core/documentsetdocumenturi01
-Status Success
diff --git a/LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi02-expected.txt b/LayoutTests/dom/xhtml/level3/core/documentsetdocumenturi02-expected.txt
deleted file mode 100644 (file)
index bce6ca0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Test   http://www.w3.org/2001/DOM-Test-Suite/level3/core/documentsetdocumenturi02
-Status Success
index 885259f..8a3e30b 100644 (file)
@@ -1,2 +1,3 @@
 Test   http://www.w3.org/2001/DOM-Test-Suite/level3/core/documentsetdocumenturi03
-Status Success
+Status failure
+Message        documentsetdocumenturi03: assertEquals failed, actual null, expected somestring.
index a1b59b7..fd99acf 100644 (file)
@@ -1,2 +1,3 @@
 Test   http://www.w3.org/2001/DOM-Test-Suite/level3/core/nodegetbaseuri02
-Status Success
+Status error
+Message        Line 120: TypeError
diff --git a/LayoutTests/fast/dom/documenturi-affects-relative-paths-expected.txt b/LayoutTests/fast/dom/documenturi-affects-relative-paths-expected.txt
deleted file mode 100644 (file)
index c0b3977..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Hyperlink to foo.html
-a.href = http://pass.example.com/foo.html
-
-
diff --git a/LayoutTests/fast/dom/documenturi-affects-relative-paths.html b/LayoutTests/fast/dom/documenturi-affects-relative-paths.html
deleted file mode 100644 (file)
index bbe5822..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<html>
-<head>
-<body>
-<script>
-if (window.layoutTestController)
-  layoutTestController.dumpAsText();
-
-document.documentURI = 'http://pass.example.com/';
-</script>
-<a href="foo.html">Hyperlink to foo.html</a>
-<pre>
-<script>
-var a = document.getElementsByTagName('a')[0];
-document.writeln('a.href = ' + a.href);
-</script>
-</pre>
-</body>
-</html>
diff --git a/LayoutTests/fast/dom/documenturi-assigned-junk-implies-baseuri-null-expected.txt b/LayoutTests/fast/dom/documenturi-assigned-junk-implies-baseuri-null-expected.txt
deleted file mode 100644 (file)
index f019399..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Now that document.documentURI is junk, document.baseURI should be null
-document.baseURI = null
-
-
diff --git a/LayoutTests/fast/dom/documenturi-assigned-junk-implies-baseuri-null.html b/LayoutTests/fast/dom/documenturi-assigned-junk-implies-baseuri-null.html
deleted file mode 100644 (file)
index 93c4ef7..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<html>
-<body>
-<pre>
-<script>
-if (window.layoutTestController)
-  layoutTestController.dumpAsText();
-
-document.documentURI = 'junk';
-document.writeln('Now that document.documentURI is junk, document.baseURI should be null');
-document.writeln('document.baseURI = ' + document.baseURI);
-</script>
-</pre>
-</body>
-</html>
diff --git a/LayoutTests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve-expected.txt b/LayoutTests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve-expected.txt
deleted file mode 100644 (file)
index 6bcccf6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Hyperlink to foo.html
-a.href = foo.html
-
-
diff --git a/LayoutTests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html b/LayoutTests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html
deleted file mode 100644 (file)
index def4691..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<html>
-<head>
-<body>
-<script>
-if (window.layoutTestController)
-  layoutTestController.dumpAsText();
-
-document.documentURI = 'junk';
-</script>
-<a href="foo.html">Hyperlink to foo.html</a>
-<pre>
-<script>
-var a = document.getElementsByTagName('a')[0];
-document.writeln('a.href = ' + a.href);
-</script>
-</pre>
-</body>
-</html>
diff --git a/LayoutTests/fast/dom/documenturi-can-hold-arbitrary-string-expected.txt b/LayoutTests/fast/dom/documenturi-can-hold-arbitrary-string-expected.txt
deleted file mode 100644 (file)
index 1bf848c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-normalizeURL(document.documentURI) = LayoutTests/fast/dom/documenturi-can-hold-arbitrary-string.html
-Assigning to documentURI
-document.documentURI = PASS: documentURI can hold an arbitrary string.
-
-
diff --git a/LayoutTests/fast/dom/documenturi-can-hold-arbitrary-string.html b/LayoutTests/fast/dom/documenturi-can-hold-arbitrary-string.html
deleted file mode 100644 (file)
index 8872c30..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<html>
-<body>
-<pre>
-<script>
-function normalizeURL(url) {
-  return url.substring(url.lastIndexOf('LayoutTests'));
-}
-
-if (window.layoutTestController)
-  layoutTestController.dumpAsText();
-
-document.writeln('normalizeURL(document.documentURI) = ' + normalizeURL(document.documentURI));
-document.writeln('Assigning to documentURI');
-document.documentURI = 'PASS: documentURI can hold an arbitrary string.';
-document.writeln('document.documentURI = ' + document.documentURI);
-</script>
-</pre>
-</body>
-</html>
diff --git a/LayoutTests/fast/dom/documenturi-readonly-expected.txt b/LayoutTests/fast/dom/documenturi-readonly-expected.txt
new file mode 100644 (file)
index 0000000..6823429
--- /dev/null
@@ -0,0 +1,2 @@
+ALERT: PASS: document.documentURI is read only.
+This test ensures that document.documentURI is a readonly attribute. It passes if a "PASS" alert is displayed.
diff --git a/LayoutTests/fast/dom/documenturi-readonly.html b/LayoutTests/fast/dom/documenturi-readonly.html
new file mode 100644 (file)
index 0000000..c14c475
--- /dev/null
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+    <script>
+        if (window.layoutTestController)
+            layoutTestController.dumpAsText();
+
+        var oldValue = document.documentURI;
+        document.documentURI = 'http://fail.example.com/';
+        if (document.documentURI === 'http://fail.example.com/')
+            alert("FAIL: document.documentURI should be read only.");
+        else if (document.documentURI === oldValue)
+            alert("PASS: document.documentURI is read only.");
+        else
+            alert("FAIL: document.documentURI is weird: " + document.documentURI);
+    </script>
+</head>
+<body>
+    <p>
+        This test ensures that document.documentURI is a readonly attribute.
+        It passes if a "PASS" alert is displayed.
+    </p>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-expected.txt b/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-expected.txt
deleted file mode 100644 (file)
index 5f98be9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-CONSOLE MESSAGE: Unsafe JavaScript attempt to access frame with URL http://localhost:8080/security/resources/innocent-victim.html from frame with URL http://127.0.0.1:8000/security/xss-DENIED-document-baseURI-javascript.html. Domains, protocols and ports must match.
-
-This test passes if there is no alert dialog  
diff --git a/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces-expected.txt b/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces-expected.txt
deleted file mode 100644 (file)
index 4e8f6d4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-CONSOLE MESSAGE: Unsafe JavaScript attempt to access frame with URL http://localhost:8080/security/resources/innocent-victim.html from frame with URL http://127.0.0.1:8000/security/xss-DENIED-document-baseURI-javascript-with-spaces.html. Domains, protocols and ports must match.
-
-This test passes if there is no alert dialog  
diff --git a/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces.html b/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript-with-spaces.html
deleted file mode 100644 (file)
index a3eda78..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<html>
-<head>
-<script>
-if (window.layoutTestController) {
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
-}
-
-
-window.onload = function()
-{
-    document.documentURI = "\x20\x09\x0a\x0djavascript://hostname.com/%0D%0Aalert('FAIL')";
-
-    frame = document.body.appendChild(document.createElement("iframe"));
-    frame.src = "http://localhost:8080/security/resources/innocent-victim.html";
-    
-    frame.onload = function()
-    {
-        frame.contentWindow.location = "";
-        setTimeout(finishTest, 0);
-    }
-}
-
-function finishTest()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-</script>
-</head>
-<body>
-This test passes if there is no alert dialog
-</body>
-</html>
diff --git a/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript.html b/LayoutTests/http/tests/security/xss-DENIED-document-baseURI-javascript.html
deleted file mode 100644 (file)
index c03ac83..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<html>
-<head>
-<script>
-if (window.layoutTestController) {
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
-}
-
-
-window.onload = function()
-{
-    document.documentURI = "javascript://hostname.com/%0D%0Aalert('FAIL')";
-
-    frame = document.body.appendChild(document.createElement("iframe"));
-    frame.src = "http://localhost:8080/security/resources/innocent-victim.html";
-    
-    frame.onload = function()
-    {
-        frame.contentWindow.location = "";
-        setTimeout(finishTest, 0);
-    }
-}
-
-function finishTest()
-{
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-</script>
-</head>
-<body>
-This test passes if there is no alert dialog
-</body>
-</html>
diff --git a/LayoutTests/platform/chromium/dom/xhtml/level3/core/nodegetbaseuri02-expected.txt b/LayoutTests/platform/chromium/dom/xhtml/level3/core/nodegetbaseuri02-expected.txt
new file mode 100644 (file)
index 0000000..65f196b
--- /dev/null
@@ -0,0 +1,3 @@
+Test   http://www.w3.org/2001/DOM-Test-Suite/level3/core/nodegetbaseuri02
+Status error
+Message        Line undefined: TypeError
diff --git a/LayoutTests/storage/domstorage/events/documentURI-expected.txt b/LayoutTests/storage/domstorage/events/documentURI-expected.txt
deleted file mode 100644 (file)
index d53d4dc..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-Test that changing documentURI has no effects on the url passed into storage events.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-Testing sessionStorage
-storage.clear()
-PASS storage.length is 0
-Reset storage event list
-storageEventList = new Array()
-storage.foo = '123'
-PASS storageEventList.length is 1
-Saving url
-document.documentURI = 'abc'
-PASS document.documentURI is "abc"
-storage.foo = 'xyz'
-PASS storageEventList.length is 2
-PASS true is true
-
-
-Testing localStorage
-storage.clear()
-PASS storage.length is 0
-Reset storage event list
-storageEventList = new Array()
-storage.foo = '123'
-PASS storageEventList.length is 1
-Saving url
-document.documentURI = 'abc'
-PASS document.documentURI is "abc"
-storage.foo = 'xyz'
-PASS storageEventList.length is 2
-PASS true is true
-
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
diff --git a/LayoutTests/storage/domstorage/events/documentURI.html b/LayoutTests/storage/domstorage/events/documentURI.html
deleted file mode 100644 (file)
index 160ad2e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-<head>
-<script src="../../../fast/js/resources/js-test-pre.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<script src="resources/eventTestHarness.js"></script>
-<script src="script-tests/documentURI.js"></script>
-</body>
-</html>
diff --git a/LayoutTests/storage/domstorage/events/script-tests/documentURI.js b/LayoutTests/storage/domstorage/events/script-tests/documentURI.js
deleted file mode 100644 (file)
index 9a81033..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-description("Test that changing documentURI has no effects on the url passed into storage events.");
-
-function test(storageString, callback)
-{
-    window.completionCallback = callback;
-    window.storage = eval(storageString);
-    if (!storage) {
-        testFailed(storageString + " DOES NOT exist");
-        return;
-    }
-
-    debug("Testing " + storageString);
-
-    storageEventList = new Array();
-    evalAndLog("storage.clear()");
-    shouldBe("storage.length", "0");
-
-    runAfterNStorageEvents(step1, 0);
-}
-
-function step1()
-{
-    debug("Reset storage event list");
-    evalAndLog("storageEventList = new Array()");
-    evalAndLog("storage.foo = '123'");
-
-    runAfterNStorageEvents(step2, 1);
-}
-
-function step2()
-{
-    shouldBe("storageEventList.length", "1");
-    debug("Saving url");
-    window.lastURL = storageEventList[0].url;
-
-    evalAndLog("document.documentURI = 'abc'");
-    shouldBeEqualToString("document.documentURI", "abc");
-    evalAndLog("storage.foo = 'xyz'");
-
-    runAfterNStorageEvents(step3, 2);
-}
-
-function step3()
-{
-    shouldBe("storageEventList.length", "2");
-    shouldBeTrue(String(window.lastURL == storageEventList[1].url));
-
-    completionCallback();
-}
-
-testStorages(test);
-
-var successfullyParsed = true;
index 3ed059b..b923e34 100644 (file)
@@ -1,3 +1,41 @@
+2012-06-12  Mike West  <mkwst@chromium.org>
+
+        Make document.documentURI readonly from JavaScript
+        https://bugs.webkit.org/show_bug.cgi?id=65187
+
+        Reviewed by Alexey Proskuryakov.
+
+        The DOM4 working draft marks the documentURI attribute as read only
+        (http://www.w3.org/TR/dom/#document). Firefox has shipped with this
+        behavior since https://hg.mozilla.org/mozilla-central/rev/3bc751906409
+        landed in October 2011, IE9 doesn't support the property, and
+        Opera throws a NO_MODIFICATION_ALLOWED_ERR. This patch changes WebKit
+        to silently fail (matching Firefox's behavior) by setting the property
+        to readonly in the IDL.
+
+        Document::setDocumentURI and the m_documentURI property are retained
+        for compatibility with ObjC clients, and the readonly attribute is
+        ifdeffed out for ObjC.
+
+        This patch adds a single test to verify the behavior, and removes a
+        variety of tests that depended on the writable behavior. In particular,
+        potential security issues involving the document.baseURL property are
+        avoided completely as long as this property can't be changed.
+
+        Test: fast/dom/documenturi-readonly.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::setDocumentURI):
+            Adds a comment explaining that the fallback is necessary only to
+            support ObjC, not for JS calls.
+        * dom/Document.cpp:
+        (WebCore::Document::updateBaseURL):
+            Ditto.
+        (Document):
+        * dom/Document.idl:
+            Add readonly to the attribute and drop null value when not in
+            LANGUAGE_OBJECTIVE_C.
+
 2012-06-12  Silvia Pfeiffer  <silviapf@chromium.org>
 
         Support !ENABLE(VIDEO) builds with horizontally layed out video controls.
index 7ac5307..3781368 100644 (file)
@@ -1316,6 +1316,7 @@ void Document::setXMLStandalone(bool standalone, ExceptionCode& ec)
 
 void Document::setDocumentURI(const String& uri)
 {
+    // This property is read-only from JavaScript, but writable from Objective-C.
     m_documentURI = uri;
     updateBaseURL();
 }
@@ -2688,8 +2689,9 @@ void Document::updateBaseURL()
     else if (!m_baseURLOverride.isEmpty())
         m_baseURL = m_baseURLOverride;
     else {
-        // The documentURI attribute is an arbitrary string. DOM 3 Core does not specify how it should be resolved,
-        // so we use a null base URL.
+        // The documentURI attribute is read-only from JavaScript, but writable from Objective C, so we need to retain
+        // this fallback behavior. We use a null base URL, since the documentURI attribute is an arbitrary string
+        // and DOM 3 Core does not specify how it should be resolved.
         m_baseURL = KURL(KURL(), documentURI());
     }
     selectorQueryCache()->invalidate();
index c3ebb46..04c5c46 100644 (file)
@@ -1232,6 +1232,8 @@ private:
     // string by content.  Document.documentURI affects m_baseURL unless the
     // document contains a <base> element, in which case the <base> element
     // takes precedence.
+    //
+    // This property is read-only from JavaScript, but writable from Objective C.
     String m_documentURI;
 
     String m_baseTarget;
index 3297c81..f38e9dd 100644 (file)
@@ -75,7 +75,15 @@ module core {
         Node               adoptNode(in [Optional=DefaultIsUndefined] Node source)
             raises (DOMException);
 
+#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
+        // document.documentURI was writable in DOM3 Core, but is read-only in DOM4
+        // (see http://www.w3.org/TR/2011/WD-dom-20110915/#document). We need to keep
+        // the writable version around for Objective C clients, but are moving to
+        // read-only for other clients.
                  attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString documentURI;
+#else
+        readonly attribute [TreatReturnedNullStringAs=Null] DOMString documentURI;
+#endif
 
         // DOM Level 2 Events (DocumentEvents interface)
 
index bbdb585..323dc8d 100644 (file)
@@ -1,3 +1,17 @@
+2012-06-12  Mike West  <mkwst@chromium.org>
+
+        Make document.documentURI readonly from JavaScript
+        https://bugs.webkit.org/show_bug.cgi?id=65187
+
+        Reviewed by Alexey Proskuryakov.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/mac/SetDocumentURI.html: Added.
+        * TestWebKitAPI/Tests/mac/SetDocumentURI.mm: Added.
+        (-[SetDocumentURITest webView:didFinishLoadForFrame:]):
+        (TestWebKitAPI):
+        (TestWebKitAPI::TEST):
+
 2012-06-12  Christophe Dumez  <christophe.dumez@intel.com>
 
         [EFL] enable LEGACY_WEBKIT_BLOB_BUILDER flag
index c519c02..628a595 100644 (file)
@@ -50,6 +50,8 @@
                51FCF7A11534B2A000104491 /* ShouldGoToBackForwardListItem_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51FCF7971534AC6D00104491 /* ShouldGoToBackForwardListItem_Bundle.cpp */; };
                520BCF4C141EB09E00937EA8 /* WebArchive_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 520BCF4A141EB09E00937EA8 /* WebArchive_Bundle.cpp */; };
                520BCF4D141EB09E00937EA8 /* WebArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 520BCF4B141EB09E00937EA8 /* WebArchive.cpp */; };
+               52B8CF9615868CF000281053 /* SetDocumentURI.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52B8CF9515868CF000281053 /* SetDocumentURI.mm */; };
+               52B8CF9815868D9100281053 /* SetDocumentURI.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 52B8CF9415868CF000281053 /* SetDocumentURI.html */; };
                52CB47411448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52CB47401448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp */; };
                52E5CE4614D21E9D003B2BD8 /* ParentFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E5CE4514D21E9D003B2BD8 /* ParentFrame.cpp */; };
                52E5CE4914D21EAB003B2BD8 /* ParentFrame_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */; };
                        dstPath = TestWebKitAPI.resources;
                        dstSubfolderSpec = 7;
                        files = (
+                               52B8CF9815868D9100281053 /* SetDocumentURI.html in Copy Resources */,
                                B55F11BE15191A0600915916 /* Ahem.ttf in Copy Resources */,
                                B55F11B71517D03300915916 /* attributedStringCustomFont.html in Copy Resources */,
                                76E182DF154767E600F1FADD /* auto-submitting-form.html in Copy Resources */,
                51FCF7981534AC6D00104491 /* ShouldGoToBackForwardListItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShouldGoToBackForwardListItem.cpp; sourceTree = "<group>"; };
                520BCF4A141EB09E00937EA8 /* WebArchive_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebArchive_Bundle.cpp; sourceTree = "<group>"; };
                520BCF4B141EB09E00937EA8 /* WebArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebArchive.cpp; sourceTree = "<group>"; };
+               52B8CF9415868CF000281053 /* SetDocumentURI.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = SetDocumentURI.html; sourceTree = "<group>"; };
+               52B8CF9515868CF000281053 /* SetDocumentURI.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SetDocumentURI.mm; sourceTree = "<group>"; };
                52CB47401448FB9300873995 /* LoadAlternateHTMLStringWithNonDirectoryURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadAlternateHTMLStringWithNonDirectoryURL.cpp; sourceTree = "<group>"; };
                52E5CE4514D21E9D003B2BD8 /* ParentFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame.cpp; sourceTree = "<group>"; };
                52E5CE4814D21EAB003B2BD8 /* ParentFrame_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentFrame_Bundle.cpp; sourceTree = "<group>"; };
                                E1220D9F155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm */,
                                517E7DFB15110EA600D0B008 /* MemoryCachePruneWithinResourceLoadDelegate.mm */,
                                3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */,
+                               52B8CF9515868CF000281053 /* SetDocumentURI.mm */,
                                C540F775152E4DA000A40C8C /* SimplifyMarkup.mm */,
                                3799AD3914120A43005EB0C6 /* StringByEvaluatingJavaScriptFromString.mm */,
                                37A6895D148A9B50005100FA /* SubresourceErrorCrash.mm */,
                C07E6CB013FD737C0038B22B /* Resources */ = {
                        isa = PBXGroup;
                        children = (
+                               52B8CF9415868CF000281053 /* SetDocumentURI.html */,
                                B55F11B9151916E600915916 /* Ahem.ttf */,
                                B55F11B01517A2C400915916 /* attributedStringCustomFont.html */,
                                379028B814FABE49007E6B43 /* acceptsFirstMouse.html */,
                                E1220DA0155B25480013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.mm in Sources */,
                                F6F49C6915545C8E0007F39D /* DOMWindowExtensionNoCache.cpp in Sources */,
                                51E93017156B13E1004C99DF /* WKPageGetScaleFactorNotZero.cpp in Sources */,
+                               52B8CF9615868CF000281053 /* SetDocumentURI.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.html b/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.html
new file mode 100644 (file)
index 0000000..ad3714b
--- /dev/null
@@ -0,0 +1,8 @@
+<!doctype html>
+<html>
+  <body>
+    <p>This is a document to load so that the ObjC [document setDocumentURI:]
+       API can be tested.</p>
+    <a href="relativeURL.html" id="relative"></a>
+  </body>
+</html>
diff --git a/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.mm b/Tools/TestWebKitAPI/Tests/mac/SetDocumentURI.mm
new file mode 100644 (file)
index 0000000..f077ed9
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PlatformUtilities.h"
+#include "PlatformWebView.h"
+#include <wtf/RetainPtr.h>
+
+#import <WebKit/DOM.h>
+#import <WebKit/WebViewPrivate.h>
+
+@interface SetDocumentURITest : NSObject {
+}
+@end
+
+static bool didFinishLoad;
+
+@implementation SetDocumentURITest
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+    didFinishLoad = true;
+}
+@end
+
+namespace TestWebKitAPI {
+
+TEST(WebKit1, SetDocumentURITestFile)
+{
+    RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
+    RetainPtr<SetDocumentURITest> testController(AdoptNS, [SetDocumentURITest new]);
+    webView.get().frameLoadDelegate = testController.get();
+    [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
+    Util::run(&didFinishLoad);
+    didFinishLoad = false;
+    DOMDocument *document = webView.get().mainFrameDocument;
+
+    [document setDocumentURI:@"file:///test"];
+    // documentURI set correctly.
+    EXPECT_WK_STREQ(@"file:///test", [document documentURI]);
+    // baseURI follows along.
+    EXPECT_WK_STREQ(@"file:///test", [document baseURI]);
+}
+
+TEST(WebKit1, SetDocumentURITestURL)
+{
+    RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
+    RetainPtr<SetDocumentURITest> testController(AdoptNS, [SetDocumentURITest new]);
+    webView.get().frameLoadDelegate = testController.get();
+    [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
+    Util::run(&didFinishLoad);
+    didFinishLoad = false;
+    DOMDocument *document = webView.get().mainFrameDocument;
+
+    [document setDocumentURI:@"http://example.com/"];
+    // documentURI set correctly.
+    EXPECT_WK_STREQ(@"http://example.com/", [document documentURI]);
+    // baseURI follows along.
+    EXPECT_WK_STREQ(@"http://example.com/", [document baseURI]);
+    // Relative links too.
+    NSString *result = [webView.get() stringByEvaluatingJavaScriptFromString:@"document.getElementById('relative').href"];
+    EXPECT_WK_STREQ(@"http://example.com/relativeURL.html", result);
+}
+
+TEST(WebKit1, SetDocumentURITestString)
+{
+    RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
+    RetainPtr<SetDocumentURITest> testController(AdoptNS, [SetDocumentURITest new]);
+    webView.get().frameLoadDelegate = testController.get();
+    [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
+    Util::run(&didFinishLoad);
+    didFinishLoad = false;
+    DOMDocument *document = webView.get().mainFrameDocument;
+
+    [document setDocumentURI:@"A non-URL string."];
+    // documentURI accepts random strings.
+    EXPECT_WK_STREQ(@"A non-URL string.", [document documentURI]);
+    // baseURI is empty for non-URL strings.
+    EXPECT_WK_STREQ(@"", [document baseURI]);
+}
+
+TEST(WebKit1, SetDocumentURITestNull)
+{
+    RetainPtr<WebView> webView(AdoptNS, [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
+    RetainPtr<SetDocumentURITest> testController(AdoptNS, [SetDocumentURITest new]);
+    webView.get().frameLoadDelegate = testController.get();
+    [[webView.get() mainFrame] loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"SetDocumentURI" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
+    Util::run(&didFinishLoad);
+    didFinishLoad = false;
+    DOMDocument *document = webView.get().mainFrameDocument;
+
+    [document setDocumentURI:nil];
+    // documenturi is empty.
+    EXPECT_WK_STREQ(@"", [document documentURI]);
+    // baseURI is null as well.
+    EXPECT_WK_STREQ(@"", [document baseURI]);
+}
+
+} // namespace TestWebKitAPI