Bug 1338272 - Require that the return value of MaybeSetPendingException is used. r=peterv
Most of the time, the return value of this method should be checked,
because behavior should depend on whether or not an exception is
thrown. However, if it is called immediately after a throw it doesn't
need to be checked because it will always return true. bz said there
is no public API that lets you assume there is an exception because it
would be "too easy to misuse".
MozReview-Commit-ID: CqyicBbcNjW
--- a/dom/base/WindowNamedPropertiesHandler.cpp
+++ b/dom/base/WindowNamedPropertiesHandler.cpp
@@ -157,17 +157,17 @@ bool
WindowNamedPropertiesHandler::defineProperty(JSContext* aCx,
JS::Handle<JSObject*> aProxy,
JS::Handle<jsid> aId,
JS::Handle<JS::PropertyDescriptor> aDesc,
JS::ObjectOpResult &result) const
{
ErrorResult rv;
rv.ThrowTypeError<MSG_DEFINEPROPERTY_ON_GSP>();
- rv.MaybeSetPendingException(aCx);
+ MOZ_ALWAYS_TRUE(rv.MaybeSetPendingException(aCx));
return false;
}
bool
WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
JS::Handle<JSObject*> aProxy,
unsigned flags,
JS::AutoIdVector& aProps) const
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -5464,17 +5464,17 @@ def getJSToNativeConversionInfo(type, de
if (!JS_WrapValue(cx, &valueToResolve)) {
$*{exceptionCode}
}
binding_detail::FastErrorResult promiseRv;
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(promiseGlobal.GetAsSupports());
if (!global) {
promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
- promiseRv.MaybeSetPendingException(cx);
+ MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
$*{exceptionCode}
}
$${declName} = Promise::Resolve(global, cx, valueToResolve,
promiseRv);
if (promiseRv.MaybeSetPendingException(cx)) {
$*{exceptionCode}
}
}
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -257,16 +257,17 @@ public:
//
// Note that a true return value does NOT mean there is now a pending
// exception on aCx, due to uncatchable exceptions. It should still be
// considered equivalent to a JSAPI failure in terms of what callers should do
// after true is returned.
//
// After this call, the TErrorResult will no longer return true from Failed(),
// since the exception will have moved to the JSContext.
+ MOZ_MUST_USE
bool MaybeSetPendingException(JSContext* cx)
{
WouldReportJSException();
if (!Failed()) {
return false;
}
SetPendingException(cx);
--- a/dom/bindings/ToJSValue.cpp
+++ b/dom/bindings/ToJSValue.cpp
@@ -51,20 +51,18 @@ ToJSValue(JSContext* aCx,
bool
ToJSValue(JSContext* aCx,
ErrorResult& aArgument,
JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(aArgument.Failed());
MOZ_ASSERT(!aArgument.IsUncatchableException(),
"Doesn't make sense to convert uncatchable exception to a JS value!");
- DebugOnly<bool> throwResult = aArgument.MaybeSetPendingException(aCx);
- MOZ_ASSERT(throwResult);
- DebugOnly<bool> getPendingResult = JS_GetPendingException(aCx, aValue);
- MOZ_ASSERT(getPendingResult);
+ MOZ_ALWAYS_TRUE(aArgument.MaybeSetPendingException(aCx));
+ MOZ_ALWAYS_TRUE(JS_GetPendingException(aCx, aValue));
JS_ClearPendingException(aCx);
return true;
}
bool
ToJSValue(JSContext* aCx, Promise& aArgument,
JS::MutableHandle<JS::Value> aValue)
{
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -315,17 +315,17 @@ AccessCheck::reportCrossOriginDenial(JSC
message = NS_LITERAL_CSTRING("Permission denied to ") +
accessType +
NS_LITERAL_CSTRING(" property ") +
NS_ConvertUTF16toUTF8(propName) +
NS_LITERAL_CSTRING(" on cross-origin object");
}
ErrorResult rv;
rv.ThrowDOMException(NS_ERROR_DOM_SECURITY_ERR, message);
- rv.MaybeSetPendingException(cx);
+ MOZ_ALWAYS_TRUE(rv.MaybeSetPendingException(cx));
}
enum Access { READ = (1<<0), WRITE = (1<<1), NO_ACCESS = 0 };
static void
EnterAndThrowASCII(JSContext* cx, JSObject* wrapper, const char* msg)
{
JSAutoCompartment ac(cx, wrapper);