ScriptElement should use FetchOptions::mode according its crossOrigin attribute
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Sep 2016 06:46:15 +0000 (06:46 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Sep 2016 06:46:15 +0000 (06:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161686

Patch by Youenn Fablet <youenn@apple.com> on 2016-09-12
Reviewed by Darin Adler.

Source/WebCore:

Setting ScriptElement fetch mode according its crossOrigin attribute.
Removing LoadableClassicScriptchecking of CORS since this is now done at ResourceLoader/CachedResource level.

Updating CachedResourceLoader to ensure that a resource that matches an on-going resource load but with different fetch mode/origin,
always gets its loading started if the resource state is not Cached.

Tests: fast/dom/script-crossorigin-loads-fail-origin.html
       http/tests/security/cross-origin-cached-images-parallel.html
       http/tests/security/cross-origin-cached-images.html
       http/tests/security/cross-origin-cached-scripts-parallel.html
       http/tests/security/cross-origin-cached-scripts.html
       http/tests/security/script-crossorigin-loads-correctly-credentials.html
       http/tests/security/script-with-dataurl.html

* dom/LoadableClassicScript.cpp:
(WebCore::LoadableClassicScript::create):
(WebCore::LoadableClassicScript::notifyFinished): Checking CORS failures using the resource state.
(WebCore::LoadableClassicScript::~LoadableClassicScript): Deleted.
(WebCore::LoadableClassicScript::isLoaded): Deleted.
* dom/LoadableClassicScript.h:
* dom/ScriptElement.cpp:
(WebCore::ScriptElement::requestClassicScript):
(WebCore::ScriptElement::requestScriptWithCache): Using CachedResourceRequest::setAsPotentiallyCrossOrigin to set fetch mode according crossOrigin attribute.
* dom/ScriptElement.h:
* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::setBodyDataFrom):
* loader/cache/CachedResourceLoader.cpp:
(WebCore::CachedResourceLoader::updateCachedResourceWithCurrentRequest): Adding support for script resources.
(WebCore::CachedResourceLoader::requestResource): Ensuring that 'updated' resources gets actually loaded.
* loader/cache/CachedScript.cpp:
(WebCore::CachedScript::setBodyDataFrom): Implementing specific data copy from another CachedScript.
* loader/cache/CachedScript.h:

LayoutTests:

Added new tests.
Updated cookie test for robustness as the order of the cookie items when more than one may not be preserved.

Moved one of the blink test to http/tests as it requires HTTP to run properly.
Updated blink test expectation as it is run from file, while it should be run from http.

Copied a similar test to http/tests/local to ensure that script load fails when served from the filesystem , CORS check failing.
The test was previously passing in WebKit as the test file was served from filesystem and was granted universal access.
The CORS checks were done through SecurityOrigin::canRequest which was testing that first.
With the patch, CORS checks are done at a lower level and do not take in to account universal access.
This aligns with Chrome and Firefox behavior.

* http/tests/local/script-crossorigin-loads-fail-origin-expected.txt: Added.
* http/tests/local/script-crossorigin-loads-fail-origin.html: Copied from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials.html.
* http/tests/cookies/resources/third-party-cookie-relaxing-iframe.html: Sorting the cookie to make the test more resistant.
* http/tests/security/cross-origin-cached-images-expected.txt: Added.
* http/tests/security/cross-origin-cached-images-parallel-expected.txt: Added.
* http/tests/security/cross-origin-cached-images-parallel.html: Renamed from LayoutTests/http/tests/security/cross-origin-cached-resource-parallel.html.
* http/tests/security/cross-origin-cached-images.html: Renamed from LayoutTests/http/tests/security/cross-origin-cached-resource.html.
* http/tests/security/cross-origin-cached-resource-parallel-expected.txt: Removed.
* http/tests/security/cross-origin-cached-scripts-expected.txt: Added.
* http/tests/security/cross-origin-cached-scripts-parallel-expected.txt: Added.
* http/tests/security/cross-origin-cached-scripts-parallel.html: Added.
* http/tests/security/cross-origin-cached-scripts.html: Added.
* http/tests/security/resources/cors-script.php: Updated according chromium script to activate CORS credentials header if requested.
* http/tests/security/resources/cross-origin-cached-resource-iframe.html:
* http/tests/security/resources/notify-loaded.js: Added.
* http/tests/security/script-crossorigin-loads-correctly-credentials-expected.txt: Renamed from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials-expected.txt.
* http/tests/security/script-crossorigin-loads-correctly-credentials.html: Renamed from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials.html.
* http/tests/security/script-with-dataurl-expected.txt: Added.
* http/tests/security/script-with-dataurl.html: Added.
* http/tests/security/script-with-failed-cors-check-fails-to-load-expected.txt:

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

30 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/cookies/resources/third-party-cookie-relaxing-iframe.html
LayoutTests/http/tests/local/script-crossorigin-loads-fail-origin-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/local/script-crossorigin-loads-fail-origin.html [new file with mode: 0644]
LayoutTests/http/tests/security/cross-origin-cached-images-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cross-origin-cached-images-parallel-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cross-origin-cached-images-parallel.html [moved from LayoutTests/http/tests/security/cross-origin-cached-resource-parallel.html with 65% similarity]
LayoutTests/http/tests/security/cross-origin-cached-images.html [moved from LayoutTests/http/tests/security/cross-origin-cached-resource.html with 70% similarity]
LayoutTests/http/tests/security/cross-origin-cached-resource-parallel-expected.txt [deleted file]
LayoutTests/http/tests/security/cross-origin-cached-scripts-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel.html [new file with mode: 0644]
LayoutTests/http/tests/security/cross-origin-cached-scripts.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/cors-script.php
LayoutTests/http/tests/security/resources/cross-origin-cached-resource-iframe.html
LayoutTests/http/tests/security/resources/notify-loaded.js [new file with mode: 0644]
LayoutTests/http/tests/security/script-crossorigin-loads-correctly-credentials-expected.txt [moved from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials-expected.txt with 100% similarity]
LayoutTests/http/tests/security/script-crossorigin-loads-correctly-credentials.html [moved from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials.html with 100% similarity]
LayoutTests/http/tests/security/script-with-dataurl-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/script-with-dataurl.html [new file with mode: 0644]
LayoutTests/http/tests/security/script-with-failed-cors-check-fails-to-load-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/dom/LoadableClassicScript.cpp
Source/WebCore/dom/LoadableClassicScript.h
Source/WebCore/dom/ScriptElement.cpp
Source/WebCore/dom/ScriptElement.h
Source/WebCore/loader/cache/CachedImage.cpp
Source/WebCore/loader/cache/CachedResourceLoader.cpp
Source/WebCore/loader/cache/CachedScript.cpp
Source/WebCore/loader/cache/CachedScript.h

index 3e0d412..851480b 100644 (file)
@@ -1,3 +1,43 @@
+2016-09-12  Youenn Fablet  <youenn@apple.com>
+
+        ScriptElement should use FetchOptions::mode according its crossOrigin attribute
+        https://bugs.webkit.org/show_bug.cgi?id=161686
+
+        Reviewed by Darin Adler.
+
+        Added new tests.
+        Updated cookie test for robustness as the order of the cookie items when more than one may not be preserved.
+
+        Moved one of the blink test to http/tests as it requires HTTP to run properly.
+        Updated blink test expectation as it is run from file, while it should be run from http.
+
+        Copied a similar test to http/tests/local to ensure that script load fails when served from the filesystem , CORS check failing.
+        The test was previously passing in WebKit as the test file was served from filesystem and was granted universal access.
+        The CORS checks were done through SecurityOrigin::canRequest which was testing that first.
+        With the patch, CORS checks are done at a lower level and do not take in to account universal access.
+        This aligns with Chrome and Firefox behavior.
+
+        * http/tests/local/script-crossorigin-loads-fail-origin-expected.txt: Added.
+        * http/tests/local/script-crossorigin-loads-fail-origin.html: Copied from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials.html.
+        * http/tests/cookies/resources/third-party-cookie-relaxing-iframe.html: Sorting the cookie to make the test more resistant.
+        * http/tests/security/cross-origin-cached-images-expected.txt: Added.
+        * http/tests/security/cross-origin-cached-images-parallel-expected.txt: Added.
+        * http/tests/security/cross-origin-cached-images-parallel.html: Renamed from LayoutTests/http/tests/security/cross-origin-cached-resource-parallel.html.
+        * http/tests/security/cross-origin-cached-images.html: Renamed from LayoutTests/http/tests/security/cross-origin-cached-resource.html.
+        * http/tests/security/cross-origin-cached-resource-parallel-expected.txt: Removed.
+        * http/tests/security/cross-origin-cached-scripts-expected.txt: Added.
+        * http/tests/security/cross-origin-cached-scripts-parallel-expected.txt: Added.
+        * http/tests/security/cross-origin-cached-scripts-parallel.html: Added.
+        * http/tests/security/cross-origin-cached-scripts.html: Added.
+        * http/tests/security/resources/cors-script.php: Updated according chromium script to activate CORS credentials header if requested.
+        * http/tests/security/resources/cross-origin-cached-resource-iframe.html:
+        * http/tests/security/resources/notify-loaded.js: Added.
+        * http/tests/security/script-crossorigin-loads-correctly-credentials-expected.txt: Renamed from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials-expected.txt.
+        * http/tests/security/script-crossorigin-loads-correctly-credentials.html: Renamed from LayoutTests/imported/blink/http/tests/security/script-crossorigin-loads-correctly-credentials.html.
+        * http/tests/security/script-with-dataurl-expected.txt: Added.
+        * http/tests/security/script-with-dataurl.html: Added.
+        * http/tests/security/script-with-failed-cors-check-fails-to-load-expected.txt:
+
 2016-09-12  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         [GTK] Fix lint warnings of LayoutTests/platform/gtk/TestExpectations
index 9eae81a..7bcfb84 100644 (file)
@@ -21,11 +21,18 @@ window.onmessage = function(evt)
         alert("Unknown message.");
 }
 
