提交 fda72ab4 编写于 作者: E Eduardo Habkost 提交者: Markus Armbruster

qapi: Fix error handling code on alternate conflict

The conflict check added by commit c0644771 ("qapi: Reject
alternates that can't work with keyval_parse()") doesn't work
with the following declaration:

  { 'alternate': 'Alt',
    'data': { 'one': 'bool',
              'two': 'str' } }

It crashes with:

  Traceback (most recent call last):
    File "./scripts/qapi-types.py", line 295, in <module>
      schema = QAPISchema(input_file)
    File "/home/ehabkost/rh/proj/virt/qemu/scripts/qapi.py", line 1468, in __init__
      self.exprs = check_exprs(parser.exprs)
    File "/home/ehabkost/rh/proj/virt/qemu/scripts/qapi.py", line 958, in check_exprs
      check_alternate(expr, info)
    File "/home/ehabkost/rh/proj/virt/qemu/scripts/qapi.py", line 830, in check_alternate
      % (name, key, types_seen[qtype]))
  KeyError: 'QTYPE_QSTRING'

This happens because the previously-seen conflicting member
('one') can't be found at types_seen[qtype], but at
types_seen['QTYPE_BOOL'].

Fix the bug by moving the error check to the same loop that adds
new items to types_seen, raising an exception if types_seen[qt]
is already set.

Add two additional test cases that can detect the bug.
Signed-off-by: NEduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170717180926.14924-1-ehabkost@redhat.com>
Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
上级 223cd0e1
...@@ -825,11 +825,11 @@ def check_alternate(expr, info): ...@@ -825,11 +825,11 @@ def check_alternate(expr, info):
else: else:
conflicting.add('QTYPE_QNUM') conflicting.add('QTYPE_QNUM')
conflicting.add('QTYPE_QBOOL') conflicting.add('QTYPE_QBOOL')
if conflicting & set(types_seen):
raise QAPISemError(info, "Alternate '%s' member '%s' can't "
"be distinguished from member '%s'"
% (name, key, types_seen[qtype]))
for qt in conflicting: for qt in conflicting:
if qt in types_seen:
raise QAPISemError(info, "Alternate '%s' member '%s' can't "
"be distinguished from member '%s'"
% (name, key, types_seen[qt]))
types_seen[qt] = key types_seen[qt] = key
......
...@@ -376,6 +376,8 @@ qapi-schema += alternate-conflict-dict.json ...@@ -376,6 +376,8 @@ qapi-schema += alternate-conflict-dict.json
qapi-schema += alternate-conflict-enum-bool.json qapi-schema += alternate-conflict-enum-bool.json
qapi-schema += alternate-conflict-enum-int.json qapi-schema += alternate-conflict-enum-int.json
qapi-schema += alternate-conflict-string.json qapi-schema += alternate-conflict-string.json
qapi-schema += alternate-conflict-bool-string.json
qapi-schema += alternate-conflict-num-string.json
qapi-schema += alternate-empty.json qapi-schema += alternate-empty.json
qapi-schema += alternate-nested.json qapi-schema += alternate-nested.json
qapi-schema += alternate-unknown.json qapi-schema += alternate-unknown.json
......
tests/qapi-schema/alternate-conflict-bool-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
# alternate branches of 'str' type conflict with all scalar types
{ 'alternate': 'Alt',
'data': { 'one': 'bool',
'two': 'str' } }
tests/qapi-schema/alternate-conflict-num-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
# alternate branches of 'str' type conflict with all scalar types
{ 'alternate': 'Alt',
'data': { 'one': 'number',
'two': 'str' } }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册