Bug 795275 - Warn about content access to |Components|. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Wed, 03 Oct 2012 11:44:18 +0200
changeset 109032 aeda4978c97c9c65cd73bc98b7c23b08bd3f9163
parent 109031 43de19945cb1beacc8d20595627216e7b76f4954
child 109033 223f29a9e730b9c34a83c3c36e4b565d02dbc33c
push id15813
push userbobbyholley@gmail.com
push dateWed, 03 Oct 2012 09:44:37 +0000
treeherdermozilla-inbound@223f29a9e730 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs795275
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 795275 - Warn about content access to |Components|. r=mrbkap
content/base/public/nsDeprecatedOperationList.h
dom/locales/en-US/chrome/dom/dom.properties
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/tests/chrome/Makefile.in
js/xpconnect/tests/chrome/test_bug795275.xul
js/xpconnect/tests/mochitest/Makefile.in
js/xpconnect/tests/mochitest/file_bug795275.html
js/xpconnect/tests/mochitest/file_bug795275.xml
--- a/content/base/public/nsDeprecatedOperationList.h
+++ b/content/base/public/nsDeprecatedOperationList.h
@@ -42,8 +42,9 @@ DEPRECATED_OPERATION(EnablePrivilege)
 DEPRECATED_OPERATION(Position)
 DEPRECATED_OPERATION(TotalSize)
 DEPRECATED_OPERATION(InputEncoding)
 DEPRECATED_OPERATION(MozBeforePaint)
 DEPRECATED_OPERATION(DOMExceptionCode)
 DEPRECATED_OPERATION(NoExposedProps)
 DEPRECATED_OPERATION(MutationEvent)
 DEPRECATED_OPERATION(MozSlice)
+DEPRECATED_OPERATION(Components)
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -127,8 +127,10 @@ MediaLoadDecodeError=Media resource %S c
 # LOCALIZATION NOTE: Do not translate "DOMException", "code" and "name"
 DOMExceptionCodeWarning=Use of DOMException's code attribute is deprecated. Use name instead.
 # LOCALIZATION NOTE: Do not translate "__exposedProps__"
 NoExposedPropsWarning=Exposing chrome JS objects to content without __exposedProps__ is insecure and deprecated. See https://developer.mozilla.org/en/XPConnect_wrappers for more information.
 # LOCALIZATION NOTE: Do not translate "Mutation Event" and "MutationObserver"
 MutationEventWarning=Use of Mutation Events is deprecated. Use MutationObserver instead.
 # LOCALIZATION NOTE: Do not translate "Blob", "mozSlice", or "slice"
 MozSliceWarning=Use of mozSlice on the Blob object is deprecated.  Use slice instead.
+# LOCALIZATION NOTE: Do not translate "Components"
+ComponentsWarning=The Components object is deprecated. It will soon be removed.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -4769,16 +4769,38 @@ nsXPCComponents::SetProperty(nsIXPConnec
 
     return NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN;
 }
 
 static JSBool
 ContentComponentsGetterOp(JSContext *cx, JSHandleObject obj, JSHandleId id,
                           JSMutableHandleValue vp)
 {
+    // If chrome is accessing the Components object of content, allow.
+    MOZ_ASSERT(nsContentUtils::GetCurrentJSContext() == cx);
+    if (nsContentUtils::IsCallerChrome())
+        return true;
+
+    // If the caller is XBL, this is ok.
+    if (AccessCheck::callerIsXBL(cx))
+        return true;
+
+    // Warn once. Note that if somebody does window.Components we may have an
+    // outer window here.
+    MOZ_ASSERT(JS_GetGlobalForObject(cx, obj) == JS_ObjectToInnerObject(cx, obj));
+    JSAutoCompartment ac(cx, obj);
+    nsCOMPtr<nsPIDOMWindow> win =
+        do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(cx, obj));
+    if (win) {
+        nsCOMPtr<nsIDocument> doc =
+            do_QueryInterface(win->GetExtantDocument());
+        if (doc)
+            doc->WarnOnceAbout(nsIDocument::eComponents, /* asError = */ true);
+    }
+
     return true;
 }
 
 // static
 JSBool
 nsXPCComponents::AttachComponentsObject(XPCCallContext& ccx,
                                         XPCWrappedNativeScope* aScope,
                                         JSObject* aTarget)
--- a/js/xpconnect/tests/chrome/Makefile.in
+++ b/js/xpconnect/tests/chrome/Makefile.in
@@ -34,16 +34,17 @@ MOCHITEST_CHROME_FILES = \
 		test_bug726949.xul \
 		test_bug738244.xul \
 		test_bug743843.xul \
 		test_bug760076.xul \
 		test_bug760109.xul \
 		test_bug763343.xul \
 		test_bug771429.xul \
 		test_bug773962.xul \
