зеркало из https://github.com/mozilla/gecko-dev.git
Bug 437361. Propagate exceptions from showModalDialog's guts to script as needed instead of dropping them on the floor. r+sr=bzbarsky
This commit is contained in:
Родитель
d750ddc25d
Коммит
198f21c6c3
|
@ -6050,24 +6050,26 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs,
|
|||
PR_FALSE, // aDialog
|
||||
PR_TRUE, // aContentModal
|
||||
PR_TRUE, // aCalledNoScript
|
||||
PR_FALSE, // aDoJSFixups
|
||||
PR_TRUE, // aDoJSFixups
|
||||
nsnull, aArgs, // args
|
||||
GetPrincipal(), // aCalleePrincipal
|
||||
nsnull, // aJSCallerContext
|
||||
getter_AddRefs(dlgWin));
|
||||
if (NS_FAILED(rv) || !dlgWin)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(dlgWin));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (dlgWin) {
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(dlgWin));
|
||||
|
||||
nsPIDOMWindow *inner = win->GetCurrentInnerWindow();
|
||||
nsPIDOMWindow *inner = win->GetCurrentInnerWindow();
|
||||
|
||||
nsCOMPtr<nsIDOMModalContentWindow> dlgInner(do_QueryInterface(inner));
|
||||
nsCOMPtr<nsIDOMModalContentWindow> dlgInner(do_QueryInterface(inner));
|
||||
|
||||
if (dlgInner) {
|
||||
dlgInner->GetReturnValue(aRetVal);
|
||||
if (dlgInner) {
|
||||
dlgInner->GetReturnValue(aRetVal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -7292,8 +7294,6 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
"Can't pass in arguments both ways");
|
||||
NS_PRECONDITION(!aCalledNoScript || (!argv && argc == 0),
|
||||
"Can't pass JS args when called via the noscript methods");
|
||||
NS_PRECONDITION(!aDoJSFixups || !aCalledNoScript,
|
||||
"JS fixups should not be done when called noscript");
|
||||
NS_PRECONDITION(!aJSCallerContext || !aCalledNoScript,
|
||||
"Shouldn't have caller context when called noscript");
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ _TEST_FILES = \
|
|||
iframe_bug430276-2.html \
|
||||
test_bug440572.html \
|
||||
iframe_bug440572.html \
|
||||
test_bug437361.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=437361
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 437361</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/mozprefs.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 437361 **/
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
function testModalDialogBlockedCleanly() {
|
||||
is(true, pref("dom.disable_open_during_load"), "mozprefs sanity check");
|
||||
var rv = window.showModalDialog( // should be blocked without exception
|
||||
"data:text/html,<html><body onload='close(); returnValue = 1;' /></html>");
|
||||
is(rv, null, "Modal dialog opened unexpectedly.");
|
||||
}
|
||||
|
||||
function testModalDialogAllowed() {
|
||||
is(false, pref("dom.disable_open_during_load"), "mozprefs sanity check");
|
||||
var rv = window.showModalDialog( // should not be blocked this time
|
||||
"data:text/html,<html><body onload='close(); returnValue = 1;' /></html>");
|
||||
is(rv, 1, "Problem with modal dialog returnValue.");
|
||||
}
|
||||
|
||||
function testOtherExceptionsNotTrapped() {
|
||||
is(false, pref("dom.disable_open_during_load"), "mozprefs sanity check");
|
||||
window.showModalDialog('about:config'); // forbidden by SecurityCheckURL
|
||||
}
|
||||
|
||||
function test(disableOpen, exceptionExpected, testFn, errorMsg) {
|
||||
try {
|
||||
pref("dom.disable_open_during_load", disableOpen, testFn);
|
||||
ok(!exceptionExpected, errorMsg);
|
||||
} catch (_) {
|
||||
ok(exceptionExpected, errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
test(true, false, testModalDialogBlockedCleanly,
|
||||
"Blocked showModalDialog caused an exception.");
|
||||
|
||||
test(false, false, testModalDialogAllowed,
|
||||
"showModalDialog was blocked even though dom.disable_open_during_load was false.");
|
||||
|
||||
test(false, true, testOtherExceptionsNotTrapped,
|
||||
"Incorrectly suppressed insecure showModalDialog exception.");
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=437361">Mozilla Bug 437361</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -69,6 +69,7 @@ _SERV_FILES = \
|
|||
redirect.js \
|
||||
$(topsrcdir)/build/pgo/server-locations.txt \
|
||||
$(topsrcdir)/netwerk/test/httpserver/httpd.js \
|
||||
mozprefs.js \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
(function() {
|
||||
|
||||
// NOTE: You *must* also include this line in any test that uses this file:
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
|
||||
function determinePrefKind(branch, prefName) {
|
||||
switch (branch.getPrefType(prefName)) {
|
||||
case branch.PREF_STRING: return "CharPref";
|
||||
case branch.PREF_INT: return "IntPref";
|
||||
case branch.PREF_BOOL: return "BoolPref";
|
||||
default: /* PREF_INVALID */ return "ComplexValue";
|
||||
}
|
||||
}
|
||||
|
||||
function memoize(fn, obj) {
|
||||
var cache = {}, sep = '___',
|
||||
join = Array.prototype.join;
|
||||
return function() {
|
||||
var key = join.call(arguments, sep);
|
||||
if (!(key in cache))
|
||||
cache[key] = fn.apply(obj, arguments);
|
||||
return cache[key];
|
||||
};
|
||||
}
|
||||
|
||||
var makeAccessor = memoize(function(pref) {
|
||||
var splat = pref.split('.'),
|
||||
basePref = splat.pop(),
|
||||
branch, kind;
|
||||
|
||||
try {
|
||||
branch = prefService.getBranch(splat.join('.') + '.')
|
||||
} catch (e) {
|
||||
alert("Calling prefService.getBranch failed: " +
|
||||
"did you read the NOTE in mozprefs.js?");
|
||||
throw e;
|
||||
}
|
||||
|
||||
kind = determinePrefKind(branch, basePref);
|
||||
|
||||
return function(value) {
|
||||
var oldValue = branch['get' + kind](basePref);
|
||||
if (arguments.length > 0)
|
||||
branch['set' + kind](basePref, value);
|
||||
return oldValue;
|
||||
};
|
||||
});
|
||||
|
||||
/* function pref(name[, value[, fn[, obj]]])
|
||||
* -----------------------------------------
|
||||
* Use cases:
|
||||
*
|
||||
* 1. Get the value of the dom.disable_open_during_load preference:
|
||||
*
|
||||
* pref('dom.disable_open_during_load')
|
||||
*
|
||||
* 2. Set the preference to true, returning the old value:
|
||||
*
|
||||
* var oldValue = pref('dom.disable_open_during_load', true);
|
||||
*
|
||||
* 3. Set the value of the preference to true just for the duration
|
||||
* of the specified function's execution:
|
||||
*
|
||||
* pref('dom.disable_open_during_load', true, function() {
|
||||
* window.open(this.getUrl()); // fails if still loading
|
||||
* }, this); // for convenience, allow binding
|
||||
*
|
||||
* Rationale: Unless a great deal of care is taken to catch all
|
||||
* exceptions and restore original preference values,
|
||||
* manually setting & restoring preferences can lead
|
||||
* to unpredictable test behavior. The try-finally
|
||||
* block below eliminates that risk.
|
||||
*/
|
||||
function pref(name, /*optional:*/ value, fn, obj) {
|
||||
var acc = makeAccessor(name);
|
||||
switch (arguments.length) {
|
||||
case 1: return acc();
|
||||
case 2: return acc(value);
|
||||
default:
|
||||
var oldValue = acc(value),
|
||||
extra_args = [].slice.call(arguments, 4);
|
||||
try { return fn.apply(obj, extra_args) }
|
||||
finally { acc(oldValue) } // reset no matter what
|
||||
}
|
||||
};
|
||||
|
||||
window.pref = pref; // export
|
||||
|
||||
})();
|
Загрузка…
Ссылка в новой задаче