Bug 1113685 - Report the right name when calling selfhosted functions on incompatible objects. r=till

This commit is contained in:
Tom Schuster 2016-02-10 18:20:12 +01:00
parent 538efc0f46
commit 7cf72748c2
6 changed files with 52 additions and 3 deletions

View File

@ -0,0 +1,9 @@
load(libdir + "asserts.js");
assertTypeErrorMessage(() => WeakSet.prototype.add.call({}), "add method called on incompatible Object");
assertTypeErrorMessage(() => newGlobal().WeakSet.prototype.add.call({}), "add method called on incompatible Object");
assertTypeErrorMessage(() => WeakSet.prototype.add.call(15), "add method called on incompatible number");
assertTypeErrorMessage(() => Int8Array.prototype.find.call({}), "find method called on incompatible Object");
assertTypeErrorMessage(() => newGlobal().Int8Array.prototype.find.call({}), "find method called on incompatible Object");
assertTypeErrorMessage(() => Int8Array.prototype.find.call(15), "find method called on incompatible number");

View File

@ -7,7 +7,7 @@ function TestArrayIteratorPrototypeConfusion() {
throw new Error("Call did not throw");
} catch (e) {
assertEq(e instanceof TypeError, true);
assertEq(e.message, "CallArrayIteratorMethodIfWrapped method called on incompatible Array Iterator");
assertEq(e.message, "next method called on incompatible Array Iterator");
}
}
TestArrayIteratorPrototypeConfusion();

View File

@ -7,7 +7,7 @@ function TestStringIteratorPrototypeConfusion() {
throw new Error("Call did not throw");
} catch (e) {
assertEq(e instanceof TypeError, true);
assertEq(e.message, "CallStringIteratorMethodIfWrapped method called on incompatible String Iterator");
assertEq(e.message, "next method called on incompatible String Iterator");
}
}
TestStringIteratorPrototypeConfusion();

View File

@ -11,6 +11,7 @@
#include "proxy/Proxy.h"
#include "vm/ProxyObject.h"
#include "vm/SelfHosting.h"
using namespace js;
@ -27,6 +28,9 @@ JS::detail::CallMethodIfWrapped(JSContext* cx, IsAcceptableThis test, NativeImpl
return Proxy::nativeCall(cx, test, impl, args);
}
if (IsCallSelfHostedNonGenericMethod(impl))
return ReportIncompatibleSelfHostedMethod(cx, args);
ReportIncompatible(cx, args);
return false;
}

View File

@ -1382,6 +1382,34 @@ CallNonGenericSelfhostedMethod(JSContext* cx, unsigned argc, Value* vp)
return CallNonGenericMethod<Test, CallSelfHostedNonGenericMethod>(cx, args);
}
bool
js::IsCallSelfHostedNonGenericMethod(NativeImpl impl)
{
return impl == CallSelfHostedNonGenericMethod;
}
bool
js::ReportIncompatibleSelfHostedMethod(JSContext* cx, const CallArgs& args)
{
// The contract for this function is the same as CallSelfHostedNonGenericMethod.
// The normal ReportIncompatible function doesn't work for selfhosted functions,
// because they always call the different CallXXXMethodIfWrapped methods,
// which would be reported as the called function instead.
// Lookup the selfhosted method that was invoked.
ScriptFrameIter iter(cx);
MOZ_ASSERT(iter.isFunctionFrame());
JSAutoByteString funNameBytes;
if (const char* funName = GetFunctionNameBytes(cx, iter.callee(cx), &funNameBytes)) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
funName, "method", InformalValueTypeName(args.thisv()));
}
return false;
}
/**
* Returns the default locale as a well-formed, but not necessarily canonicalized,
* BCP-47 language tag.

View File

@ -8,6 +8,7 @@
#define vm_SelfHosting_h_
#include "jsapi.h"
#include "NamespaceImports.h"
class JSAtom;
@ -17,7 +18,14 @@ namespace js {
* Check whether the given JSFunction is a self-hosted function whose
* self-hosted name is the given name.
*/
bool IsSelfHostedFunctionWithName(JSFunction* fun, JSAtom* name);
bool
IsSelfHostedFunctionWithName(JSFunction* fun, JSAtom* name);
bool
IsCallSelfHostedNonGenericMethod(NativeImpl impl);
bool
ReportIncompatibleSelfHostedMethod(JSContext* cx, const CallArgs& args);
/* Get the compile options used when compiling self hosted code. */
void