Bug 631615: Suppress CSS parser diagnostics in ParseSelectorString. r=dbaron a191=dveditz
authorZack Weinberg <zackw@panix.com>
Mon, 21 Mar 2011 16:08:46 -0700
changeset 27373 52e0d3ae78dd15c022b3087faf9ceed936024980
parent 27370 aeeba2b6d48747da0d99e90fa49771039bc9e14e
child 27374 9c8182d5a5ec2e6163cde544c653f0cdd3b5a9d2
push id2697
push userzackw@panix.com
push dateMon, 21 Mar 2011 23:50:44 +0000
reviewersdbaron
bugs631615
milestone1.9.1.19pre
Bug 631615: Suppress CSS parser diagnostics in ParseSelectorString. r=dbaron a191=dveditz
content/base/test/Makefile.in
content/base/test/test_bug631615.html
layout/style/nsCSSParser.cpp
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -283,16 +283,17 @@ include $(topsrcdir)/config/rules.mk
 		file_htmlserializer_ipv6.html \
 		file_htmlserializer_ipv6_out.html \
 		test_bug498433.html \
 		test_bug498897.html \
 		file_bug498897.html \
 		file_bug498897.html^headers^ \
 		file_bug498897.css \
 		test_bug590771.html \
+		test_bug631615.html \
 		$(NULL)
 
 # Disabled for now. Mochitest isn't reliable enough for these.
 # test_bug444546.html \
 # bug444546.sjs \
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug631615.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=631615
+-->
+<head>
+  <title>Test for Bug 631615</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/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=631615">Mozilla Bug 631615</a>
+<pre id="monitor">
+</pre>
+<script type="application/javascript">
+
+netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+var consoleService =
+  Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
+
+var messageCount = 0;
+var monitor = document.getElementById("monitor");
+
+var listener = {
+  observe: function(message) {
+    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+
+    if (message.message === "sentinel") {
+      is(messageCount, 0, "should have been no console messages");
+      removeListener();
+      SimpleTest.finish();
+    } else {
+      messageCount++;
+      var err = "" + messageCount + ": " + message.message + "\n";
+      monitor.appendChild(document.createTextNode(err));
+    }
+  },
+
+  QueryInterface: function(iid) {
+    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+    if (iid.equals(Ci.nsIConsoleListener) ||
+        iid.equals(Ci.nsISupports)) {
+      return this;
+    }
+    throw Cr.NS_NOINTERFACE;
+  }
+};
+
+function addListener() {
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+  consoleService.reset();
+  consoleService.registerListener(listener);
+}
+
+function removeListener() {
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+  consoleService.unregisterListener(listener);
+}
+
+function postSentinel() {
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+  consoleService.logStringMessage("sentinel");
+}
+
+SimpleTest.waitForExplicitFinish();
+
+function doTest() {
+  // 1.9.1 doesn't have matchesSelector, use querySelector instead
+  var results;
+  addListener();
+  try {
+    results = "return: " +
+      document.querySelector("[test!='']:sizzle") + "\n";
+  } catch (e) {
+    results = "throws: " + e + "\n";
+  }
+
+  monitor.appendChild(document.createTextNode(results));
+  is(results.slice(0, 6), "throws", "looking for an exception");
+
+  postSentinel();
+}
+doTest();
+
+</script>
+</body>
+</html>
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -1239,17 +1239,25 @@ CSSParserImpl::ParseSelectorString(const
   InitScanner(aSelectorString, aURL, aLineNumber, aURL, nsnull);
 
   AssertInitialState();
 
   mUnresolvablePrefixException = PR_TRUE;
 
   PRBool success = ParseSelectorList(*aSelectorList, PR_FALSE);
   nsresult rv = mScanner.GetLowLevelError();
-  OUTPUT_ERROR();
+  // We deliberately do not call OUTPUT_ERROR here, because all our
+  // callers map a failure return to a JS exception, and if that JS
+  // exception is caught, people don't want to see parser diagnostics;
+  // see e.g. http://bugs.jquery.com/ticket/7535
+  // It would be nice to be able to save the parser diagnostics into
+  // the exception, so that if it _isn't_ caught we can report them
+  // along with the usual uncaught-exception message, but we don't
+  // have any way to do that at present; see bug 631621.
+  CLEAR_ERROR();
   ReleaseScanner();
 
   mUnresolvablePrefixException = PR_FALSE;
 
   if (success) {
     NS_ASSERTION(*aSelectorList, "Should have list!");
     return NS_OK;
   }