+function sortCookie(cookie)
+{
+    var items = cookie.split("; ");
+    items.sort();
+    return items.join("; ");
+}
+
 var stage = 1;
 function showCookies()
 {
-    alert("Test stage " + stage++ + " document.cookie is: " + document.cookie);
-    parent.window.postMessage("done", "*");    
+    alert("Test stage " + stage++ + " document.cookie is: " + sortCookie(document.cookie));
+    parent.window.postMessage("done", "*");
 }
 
 function sendXHR(queryCommand)
diff --git a/LayoutTests/http/tests/local/script-crossorigin-loads-fail-origin-expected.txt b/LayoutTests/http/tests/local/script-crossorigin-loads-fail-origin-expected.txt
new file mode 100644 (file)
index 0000000..fb0b830
--- /dev/null
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: Origin  is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
+This test fails if the script loads correctly.
+
+PASS
diff --git a/LayoutTests/http/tests/local/script-crossorigin-loads-fail-origin.html b/LayoutTests/http/tests/local/script-crossorigin-loads-fail-origin.html
new file mode 100644 (file)
index 0000000..fa6ccfa
--- /dev/null
@@ -0,0 +1,23 @@
+<body>
+<p>This test fails if the script loads correctly.</p>
+<pre></pre>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function done(msg) {
+    document.querySelector("pre").innerHTML = msg;
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var script = document.createElement("script");
+script.crossOrigin = "use-credentials";
+// We are serving the test from the filesystem, so it should fail as authorized origin is 127.0.0.1:8000.
+script.src = "http://localhost:8000/security/resources/cors-script.php?credentials=true";
+script.onload = function() { done("FAIL"); }
+script.onerror = function() { done("PASS");}
+document.body.appendChild(script);
+</script>
diff --git a/LayoutTests/http/tests/security/cross-origin-cached-images-expected.txt b/LayoutTests/http/tests/security/cross-origin-cached-images-expected.txt
new file mode 100644 (file)
index 0000000..aad0512
--- /dev/null
@@ -0,0 +1,17 @@
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin image load denied by Cross-Origin Resource Sharing policy.
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin image load denied by Cross-Origin Resource Sharing policy.
+Tests source origin difference for cached resources.
+
+Trying to load sequentially the same image from different origins.
+Test 1 PASS: Loaded img http://127.0.0.1:8000/security/resources/abe-allow-star.php?allowCache from localhost:8000 (crossOrigin=anonymous)
+Test 2 PASS: Loaded img http://127.0.0.1:8000/security/resources/abe-allow-star.php?allowCache from localhost:8080 (crossOrigin=anonymous)
+Test 3 PASS: Loaded img http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8000 (crossOrigin=anonymous)
+Test 4 PASS: Did not load img http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8080 (crossOrigin=anonymous)
+Test 5 PASS: Loaded img http://127.0.0.1:8080/security/resources/abe-allow-star.php?allowCache from localhost:8000
+Test 6 PASS: Loaded img http://127.0.0.1:8080/security/resources/abe-allow-star.php?allowCache from localhost:8000 (crossOrigin=anonymous)
+Test 7 PASS: Loaded img http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8080
+Test 8 PASS: Did not load img http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8080 (crossOrigin=anonymous)
+     
+     
diff --git a/LayoutTests/http/tests/security/cross-origin-cached-images-parallel-expected.txt b/LayoutTests/http/tests/security/cross-origin-cached-images-parallel-expected.txt
new file mode 100644 (file)
index 0000000..0bc0505
--- /dev/null
@@ -0,0 +1,17 @@
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin image load denied by Cross-Origin Resource Sharing policy.
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin image load denied by Cross-Origin Resource Sharing policy.
+Tests source origin difference for cached resources.
+
+Trying to load sequentially the same image from different origins.
+Test 1 PASS: Loaded img http://127.0.0.1:8000/security/resources/abe-allow-star.php?allowCache from localhost:8000 (crossOrigin=anonymous)
+Test 2 PASS: Loaded img http://127.0.0.1:8000/security/resources/abe-allow-star.php?allowCache from localhost:8080 (crossOrigin=anonymous)
+Test 3 PASS: Loaded img http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&delay=200 from localhost:8000 (crossOrigin=anonymous)
+Test 4 PASS: Did not load img http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&delay=200 from localhost:8080 (crossOrigin=anonymous)
+Test 5 PASS: Loaded img http://127.0.0.1:8080/security/resources/abe-allow-star.php?allowCache from localhost:8000
+Test 6 PASS: Loaded img http://127.0.0.1:8080/security/resources/abe-allow-star.php?allowCache from localhost:8000 (crossOrigin=anonymous)
+Test 7 PASS: Loaded img http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&delay=200 from localhost:8080
+Test 8 PASS: Did not load img http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&delay=200 from localhost:8080 (crossOrigin=anonymous)
+     
+     
@@ -1,8 +1,7 @@
 <html>
 <body>
 <p>Tests source origin difference for cached resources.</p
-<p>Trying to load sequentially the same image from various origins.</p>
-<p>All images should load.</p>
+<p>Trying to load sequentially the same image from different origins.</p>
 <div id="console"></div>
 <div>
     <iframe id="iframe1"></iframe>
@@ -40,28 +39,28 @@ var iframeURL8000 = "http://localhost:8000/security/resources/cross-origin-cache
 var iframeURL8080 = "http://localhost:8080/security/resources/cross-origin-cached-resource-iframe.html";
 
 var allowAllImage1 = "http://127.0.0.1:8000/security/resources/abe-allow-star.php?allowCache";
-var allow8000Image1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000";
+var allow8000Image1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&delay=200";
 
 var allowAllImage2 = "http://127.0.0.1:8080/security/resources/abe-allow-star.php?allowCache";
-var allow8000Image2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000";
+var allow8000Image2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&delay=200";
 
 document.getElementById('iframe1').src = iframeURL8000 + "#" +
-    encodeURIComponent(JSON.stringify({url: allowAllImage1, shouldPass:true, crossOrigin: "anonymous", id: 1}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage1, shouldPass:true, crossOrigin: "anonymous", id: 1}));
 document.getElementById('iframe2').src = iframeURL8080 + "#" +
-    encodeURIComponent(JSON.stringify({url: allowAllImage1, shouldPass: true, crossOrigin: "anonymous", id: 2}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage1, shouldPass: true, crossOrigin: "anonymous", id: 2}));
 document.getElementById('iframe3').src = iframeURL8000 + "#" +
-    encodeURIComponent(JSON.stringify({url: allow8000Image1, shouldPass: true, crossOrigin: "anonymous", id: 3}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image1, shouldPass: true, crossOrigin: "anonymous", id: 3}));
 document.getElementById('iframe4').src = iframeURL8080 + "#" +
-    encodeURIComponent(JSON.stringify({url: allow8000Image1, shouldPass: false, crossOrigin: "anonymous", id: 4}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image1, shouldPass: false, crossOrigin: "anonymous", id: 4}));
 
 document.getElementById('iframe5').src = iframeURL8000 + "#" +
-    encodeURIComponent(JSON.stringify({url: allowAllImage2, shouldPass:true, id: 5}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage2, shouldPass:true, id: 5}));
 document.getElementById('iframe6').src = iframeURL8000 + "#" +
-    encodeURIComponent(JSON.stringify({url: allowAllImage2, shouldPass:true, crossOrigin: "anonymous", id: 6}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage2, shouldPass:true, crossOrigin: "anonymous", id: 6}));
 document.getElementById('iframe7').src = iframeURL8080 + "#" +
-    encodeURIComponent(JSON.stringify({url: allow8000Image2, shouldPass:true, id: 7}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image2, shouldPass:true, id: 7}));
 document.getElementById('iframe8').src = iframeURL8080 + "#" +
-    encodeURIComponent(JSON.stringify({url: allow8000Image2, shouldPass:false, crossOrigin: "anonymous", id: 8}));
+    encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image2, shouldPass:false, crossOrigin: "anonymous", id: 8}));
 </script>
 </body>
 </html>
@@ -1,8 +1,7 @@
 <html>
 <body>
 <p>Tests source origin difference for cached resources.</p
-<p>Trying to load sequentially the same image from various origins.</p>
-<p>All images should load.</p>
+<p>Trying to load sequentially the same image from different origins.</p>
 <div id="console"></div>
 <div>
     <iframe id="iframe1"></iframe>
@@ -43,31 +42,31 @@ function loadNextFrame()
     // Four first tests try to load an image with a given origin and then the same image (in cache) with a different origin.
     if (counter == 1)
         document.getElementById('iframe1').src = iframeURL8000 + "#" +
-            encodeURIComponent(JSON.stringify({url: allowAllImage1, shouldPass:true, crossOrigin: "anonymous", id: 1}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage1, shouldPass:true, crossOrigin: "anonymous", id: 1}));
     else if (counter == 2)
         document.getElementById('iframe2').src = iframeURL8080 + "#" +
-            encodeURIComponent(JSON.stringify({url: allowAllImage1, shouldPass: true, crossOrigin: "anonymous", id: 2}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage1, shouldPass: true, crossOrigin: "anonymous", id: 2}));
     else if (counter == 3)
         document.getElementById('iframe3').src = iframeURL8000 + "#" +
-            encodeURIComponent(JSON.stringify({url: allow8000Image1, shouldPass: true, crossOrigin: "anonymous", id: 3}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image1, shouldPass: true, crossOrigin: "anonymous", id: 3}));
     // Fourth image load should fail since requesting image from localhost:8080 while only allowed from localhost:8000.
     else if (counter == 4)
         document.getElementById('iframe4').src = iframeURL8080 + "#" +
-            encodeURIComponent(JSON.stringify({url: allow8000Image1, shouldPass: false, crossOrigin: "anonymous", id: 4}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image1, shouldPass: false, crossOrigin: "anonymous", id: 4}));
 
     // Four next tests try to load a cross-origin image without cors and then with cors.
     else if (counter == 5)
         document.getElementById('iframe5').src = iframeURL8000 + "#" +
-            encodeURIComponent(JSON.stringify({url: allowAllImage2, shouldPass:true, id: 5}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage2, shouldPass:true, id: 5}));
     else if (counter == 6)
         document.getElementById('iframe6').src = iframeURL8000 + "#" +
-            encodeURIComponent(JSON.stringify({url: allowAllImage2, shouldPass:true, crossOrigin: "anonymous", id: 6}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allowAllImage2, shouldPass:true, crossOrigin: "anonymous", id: 6}));
     else if (counter == 7)
         document.getElementById('iframe7').src = iframeURL8080 + "#" +
-            encodeURIComponent(JSON.stringify({url: allow8000Image2, shouldPass:true, id: 7}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image2, shouldPass:true, id: 7}));
     else if (counter == 8)
         document.getElementById('iframe8').src = iframeURL8080 + "#" +
-            encodeURIComponent(JSON.stringify({url: allow8000Image2, shouldPass:false, crossOrigin: "anonymous", id: 8}));
+            encodeURIComponent(JSON.stringify({node: "img", url: allow8000Image2, shouldPass:false, crossOrigin: "anonymous", id: 8}));
     else if (window.testRunner)
         testRunner.notifyDone();
 }
