mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1173593. Make it possible to throw TypeError (or, in fact, any other Error from the content compartment) from js-implemented webidl. r=bholley
This commit is contained in:
parent
ba58ba4578
commit
0d146ab622
@ -34,8 +34,6 @@
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/DOMErrorBinding.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/HTMLObjectElement.h"
|
||||
#include "mozilla/dom/HTMLObjectElementBinding.h"
|
||||
@ -284,26 +282,16 @@ ErrorResult::ReportJSExceptionFromJSImplementation(JSContext* aCx)
|
||||
MOZ_ASSERT(!mMightHaveUnreportedJSException,
|
||||
"Why didn't you tell us you planned to handle JS exceptions?");
|
||||
|
||||
dom::DOMException* domException;
|
||||
nsresult rv =
|
||||
UNWRAP_OBJECT(DOMException, &mJSException.toObject(), domException);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Check for a DOMError, since we convert that into an Error in the content
|
||||
// compartment. We can probably remove that now; see bug 1174954.
|
||||
dom::DOMError* domError;
|
||||
nsresult rv = UNWRAP_OBJECT(DOMError, &mJSException.toObject(), domError);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Just report it.
|
||||
ReportJSException(aCx);
|
||||
return;
|
||||
}
|
||||
|
||||
dom::DOMError* domError;
|
||||
rv = UNWRAP_OBJECT(DOMError, &mJSException.toObject(), domError);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Unwrapping really shouldn't fail here: if mExceptionHandling is set to
|
||||
// eRethrowContentExceptions then the CallSetup destructor only stores an
|
||||
// exception if it unwraps to DOMError or DOMException. If we reach this
|
||||
// then either mExceptionHandling wasn't set to eRethrowContentExceptions
|
||||
// and we shouldn't be calling ReportJSExceptionFromJSImplementation or
|
||||
// something went really wrong.
|
||||
NS_RUNTIMEABORT("We stored a non-DOMError exception!");
|
||||
}
|
||||
|
||||
nsString message;
|
||||
domError->GetMessage(message);
|
||||
|
||||
|
@ -6,10 +6,6 @@
|
||||
|
||||
#include "mozilla/dom/CallbackObject.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/DOMErrorBinding.h"
|
||||
#include "mozilla/dom/DOMException.h"
|
||||
#include "mozilla/dom/DOMExceptionBinding.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIXPConnect.h"
|
||||
@ -224,8 +220,7 @@ CallbackObject::CallSetup::ShouldRethrowException(JS::Handle<JS::Value> aExcepti
|
||||
MOZ_ASSERT(mCompartment);
|
||||
|
||||
// Now we only want to throw an exception to the caller if the object that was
|
||||
// thrown is a DOMError or DOMException object in the caller compartment
|
||||
// (which we stored in mCompartment).
|
||||
// thrown is in the caller compartment (which we stored in mCompartment).
|
||||
|
||||
if (!aException.isObject()) {
|
||||
return false;
|
||||
@ -233,14 +228,7 @@ CallbackObject::CallSetup::ShouldRethrowException(JS::Handle<JS::Value> aExcepti
|
||||
|
||||
JS::Rooted<JSObject*> obj(mCx, &aException.toObject());
|
||||
obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
|
||||
if (js::GetObjectCompartment(obj) != mCompartment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DOMError* domError;
|
||||
DOMException* domException;
|
||||
return NS_SUCCEEDED(UNWRAP_OBJECT(DOMError, obj, domError)) ||
|
||||
NS_SUCCEEDED(UNWRAP_OBJECT(DOMException, obj, domException));
|
||||
return js::GetObjectCompartment(obj) == mCompartment;
|
||||
}
|
||||
|
||||
CallbackObject::CallSetup::~CallSetup()
|
||||
|
@ -73,6 +73,22 @@ TestInterfaceJS.prototype = {
|
||||
"NotSupportedError");
|
||||
},
|
||||
|
||||
testThrowTypeError: function() {
|
||||
throw new this._win.TypeError("We are a TypeError");
|
||||
},
|
||||
|
||||
testThrowCallbackError: function(callback) {
|
||||
callback();
|
||||
},
|
||||
|
||||
testThrowXraySelfHosted: function() {
|
||||
this._win.Array.indexOf();
|
||||
},
|
||||
|
||||
testThrowSelfHosted: function() {
|
||||
Array.indexOf();
|
||||
},
|
||||
|
||||
testPromiseWithThrowingChromePromiseInit: function() {
|
||||
return new this._win.Promise(function() {
|
||||
noSuchMethodExistsYo1();
|
||||
|
@ -51,9 +51,86 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
|
||||
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
|
||||
"Should still have the right file name");
|
||||
is(e.lineNumber, 38, "Should still have the right line number");
|
||||
todo_is(e.columnNumber, 7,
|
||||
"No column number support for DOMException yet");
|
||||
todo_isnot(e.columnNumber, 0,
|
||||
"No column number support for DOMException yet");
|
||||
}
|
||||
|
||||
try {
|
||||
t.testThrowTypeError();
|
||||
} catch (e) {
|
||||
ok(e instanceof TypeError, "Should have a TypeError here");
|
||||
ok(!(e instanceof DOMException), "Should not have DOMException here (2)");
|
||||
ok(!("code" in e), "Should not have a 'code' property (2)");
|
||||
is(e.name, "TypeError", "Should be named TypeError");
|
||||
is(e.message, "We are a TypeError",
|
||||
"Should also have the right message (2)");
|
||||
is(e.stack,
|
||||
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:59:7\n",
|
||||
"Exception stack for TypeError should only show our code");
|
||||
is(e.fileName,
|
||||
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
|
||||
"Should still have the right file name for TypeError");
|
||||
is(e.lineNumber, 59, "Should still have the right line number for TypeError");
|
||||
is(e.columnNumber, 7, "Should have the right column number for TypeError");
|
||||
}
|
||||
|
||||
try {
|
||||
t.testThrowCallbackError(function() { Array.indexOf() });
|
||||
} catch (e) {
|
||||
ok(e instanceof TypeError, "Should have a TypeError here (3)");
|
||||
ok(!(e instanceof DOMException), "Should not have DOMException here (3)");
|
||||
ok(!("code" in e), "Should not have a 'code' property (3)");
|
||||
is(e.name, "TypeError", "Should be named TypeError (3)");
|
||||
is(e.message, "missing argument 0 when calling function Array.indexOf",
|
||||
"Should also have the right message (3)");
|
||||
is(e.stack,
|
||||
"doTest/<@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:78:45\n" +
|
||||
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:78:7\n"
|
||||
,
|
||||
"Exception stack for TypeError should only show our code (3)");
|
||||
is(e.fileName,
|
||||
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
|
||||
"Should still have the right file name for TypeError (3)");
|
||||
is(e.lineNumber, 78, "Should still have the right line number for TypeError (3)");
|
||||
is(e.columnNumber, 45, "Should have the right column number for TypeError (3)");
|
||||
}
|
||||
|
||||
try {
|
||||
t.testThrowXraySelfHosted();
|
||||
} catch (e) {
|
||||
ok(!(e instanceof Error), "Should have an Exception here (4)");
|
||||
ok(!(e instanceof DOMException), "Should not have DOMException here (4)");
|
||||
ok(!("code" in e), "Should not have a 'code' property (4)");
|
||||
is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (4)");
|
||||
is(e.message, "", "Message should be sanitized (5)");
|
||||
is(e.stack,
|
||||
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:99:7\n",
|
||||
"Exception stack for sanitized exception should only show our code (4)");
|
||||
is(e.filename,
|
||||
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
|
||||
"Should still have the right file name for sanitized exception (4)");
|
||||
is(e.lineNumber, 99, "Should still have the right line number for sanitized exception (4)");
|
||||
todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (4)");
|
||||
}
|
||||
|
||||
try {
|
||||
t.testThrowSelfHosted();
|
||||
} catch (e) {
|
||||
ok(!(e instanceof Error), "Should have an Exception here (5)");
|
||||
ok(!(e instanceof DOMException), "Should not have DOMException here (5)");
|
||||
ok(!("code" in e), "Should not have a 'code' property (5)");
|
||||
is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (5)");
|
||||
is(e.message, "", "Message should be sanitized (5)");
|
||||
is(e.stack,
|
||||
"doTest@http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html:117:7\n",
|
||||
"Exception stack for sanitized exception should only show our code (5)");
|
||||
is(e.filename,
|
||||
"http://mochi.test:8888/tests/dom/bindings/test/test_exception_options_from_jsimplemented.html",
|
||||
"Should still have the right file name for sanitized exception (5)");
|
||||
is(e.lineNumber, 117, "Should still have the right line number for sanitized exception (5)");
|
||||
todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (5)");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,18 @@ interface TestInterfaceJS {
|
||||
[Throws]
|
||||
void testThrowDOMException();
|
||||
|
||||
[Throws]
|
||||
void testThrowTypeError();
|
||||
|
||||
[Throws]
|
||||
void testThrowCallbackError(Function callback);
|
||||
|
||||
[Throws]
|
||||
void testThrowXraySelfHosted();
|
||||
|
||||
[Throws]
|
||||
void testThrowSelfHosted();
|
||||
|
||||
// Tests for promise-rejection behavior
|
||||
Promise<void> testPromiseWithThrowingChromePromiseInit();
|
||||
Promise<void> testPromiseWithThrowingContentPromiseInit(PromiseInit func);
|
||||
|
Loading…
Reference in New Issue
Block a user