+		test_bug795275.xul \
 		test_APIExposer.xul \
 		test_chrometoSource.xul \
 		outoflinexulscript.js \
 		subscript.js \
 		test_cows.xul \
 		test_documentdomain.xul \
 		test_doublewrappedcompartments.xul \
 		test_evalInSandbox.xul \
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/chrome/test_bug795275.xul
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=795275
+-->
+<window title="Mozilla Bug 795275"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=795275"
+     target="_blank">Mozilla Bug 795275</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+  /** Test for Warning in content scopes about Components. **/
+
+  SimpleTest.waitForExplicitFinish();
+
+  // Set up our console listener.
+  var gWarnings = 0;
+  function onWarning(consoleMessage) {
+    if (/soon be removed/.test(consoleMessage.message))
+      gWarnings++;
+  }
+  var gListener = {
+    observe: onWarning,
+    QueryInterface: function (iid) {
+      if (!iid.equals(Components.interfaces.nsIConsoleListener) &&
+          !iid.equals(Components.interfaces.nsISupports)) {
+        throw Components.results.NS_ERROR_NO_INTERFACE;
+      }
+      return this;
+    }
+  };
+  var gConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
+                                  .getService(Components.interfaces.nsIConsoleService);
+  gConsoleService.registerListener(gListener);
+
+  // Wait for all four child frame to load.
+  var gLoadCount = 0;
+  function frameLoaded() {
+    if (++gLoadCount == document.getElementsByTagName('iframe').length)
+      go();
+  }
+
+  function getWin(id) { return document.getElementById(id).contentWindow.wrappedJSObject; }
+  function go() {
+    getWin('frame1').touchComponents();
+    getWin('frame2').touchInterfaces();
+    getWin('frame3').touchLookupMethod();
+    getWin('frame4').touchComponents();
+    getWin('frame4').touchInterfaces();
+    getWin('frame4').touchLookupMethod();
+    // This shouldn't warn.
+    getWin('frame5').touchViaXBL();
+
+    // Warnings are dispatched async, so stick ourselves at the end of the event
+    // queue.
+    setTimeout(done, 0);
+  }
+
+  function done() {
+    gConsoleService.unregisterListener(gListener);
+    is(gWarnings, 4, "Got the right number of warnings");
+    SimpleTest.finish();
+  }
+
+  ]]>
+
+  </script>
+  <iframe id="frame1" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame2" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame3" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame4" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+  <iframe id="frame5" onload="frameLoaded();" type="content" src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_bug795275.html" />
+
+</window>
--- a/js/xpconnect/tests/mochitest/Makefile.in
+++ b/js/xpconnect/tests/mochitest/Makefile.in
@@ -62,16 +62,18 @@ MOCHITEST_FILES =	bug500931_helper.html 
 		file_bug706301.html \
 		test_bug745483.html \
 		file_bug760131.html \
 		test_bug764389.html \
 		test_bug772288.html \
 		test_bug781476.html \
 		file_bug781476.html \
 		test_bug789713.html \
+		file_bug795275.html \
+		file_bug795275.xml \
 		file_nodelists.html \
 		file_exnstack.html \
 		file_expandosharing.html \
 		file_empty.html \
 		file_documentdomain.html \
 		test_lookupMethod.html \
 		file_bug738244.html \
 		file_mozMatchesSelector.html \
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug795275.html
@@ -0,0 +1,31 @@
+<html>
+<head>
+<style>
+  .bound {
+    -moz-binding: url(file_bug795275.xml#xbltest);
+  }
+</style>
+<script type="application/javascript">
+  function touchComponents() {
+    Components;
+  }
+  function touchInterfaces() {
+    Components.interfaces;
+  }
+  function touchLookupMethod() {
+    Components.lookupMethod(document, 'getElementById');
+  }
+
+  function touchViaXBL() {
+    // Make sure none of this warns.
+    var div = document.getElementById('dummy');
+    div.testProp;
+    div.testMethod();
+  }
+
+</script>
+</head>
+<body>
+<div id="dummy" class="bound"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/mochitest/file_bug795275.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<bindings id="xbltestBindings" xmlns="http://www.mozilla.org/xbl"
+          xmlns:html="http://www.w3.org/1999/xhtml">
+<binding id="xbltest">
+<implementation>
+<method name="testMethod">
+<body>
+  Components.interfaces;
+</body>
+</method>
+<property name="testProp" readonly="true"
+          onget="Components; return 3;" />
+<constructor>
+  var foo = Components;
+</constructor>
+</implementation>
+</binding>
+</bindings>