diff --git a/LayoutTests/http/tests/security/cross-origin-cached-resource-parallel-expected.txt b/LayoutTests/http/tests/security/cross-origin-cached-resource-parallel-expected.txt
deleted file mode 100644 (file)
index 31c8e9d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
-CONSOLE MESSAGE: Cross-origin image load denied by Cross-Origin Resource Sharing policy.
-CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
-CONSOLE MESSAGE: Cross-origin image load denied by Cross-Origin Resource Sharing policy.
-Tests source origin difference for cached resources.
-
-Trying to load sequentially the same image from various origins.
-All images should load.
-
-Test 1 PASS: Loaded image http://127.0.0.1:8000/security/resources/abe-allow-star.php?allowCache from localhost:8000 (crossOrigin=anonymous)
-Test 2 PASS: Loaded image http://127.0.0.1:8000/security/resources/abe-allow-star.php?allowCache from localhost:8080 (crossOrigin=anonymous)
-Test 3 PASS: Loaded image http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8000 (crossOrigin=anonymous)
-Test 4 PASS: Did not load image http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8080 (crossOrigin=anonymous)
-Test 5 PASS: Loaded image http://127.0.0.1:8080/security/resources/abe-allow-star.php?allowCache from localhost:8000
-Test 6 PASS: Loaded image http://127.0.0.1:8080/security/resources/abe-allow-star.php?allowCache from localhost:8000 (crossOrigin=anonymous)
-Test 7 PASS: Loaded image http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8080
-Test 8 PASS: Did not load image http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000 from localhost:8080 (crossOrigin=anonymous)
-     
-     
diff --git a/LayoutTests/http/tests/security/cross-origin-cached-scripts-expected.txt b/LayoutTests/http/tests/security/cross-origin-cached-scripts-expected.txt
new file mode 100644 (file)
index 0000000..63f852c
--- /dev/null
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
+Tests source origin difference for cached resources.
+
+Trying to load sequentially the same script from different origins.
+Test 1 PASS: Loaded script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8000 (crossOrigin=anonymous)
+Test 2 PASS: Did not load script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8080 (crossOrigin=anonymous)
+Test 3 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8080
+Test 4 PASS: Did not load script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js from localhost:8080 (crossOrigin=anonymous)
+  
+  
diff --git a/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel-expected.txt b/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel-expected.txt
new file mode 100644 (file)
index 0000000..7ae3cc7
--- /dev/null
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
+CONSOLE MESSAGE: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
+Tests source origin difference for cached resources.
+
+Trying to load sequentially the same script from various origins.
+Test 1 PASS: Loaded script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=100 from localhost:8000 (crossOrigin=anonymous)
+Test 2 PASS: Did not load script http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=100 from localhost:8080 (crossOrigin=anonymous)
+Test 3 PASS: Loaded script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=100 from localhost:8080
+Test 4 PASS: Did not load script http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=100 from localhost:8080 (crossOrigin=anonymous)
+  
+  
diff --git a/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel.html b/LayoutTests/http/tests/security/cross-origin-cached-scripts-parallel.html
new file mode 100644 (file)
index 0000000..0bc75ff
--- /dev/null
@@ -0,0 +1,51 @@
+<html>
+<body>
+<p>Tests source origin difference for cached resources.</p
+<p>Trying to load sequentially the same script from various origins.</p>
+<div id="console"></div>
+<div>
+    <iframe id="iframe1"></iframe>
+    <iframe id="iframe2"></iframe>
+</div>
+<div>
+    <iframe id="iframe3"></iframe>
+    <iframe id="iframe4"></iframe>
+</div>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var counter = 0;
+var messages = [];
+window.addEventListener("message", function(event) {
+    messages.push(event.data);
+    if (messages.length == 4) {
+        messages.sort();
+        messages.forEach((message) => {
+            document.getElementById('console').innerHTML += message + "<br/>";
+        })
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }
+});
+
+var iframeURL8000 = "http://localhost:8000/security/resources/cross-origin-cached-resource-iframe.html";
+var iframeURL8080 = "http://localhost:8080/security/resources/cross-origin-cached-resource-iframe.html";
+
+var allow8000Script1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=100";
+var allow8000Script2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js&delay=100";
+
+document.getElementById('iframe1').src = iframeURL8000 + "#" +
+    encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script1, shouldPass: true, crossOrigin: "anonymous", id: 1}));
+document.getElementById('iframe2').src = iframeURL8080 + "#" +
+    encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script1, shouldPass: false, crossOrigin: "anonymous", id: 2}));
+
+document.getElementById('iframe3').src = iframeURL8080 + "#" +
+    encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script2, shouldPass:true, id: 3}));
+document.getElementById('iframe4').src = iframeURL8080 + "#" +
+    encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script2, shouldPass:false, crossOrigin: "anonymous", id: 4}));
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/cross-origin-cached-scripts.html b/LayoutTests/http/tests/security/cross-origin-cached-scripts.html
new file mode 100644 (file)
index 0000000..bdaec4a
--- /dev/null
@@ -0,0 +1,58 @@
+<html>
+<body>
+<p>Tests source origin difference for cached resources.</p
+<p>Trying to load sequentially the same script from different origins.</p>
+<div id="console"></div>
+<div>
+    <iframe id="iframe1"></iframe>
+    <iframe id="iframe2"></iframe>
+</div>
+<div>
+    <iframe id="iframe3"></iframe>
+    <iframe id="iframe4"></iframe>
+</div>
+<script>
+if (window.testRunner) {
+   testRunner.dumpAsText();
+   testRunner.waitUntilDone();
+}
+
+window.addEventListener("message", function(event) {
+    document.getElementById('console').innerHTML += event.data + "<br/>";
+    loadNextFrame();
+});
+
+var iframeURL8000 = "http://localhost:8000/security/resources/cross-origin-cached-resource-iframe.html";
+var iframeURL8080 = "http://localhost:8080/security/resources/cross-origin-cached-resource-iframe.html";
+
+var allow8000Script1 = "http://127.0.0.1:8000/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js";
+var allow8000Script2 = "http://127.0.0.1:8080/security/resources/allow-if-origin.php?allowCache&origin=http%3A%2F%2Flocalhost%3A8000&name=notify-loaded.js";
+
+var counter = 0;
+function loadNextFrame()
+{
+    counter++;
+    // Four first tests try to load an image with a given origin and then the same image (in cache) with a different origin.
+    if (counter == 1)
+        document.getElementById('iframe1').src = iframeURL8000 + "#" +
+            encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script1, shouldPass: true, crossOrigin: "anonymous", id: 1}));
+    // Fourth image load should fail since requesting image from localhost:8080 while only allowed from localhost:8000.
+    else if (counter == 2)
+        document.getElementById('iframe2').src = iframeURL8080 + "#" +
+            encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script1, shouldPass: false, crossOrigin: "anonymous", id: 2}));
+
+    // Four next tests try to load a cross-origin image without cors and then with cors.
+    else if (counter == 3)
+        document.getElementById('iframe3').src = iframeURL8080 + "#" +
+            encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script2, shouldPass:true, id: 3}));
+    else if (counter == 4)
+        document.getElementById('iframe4').src = iframeURL8080 + "#" +
+            encodeURIComponent(JSON.stringify({node: "script", url: allow8000Script2, shouldPass:false, crossOrigin: "anonymous", id: 4}));
+    else if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+loadNextFrame();
+</script>
+</body>
+</html>
index 298acf1..a71df84 100644 (file)
@@ -1,6 +1,11 @@
 <?php
 header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
 header("Content-Type: application/javascript");
