Bug 1042436 - Warn once to the console when XrayWrappers deny access to an object. r=gabor,sr=smaug

This commit is contained in:
Bobby Holley 2014-08-06 23:32:23 -04:00
parent d0d73ae49a
commit f092ba49ba
4 changed files with 113 additions and 5 deletions

View File

@ -3587,6 +3587,7 @@ public:
, forcePermissiveCOWs(false)
, adoptedNode(false)
, donatedNode(false)
, warnedAboutXrays(false)
, scriptability(c)
, scope(nullptr)
{
@ -3642,6 +3643,10 @@ public:
bool adoptedNode;
bool donatedNode;
// Whether we've emitted a warning about a property that was filtered out
// by XrayWrappers. See XrayWrapper.cpp.
bool warnedAboutXrays;
// The scriptability of this compartment.
Scriptability scriptability;

View File

@ -63,6 +63,7 @@ skip-if = buildapp == 'mulet'
[test_bug932906.xul]
[test_bug996069.xul]
[test_bug1041626.xul]
[test_bug1042436.xul]
[test_xrayToJS.xul]
skip-if = buildapp == 'mulet'
[test_chrometoSource.xul]

View File

@ -0,0 +1,49 @@
<?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=1042436
-->
<window title="Mozilla Bug 1042436"
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=1042436"
target="_blank">Mozilla Bug 1042436</a>
</body>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
/** Test for Bug 1042436 **/
SimpleTest.waitForExplicitFinish();
const Cu = Components.utils;
var contentSb = Cu.Sandbox('http://www.example.com');
var nonXrayableObj = new contentSb.WeakMap();
nonXrayableObj.wrappedJSObject.someExpandoProperty = 42;
nonXrayableObj.wrappedJSObject.someOtherExpandoProperty = 52;
SimpleTest.expectConsoleMessages(function() {
nonXrayableObj.someExpandoProperty;
nonXrayableObj.someOtherExpandoProperty;
var chromeSb = Cu.Sandbox(this);
var contentObjWithGetter = contentSb.eval('({ get getterProp() {return 42;}, valueProp: 42 })');
is(contentObjWithGetter.wrappedJSObject.getterProp, 42, "Getter prop set up correctly");
is(contentObjWithGetter.getterProp, undefined, "Xrays work right");
is(contentObjWithGetter.valueProp, 42, "Getter prop set up correctly");
chromeSb.contentObjWithGetter = contentObjWithGetter;
Cu.evalInSandbox('contentObjWithGetter.getterProp; contentObjWithGetter.valueProp; contentObjWithGetter.getterProp;',
chromeSb, "1.7", "http://phony.example.com/file.js", 99);
},
[{ errorMessage: /property someExpandoProperty \(reason: object is not safely Xrayable/, sourceName: /test_bug1042436/, isWarning: true },
{ errorMessage: /property getterProp \(reason: property has accessor/, sourceName: /phony/, lineNumber: 99, isWarning: true } ],
SimpleTest.finish.bind(SimpleTest));
]]>
</script>
</window>

View File

@ -10,6 +10,7 @@
#include "nsIContent.h"
#include "nsIControllers.h"
#include "nsIScriptError.h"
#include "mozilla/dom/Element.h"
#include "nsContentUtils.h"
@ -576,17 +577,69 @@ public:
bool
SilentFailure(JSContext *cx, HandleId id, const char *reason)
{
#ifdef DEBUG
nsAutoJSString name;
if (!name.init(cx, id))
CompartmentPrivate *priv = CompartmentPrivate::Get(CurrentGlobalOrNull(cx));
bool alreadyWarnedOnce = priv->warnedAboutXrays;
priv->warnedAboutXrays = true;
// The browser console warning is only emitted for the first violation,
// whereas the (debug-only) NS_WARNING is emitted for each violation.
#ifndef DEBUG
if (alreadyWarnedOnce)
return true;
#endif
nsAutoJSString propertyName;
if (!propertyName.init(cx, id))
return false;
AutoFilename filename;
unsigned line = 0;
DescribeScriptedCaller(cx, &filename, &line);
// Warn to the terminal for the logs.
NS_WARNING(nsPrintfCString("Silently denied access to property |%s|: %s (@%s:%u)",
NS_LossyConvertUTF16toASCII(name).get(), reason,
NS_LossyConvertUTF16toASCII(propertyName).get(), reason,
filename.get(), line).get());
#endif
// If this isn't the first warning on this topic for this global, we've
// already bailed out in opt builds. Now that the NS_WARNING is done, bail
// out in debug builds as well.
if (alreadyWarnedOnce)
return true;
//
// Log a message to the console service.
//
// Grab the pieces.
nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
NS_ENSURE_TRUE(consoleService, true);
nsCOMPtr<nsIScriptError> errorObject = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
NS_ENSURE_TRUE(errorObject, true);
// Compute the current window id if any.
uint64_t windowId = 0;
nsGlobalWindow *win = WindowGlobalOrNull(CurrentGlobalOrNull(cx));
if (win)
windowId = win->WindowID();
nsPrintfCString errorMessage("XrayWrapper denied access to property %s (reason: %s). "
"See https://developer.mozilla.org/en-US/docs/Xray_vision "
"for more information. Note that only the first denied "
"property access from a given global object will be reported.",
NS_LossyConvertUTF16toASCII(propertyName).get(),
reason);
nsString filenameStr(NS_ConvertASCIItoUTF16(filename.get()));
nsresult rv = errorObject->InitWithWindowID(NS_ConvertASCIItoUTF16(errorMessage),
filenameStr,
EmptyString(),
line, 0,
nsIScriptError::warningFlag,
"XPConnect",
windowId);
NS_ENSURE_SUCCESS(rv, true);
rv = consoleService->LogMessage(errorObject);
NS_ENSURE_SUCCESS(rv, true);
return true;
}