From fda72ab4510bcc680a3c4fe55997aa29589884f7 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 17 Jul 2017 15:09:26 -0300 Subject: 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 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: Eduardo Habkost Message-Id: <20170717180926.14924-1-ehabkost@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts/qapi.py') diff --git a/scripts/qapi.py b/scripts/qapi.py index 8aa2775..3693b52 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -825,11 +825,11 @@ def check_alternate(expr, info): else: conflicting.add('QTYPE_QNUM') 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: + 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 -- cgit v1.1