+
+if (strtolower($_GET["credentials"]) == "true") {
+    header("Access-Control-Allow-Credentials: true");
+}
+
 if (strtolower($_GET["fail"]) == "true")
     echo "throw({toString: function(){ return 'SomeError' }});";
 else
index f271930..700110c 100644 (file)
@@ -1,7 +1,8 @@
 <html>
 <body>
 
-<img id="img" onload="logStatus(true)" onerror="logStatus(false)"/>
+<img id="img" onload="logStatus(true)" onerror="logStatus(false)"></img>
+<script id="script" onload="logStatus(true)" onerror="logStatus(false)"></script>
 <script>
 var test = JSON.parse(decodeURIComponent(location.hash.substring(1)));
 
@@ -11,17 +12,17 @@ function logStatus(status)
     msg += test.shouldPass == status ? " PASS: " : " FAIL: ";
 
     msg += status ? "Loaded" : "Did not load";
-    msg += " image " + img.src + " from " + location.host;
+    msg += " " + test.node + " " + node.src + " from " + location.host;
     if (test.crossOrigin)
         msg += " (crossOrigin=" + test.crossOrigin + ")";
 
     parent.postMessage(msg, "*");
 }
 
-var image = document.getElementById('img');
+var node = document.getElementById(test.node);
 if (test.crossOrigin !== undefined)
-    image.crossOrigin = test.crossOrigin;
-image.src = test.url;
+    node.crossOrigin = test.crossOrigin;
+node.src = test.url;
 </script>
 </body>
 </html>
diff --git a/LayoutTests/http/tests/security/resources/notify-loaded.js b/LayoutTests/http/tests/security/resources/notify-loaded.js
new file mode 100644 (file)
index 0000000..0eb25e0
--- /dev/null
@@ -0,0 +1 @@
+document.body.innerHTML += "LOADED";
diff --git a/LayoutTests/http/tests/security/script-with-dataurl-expected.txt b/LayoutTests/http/tests/security/script-with-dataurl-expected.txt
new file mode 100644 (file)
index 0000000..bf74248
--- /dev/null
@@ -0,0 +1,10 @@
+CONSOLE MESSAGE: line 1: PASS: my data URL in no-cors mode is throwing rich messages
+CONSOLE MESSAGE: Origin http://127.0.0.1:8000 is not allowed by Access-Control-Allow-Origin.
+CONSOLE MESSAGE: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
+Trying to load data URLs scripts. If being loaded, the scripts should throw error messages.
+
+Received error 'Script error.' from '', location 0:0.
+PASS: loaded script in no-cors mode
+PASS: did not load script in cors mode
+DONE
+
diff --git a/LayoutTests/http/tests/security/script-with-dataurl.html b/LayoutTests/http/tests/security/script-with-dataurl.html
new file mode 100644 (file)
index 0000000..7a514de
--- /dev/null
@@ -0,0 +1,47 @@
+<body>
+<p>Trying to load data URLs scripts. If being loaded, the scripts should throw error messages.</p>
+<pre></pre>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function done() {
+    log("DONE");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function log(msg) {
+    document.querySelector("pre").innerHTML += msg + "<br>";
+}
+
+window.onerror = function(message, source, lineno, colno, error)
+{
+    log("Received error '" + message + "' from '" + source + "', location " + lineno + ":" + colno + ".");
+}
+
+function test1()
+{
+    var script = document.createElement("script");
+    script.src = "data:text/script, throw 'PASS: my data URL in no-cors mode is throwing rich messages';";
+    script.onload = () => { log("PASS: loaded script in no-cors mode"); test2(); }
+    script.onerror = () => { log("FAIL: did not load script in no-cors mode"); test2(); }
+    document.body.appendChild(script);
+}
+
+function test2()
+{
+    var script = document.createElement("script");
+    script.crossOrigin = "";
+    script.src = "data:text/script, throw 'FAIL: my error is too rich!'";
+    script.onload = () => { log("FAIL: loaded script in cors mode"); done(); }
+    script.onerror = () => { log("PASS: did not load script in cors mode"); done(); }
+    document.body.appendChild(script);
+}
+
+test1();
+
+</script>
+</body>
index 83a69af..4e63b48 100644 (file)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: Origin http://127.0.0.1:8000 is not allowed by Access-Control-Allow-Origin.
 CONSOLE MESSAGE: Cross-origin script load denied by Cross-Origin Resource Sharing policy.
 This test passes if the script does not load.
 
index 6de28ea..4a68512 100644 (file)
@@ -1,3 +1,43 @@
+2016-09-12  Youenn Fablet  <youenn@apple.com>
+
+        ScriptElement should use FetchOptions::mode according its crossOrigin attribute
+        https://bugs.webkit.org/show_bug.cgi?id=161686
+
+        Reviewed by Darin Adler.
+
+        Setting ScriptElement fetch mode according its crossOrigin attribute.
+        Removing LoadableClassicScriptchecking of CORS since this is now done at ResourceLoader/CachedResource level.
+
+        Updating CachedResourceLoader to ensure that a resource that matches an on-going resource load but with different fetch mode/origin,
+        always gets its loading started if the resource state is not Cached.
+
+        Tests: fast/dom/script-crossorigin-loads-fail-origin.html
+               http/tests/security/cross-origin-cached-images-parallel.html
+               http/tests/security/cross-origin-cached-images.html
+               http/tests/security/cross-origin-cached-scripts-parallel.html
+               http/tests/security/cross-origin-cached-scripts.html
+               http/tests/security/script-crossorigin-loads-correctly-credentials.html
+               http/tests/security/script-with-dataurl.html
+
+        * dom/LoadableClassicScript.cpp:
+        (WebCore::LoadableClassicScript::create):
+        (WebCore::LoadableClassicScript::notifyFinished): Checking CORS failures using the resource state.
+        (WebCore::LoadableClassicScript::~LoadableClassicScript): Deleted.
+        (WebCore::LoadableClassicScript::isLoaded): Deleted.
+        * dom/LoadableClassicScript.h:
+        * dom/ScriptElement.cpp:
+        (WebCore::ScriptElement::requestClassicScript):
+        (WebCore::ScriptElement::requestScriptWithCache): Using CachedResourceRequest::setAsPotentiallyCrossOrigin to set fetch mode according crossOrigin attribute.
+        * dom/ScriptElement.h:
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::setBodyDataFrom):
+        * loader/cache/CachedResourceLoader.cpp:
+        (WebCore::CachedResourceLoader::updateCachedResourceWithCurrentRequest): Adding support for script resources.
+        (WebCore::CachedResourceLoader::requestResource): Ensuring that 'updated' resources gets actually loaded.
+        * loader/cache/CachedScript.cpp:
+        (WebCore::CachedScript::setBodyDataFrom): Implementing specific data copy from another CachedScript.
+        * loader/cache/CachedScript.h:
+
 2016-09-12  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Scrollbar  too large
