mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 836816 - WebIDL parser should enforce spec restrictions on dictionary member types. r=bzbarsky
This commit is contained in:
parent
87131afd0e
commit
242d2bcf74
@ -1023,7 +1023,65 @@ class IDLDictionary(IDLObjectWithScope):
|
||||
[member.location, inheritedMember.location])
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
def typeContainsDictionary(memberType, dictionary):
|
||||
"""
|
||||
Returns a tuple whose:
|
||||
|
||||
- First element is a Boolean value indicating whether
|
||||
memberType contains dictionary.
|
||||
|
||||
- Second element is:
|
||||
A list of locations that leads from the type that was passed in
|
||||
the memberType argument, to the dictionary being validated,
|
||||
if the boolean value in the first element is True.
|
||||
|
||||
None, if the boolean value in the first element is False.
|
||||
"""
|
||||
|
||||
if memberType.nullable() or \
|
||||
memberType.isArray() or \
|
||||
memberType.isSequence():
|
||||
return typeContainsDictionary(memberType.inner, dictionary)
|
||||
|
||||
if memberType.isDictionary():
|
||||
if memberType.inner == dictionary:
|
||||
return (True, [memberType.location])
|
||||
|
||||
(contains, locations) = dictionaryContainsDictionary(memberType.inner, \
|
||||
dictionary)
|
||||
if contains:
|
||||
return (True, [memberType.location] + locations)
|
||||
|
||||
if memberType.isUnion():
|
||||
for member in memberType.flatMemberTypes:
|
||||
(contains, locations) = typeContainsDictionary(member, dictionary)
|
||||
if contains:
|
||||
return (True, locations)
|
||||
|
||||
return (False, None)
|
||||
|
||||
def dictionaryContainsDictionary(dictMember, dictionary):
|
||||
for member in dictMember.members:
|
||||
(contains, locations) = typeContainsDictionary(member.type, dictionary)
|
||||
if contains:
|
||||
return (True, [member.location] + locations)
|
||||
|
||||
if dictMember.parent:
|
||||
if dictMember.parent == dictionary:
|
||||
return (True, [dictMember.location])
|
||||
else:
|
||||
(contains, locations) = dictionaryContainsDictionary(dictMember.parent, dictionary)
|
||||
if contains:
|
||||
return (True, [dictMember.location] + locations)
|
||||
|
||||
return (False, None)
|
||||
|
||||
for member in self.members:
|
||||
(contains, locations) = typeContainsDictionary(member.type, self)
|
||||
if contains:
|
||||
raise WebIDLError("Dictionary %s has member with itself as type." %
|
||||
self.identifier.name,
|
||||
[member.location] + locations)
|
||||
|
||||
def addExtendedAttributes(self, attrs):
|
||||
assert len(attrs) == 0
|
||||
|
@ -296,3 +296,132 @@ def WebIDLTest(parser, harness):
|
||||
""")
|
||||
results = parser.finish()
|
||||
harness.ok(True, "Union arg containing a dictionary should actually parse")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo {
|
||||
Foo foo;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Member type must not be its Dictionary.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo3 : Foo {
|
||||
short d;
|
||||
};
|
||||
|
||||
dictionary Foo2 : Foo3 {
|
||||
boolean c;
|
||||
};
|
||||
|
||||
dictionary Foo1 : Foo2 {
|
||||
long a;
|
||||
};
|
||||
|
||||
dictionary Foo {
|
||||
Foo1 b;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Member type must not be a Dictionary that "
|
||||
"inherits from its Dictionary.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo {
|
||||
(Foo or DOMString)[]? b;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Member type must not be a Nullable type "
|
||||
"whose inner type includes its Dictionary.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo {
|
||||
(DOMString or Foo) b;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Member type must not be a Union type, one of "
|
||||
"whose member types includes its Dictionary.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo {
|
||||
sequence<sequence<sequence<Foo>>> c;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Member type must not be a Sequence type "
|
||||
"whose element type includes its Dictionary.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo {
|
||||
(DOMString or Foo)[] d;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Member type must not be an Array type "
|
||||
"whose element type includes its Dictionary.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary Foo {
|
||||
Foo1 b;
|
||||
};
|
||||
|
||||
dictionary Foo3 {
|
||||
Foo d;
|
||||
};
|
||||
|
||||
dictionary Foo2 : Foo3 {
|
||||
short c;
|
||||
};
|
||||
|
||||
dictionary Foo1 : Foo2 {
|
||||
long a;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Member type must not be a Dictionary, one of whose "
|
||||
"members or inherited members has a type that includes "
|
||||
"its Dictionary.")
|
||||
|
Loading…
Reference in New Issue
Block a user