Bug 1618011 part 4. Pass a BindingCallContext to dictionary Init() methods. r=peterv

Dictionaries always need a BindingCallContext, because they can throw
MSG_NOT_DICTIONARY from Init().

We allow non-binding callsites to pass JSContext*, in which case they will not
get quite-as-nice error reporting.

Differential Revision: https://phabricator.services.mozilla.com/D64885

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2020-03-06 20:30:52 +00:00
Родитель 8cc6fcde91
Коммит 242fd385c0
3 изменённых файлов: 30 добавлений и 6 удалений

Просмотреть файл

@ -21,6 +21,7 @@
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/TimingParams.h"
#include "mozilla/dom/BaseKeyframeTypesBinding.h" // For FastBaseKeyframe etc.
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/Document.h" // For Document::AreWebAnimationsImplicitKeyframesEnabled
#include "mozilla/dom/Element.h"
#include "mozilla/dom/KeyframeEffect.h" // For PropertyValuesPair etc.
@ -421,7 +422,8 @@ static bool ConvertKeyframeSequence(JSContext* aCx, dom::Document* aDocument,
// Convert the JS value into a BaseKeyframe dictionary value.
dom::binding_detail::FastBaseKeyframe keyframeDict;
if (!keyframeDict.Init(aCx, value,
BindingCallContext callCx(aCx, aContext);
if (!keyframeDict.Init(callCx, value,
"Element of sequence<Keyframe> argument")) {
// This may happen if the value type of the member of BaseKeyframe is
// invalid. e.g. `offset` only accept a double value, so if we provide a
@ -993,8 +995,8 @@ static void GetKeyframeListFromPropertyIndexedKeyframe(
// Convert the object to a property-indexed keyframe dictionary to
// get its explicit dictionary members.
dom::binding_detail::FastBasePropertyIndexedKeyframe keyframeDict;
if (!keyframeDict.Init(aCx, aValue, "BasePropertyIndexedKeyframe argument",
false)) {
// XXXbz Pass in the method name from callers and set up a BindingCallContext?
if (!keyframeDict.Init(aCx, aValue, "BasePropertyIndexedKeyframe argument")) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}

Просмотреть файл

@ -14177,7 +14177,26 @@ class CGDictionary(CGThing):
body += "return true;\n"
return ClassMethod("Init", "bool", [
Argument('JSContext*', 'cx'),
Argument('BindingCallContext&', 'cx'),
Argument('JS::Handle<JS::Value>', 'val'),
Argument('const char*', 'sourceDescription', default='"Value"'),
Argument('bool', 'passedToJSImpl', default='false')
], body=body)
def initWithoutCallContextMethod(self):
"""
This function outputs the body of an Init() method for the dictionary
that takes just a JSContext*. This is needed for non-binding consumers.
"""
body = dedent(
"""
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
""")
return ClassMethod("Init", "bool", [
Argument('JSContext*', 'cx_'),
Argument('JS::Handle<JS::Value>', 'val'),
Argument('const char*', 'sourceDescription', default='"Value"'),
Argument('bool', 'passedToJSImpl', default='false')
@ -14475,7 +14494,7 @@ class CGDictionary(CGThing):
baseConstructors = None
if d.needsConversionFromJS:
initArgs = "nullptr, JS::NullHandleValue",
initArgs = "nullptr, JS::NullHandleValue"
else:
initArgs =""
ctors = [
@ -14501,6 +14520,7 @@ class CGDictionary(CGThing):
if d.needsConversionFromJS:
methods.append(self.initMethod())
methods.append(self.initWithoutCallContextMethod())
else:
methods.append(self.simpleInitMethod())

Просмотреть файл

@ -31,6 +31,7 @@
#include "xpc_make_class.h"
#include "XPCWrapper.h"
#include "Crypto.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/cache/CacheStorage.h"
@ -305,8 +306,9 @@ static bool SandboxFetch(JSContext* cx, JS::HandleObject scope,
return false;
}
RootedDictionary<dom::RequestInit> options(cx);
BindingCallContext callCx(cx, "fetch");
if (!options.Init(cx, args.hasDefined(1) ? args[1] : JS::NullHandleValue,
"Argument 2 of fetch", false)) {
"Argument 2", false)) {
return false;
}
nsCOMPtr<nsIGlobalObject> global = xpc::NativeGlobal(scope);