mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 890576 - Disallow resumption values in onNewGlobalObject hooks. r=jimb
This commit is contained in:
parent
7e75c28488
commit
1bf232fd00
@ -1,4 +1,4 @@
|
||||
// Resumption values from onNewGlobalObject handlers are respected.
|
||||
// Resumption values from onNewGlobalObject handlers are disallowed.
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
||||
@ -10,18 +10,25 @@ log = '';
|
||||
assertEq(typeof newGlobal(), "object");
|
||||
assertEq(log, 'n');
|
||||
|
||||
// For onNewGlobalObject, { return: V } resumption values are treated like
|
||||
// 'undefined': the new global is still returned.
|
||||
dbg.uncaughtExceptionHook = function (ex) { assertEq(/disallowed/.test(ex), true); log += 'u'; }
|
||||
dbg.onNewGlobalObject = function (g) { log += 'n'; return { return: "snoo" }; };
|
||||
log = '';
|
||||
assertEq(typeof newGlobal(), "object");
|
||||
assertEq(log, 'n');
|
||||
assertEq(log, 'nu');
|
||||
|
||||
dbg.onNewGlobalObject = function (g) { log += 'n'; return { throw: "snoo" }; };
|
||||
log = '';
|
||||
assertThrowsValue(function () { newGlobal(); }, "snoo");
|
||||
assertEq(log, 'n');
|
||||
assertEq(typeof newGlobal(), "object");
|
||||
assertEq(log, 'nu');
|
||||
|
||||
dbg.onNewGlobalObject = function (g) { log += 'n'; return null; };
|
||||
log = '';
|
||||
assertEq(evaluate('newGlobal();', { catchTermination: true }), "terminated");
|
||||
assertEq(typeof newGlobal(), "object");
|
||||
assertEq(log, 'nu');
|
||||
|
||||
dbg.uncaughtExceptionHook = function (ex) { assertEq(/foopy/.test(ex), true); log += 'u'; }
|
||||
dbg.onNewGlobalObject = function (g) { log += 'n'; throw "foopy"; };
|
||||
log = '';
|
||||
assertEq(typeof newGlobal(), "object");
|
||||
assertEq(log, 'nu');
|
||||
|
||||
|
@ -16,8 +16,12 @@ dbg1.onNewGlobalObject = dbg2.onNewGlobalObject = dbg3.onNewGlobalObject = funct
|
||||
return { throw: "snoo" };
|
||||
return undefined;
|
||||
};
|
||||
dbg2.uncaughtExceptionHook = function (exn) {
|
||||
assertEq(/disallowed/.test(exn), true);
|
||||
log += 'u';
|
||||
};
|
||||
|
||||
log = '';
|
||||
count = 0;
|
||||
assertThrowsValue(function () { newGlobal(); }, "snoo");
|
||||
assertEq(log, '12');
|
||||
assertEq(typeof newGlobal(), "object");
|
||||
assertEq(log, '12u3');
|
||||
|
@ -316,7 +316,7 @@ MSG_DEF(JSMSG_SC_RECURSION, 262, 0, JSEXN_INTERNALERR, "recursive obje
|
||||
MSG_DEF(JSMSG_UNUSED263, 263, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version")
|
||||
MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object")
|
||||
MSG_DEF(JSMSG_UNUSED266, 266, 0, JSEXN_NONE, "")
|
||||
MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 266, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook")
|
||||
MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function")
|
||||
MSG_DEF(JSMSG_INVALID_FOR_IN_INIT, 268, 0, JSEXN_SYNTAXERR, "for-in loop let declaration may not have an initializer")
|
||||
MSG_DEF(JSMSG_CLEARED_SCOPE, 269, 0, JSEXN_TYPEERR, "attempt to run compile-and-go script on a cleared scope")
|
||||
|
@ -1312,8 +1312,27 @@ Debugger::fireNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global, Muta
|
||||
return handleUncaughtException(ac, false);
|
||||
|
||||
RootedValue rv(cx);
|
||||
|
||||
// onNewGlobalObject is infallible, and thus is only allowed to return
|
||||
// undefined as a resumption value. If it returns anything else, we throw.
|
||||
// And if that happens, or if the hook itself throws, we invoke the
|
||||
// uncaughtExceptionHook so that we never leave an exception pending on the
|
||||
// cx. This allows JS_NewGlobalObject to avoid handling failures from debugger
|
||||
// hooks.
|
||||
bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, argv, &rv);
|
||||
return parseResumptionValue(ac, ok, rv, vp);
|
||||
if (ok && !rv.isUndefined()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED);
|
||||
ok = false;
|
||||
}
|
||||
// NB: Even though we don't care about what goes into it, we have to pass vp
|
||||
// to handleUncaughtException so that it parses resumption values from the
|
||||
// uncaughtExceptionHook and tells the caller whether we should execute the
|
||||
// rest of the onNewGlobalObject hooks or not.
|
||||
JSTrapStatus status = ok ? JSTRAP_CONTINUE
|
||||
: handleUncaughtException(ac, vp, true);
|
||||
JS_ASSERT(!cx->isExceptionPending());
|
||||
return status;
|
||||
}
|
||||
|
||||
bool
|
||||
|
Loading…
Reference in New Issue
Block a user