Bug 836816 - WebIDL parser should enforce spec restrictions on dictionary member types. r=bzbarsky

This commit is contained in:
Pranav Ravichandran 2013-02-27 09:55:56 -05:00
parent 87131afd0e
commit 242d2bcf74
2 changed files with 188 additions and 1 deletions

View File

@ -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

View File

@ -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.")