Bug 732209 part 5. Enforce CORS on stylesheet loads as needed. r=sicking
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 28 Aug 2012 13:10:08 -0400
changeset 105709 4af1510fc1c2f8e4ac154e5d5724c9a56e2e3135
parent 105708 40e63320e4b5cf575c3e8bd9b56e7dc0fae74bd6
child 105710 62b86f439a09333d52db9d69e2023a1b0002fbc5
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewerssicking
bugs732209
milestone18.0a1
Bug 732209 part 5. Enforce CORS on stylesheet loads as needed. r=sicking
layout/style/Loader.cpp
layout/style/test/Makefile.in
layout/style/test/bug732209-css.sjs
layout/style/test/test_bug732209.html
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -46,16 +46,17 @@
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsCSSParser.h"
 #include "mozilla/css/ImportRule.h"
 #include "nsThreadUtils.h"
 #include "nsGkAtoms.h"
 #include "nsDocShellCID.h"
 #include "nsIThreadInternal.h"
+#include "nsCrossSiteListenerProxy.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPrototypeCache.h"
 #endif
 
 #include "nsIMediaList.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsIDOMCSSStyleSheet.h"
@@ -1553,19 +1554,46 @@ Loader::LoadSheet(SheetLoadData* aLoadDa
     }
   }
 
   // We don't have to hold on to the stream loader.  The ownership
   // model is: Necko owns the stream loader, which owns the load data,
   // which owns us
   nsCOMPtr<nsIUnicharStreamLoader> streamLoader;
   rv = NS_NewUnicharStreamLoader(getter_AddRefs(streamLoader), aLoadData);
+  if (NS_FAILED(rv)) {
+#ifdef DEBUG
+    mSyncCallback = false;
+#endif
+    LOG_ERROR(("  Failed to create stream loader"));
+    SheetComplete(aLoadData, rv);
+    return rv;
+  }
 
-  if (NS_SUCCEEDED(rv))
-    rv = channel->AsyncOpen(streamLoader, nullptr);
+  nsCOMPtr<nsIStreamListener> channelListener;
+  CORSMode ourCORSMode = aLoadData->mSheet->GetCORSMode();
+  if (ourCORSMode != CORS_NONE) {
+    bool withCredentials = (ourCORSMode == CORS_USE_CREDENTIALS);
+    LOG(("  Doing CORS-enabled load; credentials %d", withCredentials));
+    channelListener =
+      new nsCORSListenerProxy(streamLoader, aLoadData->mLoaderPrincipal,
+			      channel, withCredentials, &rv);
+    if (NS_FAILED(rv)) {
+#ifdef DEBUG
+      mSyncCallback = false;
+#endif
+      LOG_ERROR(("  Initial CORS check failed"));
+      SheetComplete(aLoadData, rv);
+      return rv;
+    }
+  } else {
+    channelListener = streamLoader;
+  }
+
+  rv = channel->AsyncOpen(channelListener, nullptr);
 
 #ifdef DEBUG
   mSyncCallback = false;
 #endif
 
   if (NS_FAILED(rv)) {
     LOG_ERROR(("  Failed to create stream loader"));
     SheetComplete(aLoadData, rv);
--- a/layout/style/test/Makefile.in
+++ b/layout/style/test/Makefile.in
@@ -181,16 +181,18 @@ MOCHITEST_FILES =	test_acid3_test46.html
 		visited-pref-iframe.html \
 		visited-lying-inner.html \
 		visited_image_loading.sjs \
 		visited_image_loading_frame.html \
 		visited_image_loading_frame_empty.html \
 		test_load_events_on_stylesheets.html \
 		test_bug721136.html \
 		test_bug732153.html \
+		test_bug732209.html \
+		bug732209-css.sjs \
 		$(NULL)
 
 ifdef MOZ_FLEXBOX
 MOCHITEST_FILES +=	\
 		test_flexbox_align_self_auto.html \
 		test_flexbox_flex_grow_and_shrink.html \
 		test_flexbox_flex_shorthand.html \
 		test_flexbox_layout.html \
new file mode 100644
--- /dev/null
+++ b/layout/style/test/bug732209-css.sjs
@@ -0,0 +1,19 @@
+function handleRequest(request, response)
+{
+   // First item will be the ID; other items are optional
+   var query = request.queryString.split(/&/);
+
+   response.setHeader("Content-Type", "text/css", false);
+
+   if (query.indexOf("cors-anonymous") != -1) {
+     response.setHeader("Access-Control-Allow-Origin", "*", false);
+   } else if (query.indexOf("cors-credentials") != -1 &&
+              request.hasHeader("Origin")) {
+     response.setHeader("Access-Control-Allow-Origin",
+                        request.getHeader("Origin"), false)
+     response.setHeader("Access-Control-Allow-Credentials", "true", false);
+   }
+
+   response.write("#" + query[0] + " { color: green !important }" + "\n" +
+                  "#" + query[0] + ".reverse { color: red !important }");
+}
new file mode 100644
--- /dev/null
+++ b/layout/style/test/test_bug732209.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=732209
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 732209</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <style>
+    #content span { color: red; }
+    #content span.reverse { color: green; }
+    #content { display: block !important; }
+    #content span::before { content: attr(id); }
+  </style>
+  <link rel="stylesheet" href="bug732209-css.sjs?one">
+  <link rel="stylesheet" href="bug732209-css.sjs?two" crossorigin>
+  <link rel="stylesheet" href="bug732209-css.sjs?three" crossorigin="use-credentials">
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?four">
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?five"
+        crossorigin>
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?six"
+        crossorigin="use-credentials">
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?seven&cors-anonymous">
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?eight&cors-anonymous"
+        crossorigin>
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?nine&cors-anonymous"
+        crossorigin="use-credentials">
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?ten&cors-credentials">
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?eleven&cors-credentials"
+        crossorigin>
+  <link rel="stylesheet"
+        href="http://example.com/tests/layout/style/test/bug732209-css.sjs?twelve&cors-credentials"
+        crossorigin="use-credentials">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=732209">Mozilla Bug 732209</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <span id="one"></span>
+  <span id="two"></span>
+  <span id="three"></span>
+  <span id="four"></span>
+  <span id="five" class="reverse"></span>
+  <span id="six" class="reverse"></span>
+  <span id="seven"></span>
+  <span id="eight"></span>
+  <span id="nine" class="reverse"></span>
+  <span id="ten"></span>
+  <span id="eleven"></span>
+  <span id="twelve"></span>
+</div>
+<pre id="test" style="color: red">
+<script type="application/javascript">
+
+/** Test for Bug 732209 **/
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+  var spans = $("content").querySelectorAll("span");
+  for (var i = 0; i < spans.length; ++i) {
+    is(getComputedStyle(spans[i], "").color, "rgb(0, 128, 0)",
+       "Span " + spans[i].id + " should be green");
+  }
+  SimpleTest.finish();
+});
+
+
+
+</script>
+</pre>
+</body>
+</html>