forked from mirrors/gecko-dev
Bug 1873386 - Interfaces referenced from scriptable members need to be [scriptable] r=necko-reviewers,jschanck,mccr8,valentin
Differential Revision: https://phabricator.services.mozilla.com/D202104
This commit is contained in:
parent
24d759d2a0
commit
392dac6191
9 changed files with 51 additions and 17 deletions
|
|
@ -39,12 +39,14 @@ interface nsIWebAuthnService : nsISupports
|
||||||
// IsUserVerifyingPlatformAuthenticatorAvailable
|
// IsUserVerifyingPlatformAuthenticatorAvailable
|
||||||
readonly attribute boolean isUVPAA;
|
readonly attribute boolean isUVPAA;
|
||||||
|
|
||||||
|
[noscript]
|
||||||
void makeCredential(
|
void makeCredential(
|
||||||
in uint64_t aTransactionId,
|
in uint64_t aTransactionId,
|
||||||
in uint64_t browsingContextId,
|
in uint64_t browsingContextId,
|
||||||
in nsIWebAuthnRegisterArgs args,
|
in nsIWebAuthnRegisterArgs args,
|
||||||
in nsIWebAuthnRegisterPromise promise);
|
in nsIWebAuthnRegisterPromise promise);
|
||||||
|
|
||||||
|
[noscript]
|
||||||
void getAssertion(
|
void getAssertion(
|
||||||
in uint64_t aTransactionId,
|
in uint64_t aTransactionId,
|
||||||
in uint64_t browsingContextId,
|
in uint64_t browsingContextId,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ interface nsIAsyncVerifyRedirectReadyCallback : nsISupports
|
||||||
* Implemented by chrome side of IPC protocols that support redirect responses.
|
* Implemented by chrome side of IPC protocols that support redirect responses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[scriptable, uuid(3ed1d288-5324-46ee-8a98-33ac37d1080b)]
|
[uuid(3ed1d288-5324-46ee-8a98-33ac37d1080b)]
|
||||||
interface nsIParentRedirectingChannel : nsIParentChannel
|
interface nsIParentRedirectingChannel : nsIParentChannel
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ interface nsIStreamTransportService : nsISupports
|
||||||
nsITransport createInputTransport(in nsIInputStream aStream,
|
nsITransport createInputTransport(in nsIInputStream aStream,
|
||||||
in boolean aCloseWhenDone);
|
in boolean aCloseWhenDone);
|
||||||
|
|
||||||
|
[noscript]
|
||||||
void InputAvailable(in nsIInputStream aStream,
|
void InputAvailable(in nsIInputStream aStream,
|
||||||
in nsIInputAvailableCallback aCallback);
|
in nsIInputAvailableCallback aCallback);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ interface nsIUDPSocket : nsISupports
|
||||||
* If it is used off the socket thread there is a risk of triggering a bug
|
* If it is used off the socket thread there is a risk of triggering a bug
|
||||||
* in OS thatcan cause a crash.
|
* in OS thatcan cause a crash.
|
||||||
*/
|
*/
|
||||||
void syncListen(in nsIUDPSocketSyncListener aListener);
|
[noscript] void syncListen(in nsIUDPSocketSyncListener aListener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* connect
|
* connect
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ interface nsICertStorage : nsISupports {
|
||||||
* - STATE_NO_FILTER if there is no (usable) CRLite filter.
|
* - STATE_NO_FILTER if there is no (usable) CRLite filter.
|
||||||
* No lookup is performed in the STATE_NOT_ENROLLED and STATE_NOT_COVERED cases.
|
* No lookup is performed in the STATE_NOT_ENROLLED and STATE_NOT_COVERED cases.
|
||||||
*/
|
*/
|
||||||
[must_use]
|
[must_use, noscript]
|
||||||
short getCRLiteRevocationState(in Array<octet> issuer,
|
short getCRLiteRevocationState(in Array<octet> issuer,
|
||||||
in Array<octet> issuerSPKI,
|
in Array<octet> issuerSPKI,
|
||||||
in Array<octet> serialNumber,
|
in Array<octet> serialNumber,
|
||||||
|
|
@ -203,7 +203,7 @@ interface nsICertStorage : nsISupports {
|
||||||
* this issuer SPKI and serial number is revoked according to the current set of stashed CRLite
|
* this issuer SPKI and serial number is revoked according to the current set of stashed CRLite
|
||||||
* revocation information.
|
* revocation information.
|
||||||
*/
|
*/
|
||||||
[must_use]
|
[must_use, noscript]
|
||||||
boolean isCertRevokedByStash(in Array<octet> issuerSPKI, in Array<octet> serialNumber);
|
boolean isCertRevokedByStash(in Array<octet> issuerSPKI, in Array<octet> serialNumber);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ interface nsIClassInfo : nsISupports
|
||||||
* Return an object to assist XPConnect in supplying JavaScript-specific
|
* Return an object to assist XPConnect in supplying JavaScript-specific
|
||||||
* behavior to callers of the instance object, or null if not needed.
|
* behavior to callers of the instance object, or null if not needed.
|
||||||
*/
|
*/
|
||||||
nsIXPCScriptable getScriptableHelper();
|
[noscript] nsIXPCScriptable getScriptableHelper();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A contract ID through which an instance of this class can be created
|
* A contract ID through which an instance of this class can be created
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ def flags(*flags):
|
||||||
return [flag for flag, cond in flags if cond]
|
return [flag for flag, cond in flags if cond]
|
||||||
|
|
||||||
|
|
||||||
def get_type(type, calltype, iid_is=None, size_is=None):
|
def get_type(type, calltype, iid_is=None, size_is=None, needs_scriptable=None):
|
||||||
while isinstance(type, xpidl.Typedef):
|
while isinstance(type, xpidl.Typedef):
|
||||||
type = type.realtype
|
type = type.realtype
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ def get_type(type, calltype, iid_is=None, size_is=None):
|
||||||
# This allows Arrays of InterfaceIs types to work.
|
# This allows Arrays of InterfaceIs types to work.
|
||||||
return {
|
return {
|
||||||
"tag": "TD_ARRAY",
|
"tag": "TD_ARRAY",
|
||||||
"element": get_type(type.type, calltype, iid_is),
|
"element": get_type(type.type, calltype, iid_is, None, needs_scriptable),
|
||||||
}
|
}
|
||||||
|
|
||||||
if isinstance(type, xpidl.LegacyArray):
|
if isinstance(type, xpidl.LegacyArray):
|
||||||
|
|
@ -72,10 +72,12 @@ def get_type(type, calltype, iid_is=None, size_is=None):
|
||||||
return {
|
return {
|
||||||
"tag": "TD_LEGACY_ARRAY",
|
"tag": "TD_LEGACY_ARRAY",
|
||||||
"size_is": size_is,
|
"size_is": size_is,
|
||||||
"element": get_type(type.type, calltype, iid_is),
|
"element": get_type(type.type, calltype, iid_is, None, needs_scriptable),
|
||||||
}
|
}
|
||||||
|
|
||||||
if isinstance(type, xpidl.Interface) or isinstance(type, xpidl.Forward):
|
if isinstance(type, xpidl.Interface) or isinstance(type, xpidl.Forward):
|
||||||
|
if isinstance(needs_scriptable, set):
|
||||||
|
needs_scriptable.add(type.name)
|
||||||
return {
|
return {
|
||||||
"tag": "TD_INTERFACE_TYPE",
|
"tag": "TD_INTERFACE_TYPE",
|
||||||
"name": type.name,
|
"name": type.name,
|
||||||
|
|
@ -163,6 +165,9 @@ def build_interface(iface):
|
||||||
consts = []
|
consts = []
|
||||||
methods = []
|
methods = []
|
||||||
|
|
||||||
|
# Interfaces referenced from scriptable members need to be [scriptable].
|
||||||
|
needs_scriptable = set()
|
||||||
|
|
||||||
def build_const(c):
|
def build_const(c):
|
||||||
consts.append(
|
consts.append(
|
||||||
{
|
{
|
||||||
|
|
@ -182,7 +187,7 @@ def build_interface(iface):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def build_method(m):
|
def build_method(m, needs_scriptable=None):
|
||||||
params = []
|
params = []
|
||||||
for p in m.params:
|
for p in m.params:
|
||||||
params.append(
|
params.append(
|
||||||
|
|
@ -192,6 +197,7 @@ def build_interface(iface):
|
||||||
p.paramtype,
|
p.paramtype,
|
||||||
iid_is=attr_param_idx(p, m, "iid_is"),
|
iid_is=attr_param_idx(p, m, "iid_is"),
|
||||||
size_is=attr_param_idx(p, m, "size_is"),
|
size_is=attr_param_idx(p, m, "size_is"),
|
||||||
|
needs_scriptable=needs_scriptable,
|
||||||
),
|
),
|
||||||
in_=p.paramtype.count("in"),
|
in_=p.paramtype.count("in"),
|
||||||
out=p.paramtype.count("out"),
|
out=p.paramtype.count("out"),
|
||||||
|
|
@ -202,33 +208,36 @@ def build_interface(iface):
|
||||||
hasretval = len(m.params) > 0 and m.params[-1].retval
|
hasretval = len(m.params) > 0 and m.params[-1].retval
|
||||||
if not m.notxpcom and m.realtype.name != "void":
|
if not m.notxpcom and m.realtype.name != "void":
|
||||||
hasretval = True
|
hasretval = True
|
||||||
params.append(mk_param(get_type(m.realtype, "out"), out=1))
|
type = get_type(m.realtype, "out", needs_scriptable=needs_scriptable)
|
||||||
|
params.append(mk_param(type, out=1))
|
||||||
|
|
||||||
methods.append(
|
methods.append(
|
||||||
mk_method(m, params, optargc=m.optional_argc, hasretval=hasretval)
|
mk_method(m, params, optargc=m.optional_argc, hasretval=hasretval)
|
||||||
)
|
)
|
||||||
|
|
||||||
def build_attr(a):
|
def build_attr(a, needs_scriptable=None):
|
||||||
assert a.realtype.name != "void"
|
assert a.realtype.name != "void"
|
||||||
|
|
||||||
# Write the getter
|
# Write the getter
|
||||||
getter_params = []
|
getter_params = []
|
||||||
if not a.notxpcom:
|
if not a.notxpcom:
|
||||||
getter_params.append(mk_param(get_type(a.realtype, "out"), out=1))
|
type = get_type(a.realtype, "out", needs_scriptable=needs_scriptable)
|
||||||
|
getter_params.append(mk_param(type, out=1))
|
||||||
|
|
||||||
methods.append(mk_method(a, getter_params, getter=1, hasretval=1))
|
methods.append(mk_method(a, getter_params, getter=1, hasretval=1))
|
||||||
|
|
||||||
# And maybe the setter
|
# And maybe the setter
|
||||||
if not a.readonly:
|
if not a.readonly:
|
||||||
param = mk_param(get_type(a.realtype, "in"), in_=1)
|
type = get_type(a.realtype, "in", needs_scriptable=needs_scriptable)
|
||||||
methods.append(mk_method(a, [param], setter=1))
|
methods.append(mk_method(a, [mk_param(type, in_=1)], setter=1))
|
||||||
|
|
||||||
for member in iface.members:
|
for member in iface.members:
|
||||||
if isinstance(member, xpidl.ConstMember):
|
if isinstance(member, xpidl.ConstMember):
|
||||||
build_const(member)
|
build_const(member)
|
||||||
elif isinstance(member, xpidl.Attribute):
|
elif isinstance(member, xpidl.Attribute):
|
||||||
build_attr(member)
|
build_attr(member, member.isScriptable() and needs_scriptable)
|
||||||
elif isinstance(member, xpidl.Method):
|
elif isinstance(member, xpidl.Method):
|
||||||
build_method(member)
|
build_method(member, member.isScriptable() and needs_scriptable)
|
||||||
elif isinstance(member, xpidl.CEnum):
|
elif isinstance(member, xpidl.CEnum):
|
||||||
build_cenum(member)
|
build_cenum(member)
|
||||||
elif isinstance(member, xpidl.CDATA):
|
elif isinstance(member, xpidl.CDATA):
|
||||||
|
|
@ -236,12 +245,24 @@ def build_interface(iface):
|
||||||
else:
|
else:
|
||||||
raise Exception("Unexpected interface member: %s" % member)
|
raise Exception("Unexpected interface member: %s" % member)
|
||||||
|
|
||||||
|
for ref in set(needs_scriptable):
|
||||||
|
p = iface.idl.getName(xpidl.TypeId(ref), None)
|
||||||
|
if isinstance(p, xpidl.Interface):
|
||||||
|
needs_scriptable.remove(ref)
|
||||||
|
if not p.attributes.scriptable:
|
||||||
|
raise Exception(
|
||||||
|
f"Scriptable member in {iface.name} references non-scriptable {ref}. "
|
||||||
|
"The interface must be marked as [scriptable], "
|
||||||
|
"or the referencing member with [noscript]."
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"name": iface.name,
|
"name": iface.name,
|
||||||
"uuid": iface.attributes.uuid,
|
"uuid": iface.attributes.uuid,
|
||||||
"methods": methods,
|
"methods": methods,
|
||||||
"consts": consts,
|
"consts": consts,
|
||||||
"parent": iface.base,
|
"parent": iface.base,
|
||||||
|
"needs_scriptable": sorted(needs_scriptable),
|
||||||
"flags": flags(
|
"flags": flags(
|
||||||
("function", iface.attributes.function),
|
("function", iface.attributes.function),
|
||||||
("builtinclass", iface.attributes.builtinclass),
|
("builtinclass", iface.attributes.builtinclass),
|
||||||
|
|
|
||||||
|
|
@ -625,6 +625,16 @@ def link_and_write(files, outfile, outheader):
|
||||||
iids.add(interface["uuid"])
|
iids.add(interface["uuid"])
|
||||||
names.add(interface["name"])
|
names.add(interface["name"])
|
||||||
|
|
||||||
|
# All forwards referenced from scriptable members must be known (as scriptable).
|
||||||
|
for iface in interfaces:
|
||||||
|
for ref in iface["needs_scriptable"]:
|
||||||
|
if not ref in names:
|
||||||
|
raise Exception(
|
||||||
|
f"Scriptable member in {iface['name']} references unknown {ref}. "
|
||||||
|
"Forward must be a known and [scriptable] interface, "
|
||||||
|
"or the referencing member marked with [noscript]."
|
||||||
|
)
|
||||||
|
|
||||||
link_to_cpp(interfaces, outfile, outheader)
|
link_to_cpp(interfaces, outfile, outheader)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ interface nsIThreadObserver;
|
||||||
* The XPCOM thread object implements this interface, which allows a consumer
|
* The XPCOM thread object implements this interface, which allows a consumer
|
||||||
* to observe dispatch activity on the thread.
|
* to observe dispatch activity on the thread.
|
||||||
*/
|
*/
|
||||||
[builtinclass, scriptable, rust_sync, uuid(a3a72e5f-71d9-4add-8f30-59a78fb6d5eb)]
|
[rust_sync, uuid(a3a72e5f-71d9-4add-8f30-59a78fb6d5eb)]
|
||||||
interface nsIThreadInternal : nsIThread
|
interface nsIThreadInternal : nsIThread
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue