Bug 606729 - Make sure a script with the src attribute is treated as an external script even if the value of the attribute is not a valid URL. r=jonas, a=blocking2.0-final.
authorHenri Sivonen <hsivonen@iki.fi>
Wed, 27 Oct 2010 10:03:10 +0300
changeset 57850 d6d9cb57b170c100ea9ed8b54629d936b6a1052c
parent 57849 fe9637495f974593b4c6e706f1ddb22b57c021f6
child 57851 48d4abb5de8fb0c59a84fd023b59deb396849d5b
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersjonas, blocking2
bugs606729
milestone2.0b8pre
Bug 606729 - Make sure a script with the src attribute is treated as an external script even if the value of the attribute is not a valid URL. r=jonas, a=blocking2.0-final.
content/base/crashtests/606729-1.html
content/base/crashtests/crashtests.list
content/base/public/nsIScriptElement.h
content/base/src/nsScriptLoader.cpp
content/base/test/Makefile.in
content/base/test/test_bug606729.html
content/html/content/src/nsHTMLScriptElement.cpp
content/svg/content/src/nsSVGScriptElement.cpp
new file mode 100644
--- /dev/null
+++ b/content/base/crashtests/606729-1.html
@@ -0,0 +1,1 @@
+<script async src="data:">0</script>
--- a/content/base/crashtests/crashtests.list
+++ b/content/base/crashtests/crashtests.list
@@ -69,8 +69,9 @@ load 552651.html
 load 558973.html
 load 564079-1.html 
 load 564114.html
 load 565125-1.html
 load 582601.html
 load 575462.svg
 load 595606-1.html
 load 595606-2.html
+load 606729-1.html
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -65,16 +65,17 @@ public:
       mMalformed(PR_FALSE),
       mDoneAddingChildren(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
                           aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
       mForceAsync(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
                   aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT),
       mFrozen(PR_FALSE),
       mDefer(PR_FALSE),
       mAsync(PR_FALSE),
+      mExternal(PR_FALSE),
       mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
                      mozilla::dom::NOT_FROM_PARSER : aFromParser),
                      // Fragment parser-created scripts (if executable)
                      // behave like script-created scripts.
       mCreatorParser(nsnull)
   {
   }
 
@@ -122,16 +123,25 @@ public:
    */
   PRBool GetScriptAsync()
   {
     NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
     return mAsync;  
   }
 
   /**
+   * Is the script an external script?
+   */
+  PRBool GetScriptExternal()
+  {
+    NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
+    return mExternal;
+  }
+
+  /**
    * Returns how the element was created.
    */
   mozilla::dom::FromParser GetParserCreated()
   {
     return mParserCreated;
   }
 
   void SetScriptLineNumber(PRUint32 aLineNumber)