index 379f209..11f1205 100644 (file)
 
 namespace WebCore {
 
-Ref<LoadableClassicScript> LoadableClassicScript::create(CachedResourceHandle<CachedScript>&& cachedScript, const String& crossOriginMode, SecurityOrigin& securityOrigin)
+Ref<LoadableClassicScript> LoadableClassicScript::create(CachedResourceHandle<CachedScript>&& cachedScript)
 {
     ASSERT(cachedScript);
-    auto script = adoptRef(*new LoadableClassicScript(WTFMove(cachedScript), crossOriginMode, securityOrigin));
+    auto script = adoptRef(*new LoadableClassicScript(WTFMove(cachedScript)));
     cachedScript->addClient(script.ptr());
     return script;
 }
 
-LoadableClassicScript::LoadableClassicScript(CachedResourceHandle<CachedScript>&& cachedScript, const String& crossOriginMode, SecurityOrigin& securityOrigin)
-    : m_cachedScript(cachedScript)
-    , m_securityOrigin(securityOrigin)
-    , m_requestUsesAccessControl(!crossOriginMode.isNull())
-{
-}
-
 LoadableClassicScript::~LoadableClassicScript()
 {
     m_cachedScript->removeClient(this);
@@ -74,9 +67,10 @@ bool LoadableClassicScript::wasCanceled() const
     return m_cachedScript->wasCanceled();
 }
 
-void LoadableClassicScript::notifyFinished(CachedResource*)
+void LoadableClassicScript::notifyFinished(CachedResource* resource)
 {
-    if (!m_error && m_requestUsesAccessControl && !m_cachedScript->passesSameOriginPolicyCheck(m_securityOrigin.get())) {
+    ASSERT(resource);
+    if (resource->resourceError().isAccessControl()) {
         static NeverDestroyed<String> consoleMessage(ASCIILiteral("Cross-origin script load denied by Cross-Origin Resource Sharing policy."));
         m_error = Error {
             ErrorType::CrossOriginLoad,
index 247d8d9..afdf152 100644 (file)
@@ -42,7 +42,7 @@ class LoadableClassicScript final : public LoadableScript, private CachedResourc
 public:
     ~LoadableClassicScript();
 
-    static Ref<LoadableClassicScript> create(CachedResourceHandle<CachedScript>&&, const String& crossOriginMode, SecurityOrigin&);
+    static Ref<LoadableClassicScript> create(CachedResourceHandle<CachedScript>&&);
     bool isLoaded() const override;
     Optional<Error> wasErrored() const override;
     bool wasCanceled() const override;
@@ -53,14 +53,12 @@ public:
     void execute(ScriptElement&) override;
 
 private:
-    LoadableClassicScript(CachedResourceHandle<CachedScript>&&, const String& crossOriginMode, SecurityOrigin&);
+    LoadableClassicScript(CachedResourceHandle<CachedScript>&& cachedScript) : m_cachedScript(WTFMove(cachedScript)) { }
 
     void notifyFinished(CachedResource*) override;
 
     CachedResourceHandle<CachedScript> m_cachedScript;
-    Ref<SecurityOrigin> m_securityOrigin;
     Optional<Error> m_error { Nullopt };
-    bool m_requestUsesAccessControl;
 };
 
 }
index fa76006..31f2f9c 100644 (file)
@@ -263,10 +263,9 @@ bool ScriptElement::requestClassicScript(const String& sourceURL)
 
     ASSERT(!m_loadableScript);
     if (!stripLeadingAndTrailingHTMLSpaces(sourceURL).isEmpty()) {
-        String crossOriginMode = m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr);
-        auto request = requestScriptWithCache(m_element.document().completeURL(sourceURL), m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr), crossOriginMode);
+        auto request = requestScriptWithCache(m_element.document().completeURL(sourceURL), m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr));
         if (request) {
-            m_loadableScript = LoadableClassicScript::create(WTFMove(request), crossOriginMode, *m_element.document().securityOrigin());
+            m_loadableScript = LoadableClassicScript::create(WTFMove(request));
             m_isExternalScript = true;
         }
     }
@@ -280,22 +279,17 @@ bool ScriptElement::requestClassicScript(const String& sourceURL)
     return false;
 }
 