@@ -245,16 +255,22 @@ protected:
   PRPackedBool mDefer;
   
   /**
    * The effective asyncness.
    */
   PRPackedBool mAsync;
   
   /**
+   * The effective externalness. A script can be external with mUri being null
+   * if the src attribute contained an invalid URL string.
+   */
+  PRPackedBool mExternal;
+
+  /**
    * Whether this element was parser-created.
    */
   mozilla::dom::FromParser mParserCreated;
 
   /**
    * The effective src (or null if no src).
    */
   nsCOMPtr<nsIURI> mUri;
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -541,20 +541,23 @@ nsScriptLoader::ProcessScriptElement(nsI
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsCOMPtr<nsIContent> eltContent(do_QueryInterface(aElement));
   eltContent->SetScriptTypeID(typeID);
 
   // Step 9. in the HTML5 spec
 
-  nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
   nsRefPtr<nsScriptLoadRequest> request;
-  if (scriptURI) {
+  if (aElement->GetScriptExternal()) {
     // external script
+    nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
+    if (!scriptURI) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
     nsTArray<PreloadInfo>::index_type i =
       mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
     if (i != nsTArray<PreloadInfo>::NoIndex) {
       // preloaded
       // note that a script-inserted script can steal a preload!
       request = mPreloads[i].mRequest;
       request->mElement = aElement;
       // XXX what if the charset attribute of the element and the charset
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -437,16 +437,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug604660.html \
 		file_bug604660-1.xml \
 		file_bug604660-2.xsl \
 		file_bug604660-3.js \
 		file_bug604660-4.js \
 		file_bug604660-5.xml \
 		file_bug604660-6.xsl \
 		test_bug605982.html \
+		test_bug606729.html \
 		test_treewalker_nextsibling.xml \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
 _TEST_FILES2 += 	test_copyimage.html \
 		$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug606729.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=606729
+-->
+<head>
+  <title>Test for Bug 606729</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=606729">Mozilla Bug 606729</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script
+  src="data:"
+  onerror="ok(false, 'Script with src=data: should not fire onerror.');"
+  onload="ok(false, 'Script with src=data: should not fire onload.');"
+>
+ok(false, "Script with src=data: should not run textContent.");
+</script>
+<script
+  src="bogus:"
+  onerror="ok(false, 'Script with src=bogus: should not fire onerror.');"
+  onload="ok(false, 'Script with src=bogus: should not fire onload.');"
+>
+ok(false, "Script with src=bogus: should not run textContent.");
+</script>
+<script class="testbody" type="text/javascript">
+ok(true, "Obligatory succeeding test assertion.");
+</script>
+</pre>
+</body>
+</html>
+
+
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -551,32 +551,34 @@ nsHTMLScriptElement::FreezeUriAsyncDefer
   }
   
   // variation of this code in nsSVGScriptElement - check if changes
   // need to be transfered when modifying
   if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
     nsAutoString src;
     GetSrc(src);
     NS_NewURI(getter_AddRefs(mUri), src);
+    // At this point mUri will be null for invalid URLs.
+    mExternal = PR_TRUE;
 
     PRBool defer, async;
     GetAsync(&async);
     GetDefer(&defer);
 
     mDefer = !async && defer;
     mAsync = async;
   }
   
   mFrozen = PR_TRUE;
 }
 
 PRBool
 nsHTMLScriptElement::HasScriptContent()
 {
-  return (mFrozen ? !!mUri : HasAttr(kNameSpaceID_None, nsGkAtoms::src)) ||
+  return (mFrozen ? mExternal : HasAttr(kNameSpaceID_None, nsGkAtoms::src)) ||
          nsContentUtils::HasNonEmptyTextContent(this);
 }
 
 nsresult
 nsHTMLScriptElement::MaybeProcessScript()
 {
   nsresult rv = nsScriptElement::MaybeProcessScript();
   if (rv == NS_CONTENT_SCRIPT_IS_EVENTHANDLER) {
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -226,31 +226,33 @@ nsSVGScriptElement::FreezeUriAsyncDefer(
   // variation of this code in nsHTMLScriptElement - check if changes
   // need to be transfered when modifying
   nsAutoString src;
   mStringAttributes[HREF].GetAnimValue(src, this);
   // preserving bug 528444 here due to being unsure how to fix correctly
   if (!src.IsEmpty()) {
     nsCOMPtr<nsIURI> baseURI = GetBaseURI();
     NS_NewURI(getter_AddRefs(mUri), src, nsnull, baseURI);
+    // At this point mUri will be null for invalid URLs.
+    mExternal = PR_TRUE;
   }
   
   mFrozen = PR_TRUE;
 }
 
 //----------------------------------------------------------------------
 // nsScriptElement methods
 
 PRBool
 nsSVGScriptElement::HasScriptContent()
 {
   nsAutoString src;
   mStringAttributes[HREF].GetAnimValue(src, this);
   // preserving bug 528444 here due to being unsure how to fix correctly
-  return (mFrozen ? !!mUri : !src.IsEmpty()) ||
+  return (mFrozen ? mExternal : !src.IsEmpty()) ||
          nsContentUtils::HasNonEmptyTextContent(this);
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 void
 nsSVGScriptElement::DidChangeString(PRUint8 aAttrEnum)