-CachedResourceHandle<CachedScript> ScriptElement::requestScriptWithCache(const URL& sourceURL, const String& nonceAttribute, const String& crossOriginMode)
+CachedResourceHandle<CachedScript> ScriptElement::requestScriptWithCache(const URL& sourceURL, const String& nonceAttribute)
 {
     bool hasKnownNonce = m_element.document().contentSecurityPolicy()->allowScriptWithNonce(nonceAttribute, m_element.isInUserAgentShadowTree());
     ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
     options.contentSecurityPolicyImposition = hasKnownNonce ? ContentSecurityPolicyImposition::SkipPolicyCheck : ContentSecurityPolicyImposition::DoPolicyCheck;
 
     CachedResourceRequest request(ResourceRequest(sourceURL), options);
+    request.setAsPotentiallyCrossOrigin(m_element.attributeWithoutSynchronization(HTMLNames::crossoriginAttr), m_element.document());
 
     m_element.document().contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(request.mutableResourceRequest(), ContentSecurityPolicy::InsecureRequestType::Load);
 
-    if (!crossOriginMode.isNull()) {
-        StoredCredentials allowCredentials = equalLettersIgnoringASCIICase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
-        ASSERT(m_element.document().securityOrigin());
-        updateRequestForAccessControl(request.mutableResourceRequest(), *m_element.document().securityOrigin(), allowCredentials);
-    }
-
     request.setCharset(scriptCharset());
     request.setInitiator(&element());
 
index f52b778..18e33b5 100644 (file)
@@ -89,7 +89,7 @@ private:
     bool ignoresLoadRequest() const;
     bool isScriptForEventSupported() const;
 
-    CachedResourceHandle<CachedScript> requestScriptWithCache(const URL&, const String& nonceAttribute, const String& crossoriginAttribute);
+    CachedResourceHandle<CachedScript> requestScriptWithCache(const URL&, const String&);
 
     bool requestClassicScript(const String& sourceURL);
 
index b5d0ed7..8f5725c 100644 (file)
@@ -119,7 +119,6 @@ void CachedImage::setBodyDataFrom(const CachedResource& resource)
     ASSERT(resource.type() == type());
     const CachedImage& image = static_cast<const CachedImage&>(resource);
 
-    setLoading(false);
     m_image = image.m_image;
 
     if (m_image && is<SVGImage>(*m_image))
index 9a7b2fd..e937e37 100644 (file)
@@ -546,7 +546,7 @@ bool CachedResourceLoader::updateCachedResourceWithCurrentRequest(CachedResource
     CachedResource& resource = *resourceHandle;
 
     // FIXME: We should progressively extend this to other reusable resources
-    if (resource.type() != CachedResource::Type::ImageResource && resource.type() != CachedResource::Type::TextTrackResource)
+    if (resource.type() != CachedResource::Type::ImageResource && resource.type() != CachedResource::Type::Script && resource.type() != CachedResource::Type::TextTrackResource)
         return false;
 
     bool shouldUpdate = resource.options().mode != request.options().mode || request.resourceRequest().httpOrigin() != resource.resourceRequest().httpOrigin();
@@ -647,7 +647,7 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache
 
     logMemoryCacheResourceRequest(frame(), resource ? DiagnosticLoggingKeys::inMemoryCacheKey() : DiagnosticLoggingKeys::notInMemoryCacheKey());
 
-    const RevalidationPolicy policy = determineRevalidationPolicy(type, request, resource.get());
+    RevalidationPolicy policy = determineRevalidationPolicy(type, request, resource.get());
     switch (policy) {
     case Reload:
         memoryCache.remove(*resource);
@@ -663,7 +663,11 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache
         resource = revalidateResource(request, resource.get());
         break;
     case Use:
-        if (!updateCachedResourceWithCurrentRequest(request, resource)) {
+        if (updateCachedResourceWithCurrentRequest(request, resource)) {
+            if (resource->status() != CachedResource::Status::Cached)
+                policy = Load;
+        } else {
+            ASSERT(policy == Use);
             if (!shouldContinueAfterNotifyingLoadedFromMemoryCache(request, resource.get()))
                 return nullptr;
             logMemoryCacheResourceRequest(frame(), DiagnosticLoggingKeys::inMemoryCacheKey(), DiagnosticLoggingKeys::usedKey());
index 74584c9..990af1d 100644 (file)
@@ -123,6 +123,18 @@ void CachedScript::destroyDecodedData()
     setDecodedSize(0);
 }
 
+void CachedScript::setBodyDataFrom(const CachedResource& resource)
+{
+    ASSERT(resource.type() == type());
+    auto& script = static_cast<const CachedScript&>(resource);
+
+    m_data = script.m_data;
+    m_script = script.m_script;
+    m_scriptHash = script.m_scriptHash;
+    m_decodingState = script.m_decodingState;
+    m_decoder = script.m_decoder;
+}
+
 #if ENABLE(NOSNIFF)
 bool CachedScript::mimeTypeAllowedByNosniff() const
 {
index dbf1d14..4013346 100644 (file)
@@ -47,16 +47,18 @@ public:
 #endif
 
 private:
-    bool mayTryReplaceEncodedData() const override { return true; }
+    bool mayTryReplaceEncodedData() const final { return true; }
 
-    bool shouldIgnoreHTTPStatusCodeErrors() const override;
+    bool shouldIgnoreHTTPStatusCodeErrors() const final;
 
-    void setEncoding(const String&) override;
-    String encoding() const override;
-    const TextResourceDecoder* textResourceDecoder() const override { return m_decoder.get(); }
-    void finishLoading(SharedBuffer*) override;
+    void setEncoding(const String&) final;
+    String encoding() const final;
+    const TextResourceDecoder* textResourceDecoder() const final { return m_decoder.get(); }
+    void finishLoading(SharedBuffer*) final;
 
-    void destroyDecodedData() override;
+    void destroyDecodedData() final;
+
+    void setBodyDataFrom(const CachedResource&) final;
 
     String m_script;
     unsigned m_scriptHash { 0 };