qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: Eduardo Habkost <ehabkost@redhat.com>
Subject: [Qemu-devel] [PULL v2 01/47] qapi: Fix error handling code on alternate conflict
Date: Fri,  1 Sep 2017 17:37:12 +0200	[thread overview]
Message-ID: <20170901153758.8628-2-armbru@redhat.com> (raw)
In-Reply-To: <20170901153758.8628-1-armbru@redhat.com>

From: Eduardo Habkost <ehabkost@redhat.com>

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: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170717180926.14924-1-ehabkost@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 scripts/qapi.py                                       | 8 ++++----
 tests/Makefile.include                                | 2 ++
 tests/qapi-schema/alternate-conflict-bool-string.err  | 1 +
 tests/qapi-schema/alternate-conflict-bool-string.exit | 1 +
 tests/qapi-schema/alternate-conflict-bool-string.json | 4 ++++
 tests/qapi-schema/alternate-conflict-bool-string.out  | 0
 tests/qapi-schema/alternate-conflict-num-string.err   | 1 +
 tests/qapi-schema/alternate-conflict-num-string.exit  | 1 +
 tests/qapi-schema/alternate-conflict-num-string.json  | 4 ++++
 tests/qapi-schema/alternate-conflict-num-string.out   | 0
 10 files changed, 18 insertions(+), 4 deletions(-)
 create mode 100644 tests/qapi-schema/alternate-conflict-bool-string.err
 create mode 100644 tests/qapi-schema/alternate-conflict-bool-string.exit
 create mode 100644 tests/qapi-schema/alternate-conflict-bool-string.json
 create mode 100644 tests/qapi-schema/alternate-conflict-bool-string.out
 create mode 100644 tests/qapi-schema/alternate-conflict-num-string.err
 create mode 100644 tests/qapi-schema/alternate-conflict-num-string.exit
 create mode 100644 tests/qapi-schema/alternate-conflict-num-string.json
 create mode 100644 tests/qapi-schema/alternate-conflict-num-string.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 8aa2775f12..3693b520da 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
 
 
diff --git a/tests/Makefile.include b/tests/Makefile.include
index f08b7418f0..00af45ca85 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -376,6 +376,8 @@ qapi-schema += alternate-conflict-dict.json
 qapi-schema += alternate-conflict-enum-bool.json
 qapi-schema += alternate-conflict-enum-int.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-nested.json
 qapi-schema += alternate-unknown.json
diff --git a/tests/qapi-schema/alternate-conflict-bool-string.err b/tests/qapi-schema/alternate-conflict-bool-string.err
new file mode 100644
index 0000000000..e52fee7620
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-bool-string.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-conflict-bool-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
diff --git a/tests/qapi-schema/alternate-conflict-bool-string.exit b/tests/qapi-schema/alternate-conflict-bool-string.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-bool-string.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/alternate-conflict-bool-string.json b/tests/qapi-schema/alternate-conflict-bool-string.json
new file mode 100644
index 0000000000..0544de10f3
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-bool-string.json
@@ -0,0 +1,4 @@
+# alternate branches of 'str' type conflict with all scalar types
+{ 'alternate': 'Alt',
+  'data': { 'one': 'bool',
+            'two': 'str' } }
diff --git a/tests/qapi-schema/alternate-conflict-bool-string.out b/tests/qapi-schema/alternate-conflict-bool-string.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alternate-conflict-num-string.err b/tests/qapi-schema/alternate-conflict-num-string.err
new file mode 100644
index 0000000000..5ba3827dd1
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-num-string.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-conflict-num-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one'
diff --git a/tests/qapi-schema/alternate-conflict-num-string.exit b/tests/qapi-schema/alternate-conflict-num-string.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-num-string.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/alternate-conflict-num-string.json b/tests/qapi-schema/alternate-conflict-num-string.json
new file mode 100644
index 0000000000..ae901449af
--- /dev/null
+++ b/tests/qapi-schema/alternate-conflict-num-string.json
@@ -0,0 +1,4 @@
+# alternate branches of 'str' type conflict with all scalar types
+{ 'alternate': 'Alt',
+  'data': { 'one': 'number',
+            'two': 'str' } }
diff --git a/tests/qapi-schema/alternate-conflict-num-string.out b/tests/qapi-schema/alternate-conflict-num-string.out
new file mode 100644
index 0000000000..e69de29bb2
-- 
2.13.5

  reply	other threads:[~2017-09-01 15:38 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-01 15:37 [Qemu-devel] [PULL v2 00/47] QAPI patches for 2017-09-01 Markus Armbruster
2017-09-01 15:37 ` Markus Armbruster [this message]
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 02/47] tests/qmp-test: Add generic, basic test of query commands Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 03/47] qobject: Explain how QNum works, and why Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 04/47] qdict: Add qdict_put_null() helper, and put it to use Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 05/47] qlit: move qlit from check-qjson to qobject/ Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 06/47] qlit: use QLit prefix consistently Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 07/47] qlit: Change compound literals to initializers Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 08/47] qlit: rename compare_litqobj_to_qobj() to qlit_equal_qobject() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 09/47] qlit: make qlit_equal_qobject return a bool Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 10/47] qlit: make qlit_equal_qobject() take const arguments Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 11/47] qlit: add QLIT_QNULL and QLIT_BOOL Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 12/47] qlit: Replace open-coded qnum_get_int() by call Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 13/47] tests/check-qlit: New, covering qobject/qlit.c Markus Armbruster
2017-09-05 20:38   ` Eric Blake
2017-09-06  5:39     ` Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 14/47] qlit: Tighten QLit dict vs QDict comparison Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 15/47] qlit: Tighten QLit list vs QList comparison Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 16/47] qapi-schema: Document how generated documentation is ordered Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 17/47] qapi-schema: Introspection doc is in the wrong section, fix Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 18/47] qapi-schema: Rocker doc section contains unrelated stuff, fix Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 19/47] qapi-schema: Collect sockets stuff in qapi/sockets.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 20/47] qapi-schema: Collect run state stuff in qapi/run-state.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 21/47] qapi-schema: Collect char device stuff in qapi/char.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 22/47] qapi-schema: Collect net device stuff in qapi/net.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 23/47] qapi-schema: Collect UI stuff in qapi/ui.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 24/47] qapi-schema: Collect migration stuff in qapi/migration.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 25/47] qapi-schema: Collect transaction stuff in qapi/transaction.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 26/47] qapi-schema: Collect TPM stuff in qapi/tpm.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 27/47] qapi-schema: Move block events from event.json to block.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 28/47] qapi-schema: Fold event.json back into qapi-schema.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 29/47] qapi-schema: Make block-core.json self-contained Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 30/47] qapi-schema: Move queries from common.json to qapi-schema.json Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 31/47] qapi-schema: Improve section headings Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 32/47] qapi: Update qapi-code-gen.txt examples to match current code Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 33/47] qapi: Drop superfluous qapi_enum_parse() parameter max Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 34/47] tpm: Clean up driver registration & lookup Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 35/47] tpm: Clean up model " Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 36/47] hmp: Use qapi_enum_parse() in hmp_migrate_set_capability() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 37/47] hmp: Use qapi_enum_parse() in hmp_migrate_set_parameter() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 38/47] block: Use qemu_enum_parse() in blkdebug_debug_breakpoint() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 39/47] quorum: Use qapi_enum_parse() in quorum_open() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 40/47] crypto: Use qapi_enum_parse() in qcrypto_block_luks_name_lookup() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 41/47] qapi: Use qapi_enum_parse() in input_type_enum() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 42/47] qapi: Avoid unnecessary use of enum lookup table's sentinel Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 43/47] qapi: Generate FOO_str() macro for QAPI enum FOO Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 44/47] qapi: Mechanically convert FOO_lookup[...] to FOO_str(...) Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 45/47] qapi: Convert indirect uses of FOO_lookup[...] to qapi_enum_lookup() Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 46/47] qapi: Change data type of the FOO_lookup generated for enum FOO Markus Armbruster
2017-09-01 15:37 ` [Qemu-devel] [PULL v2 47/47] qapi: drop the sentinel in enum array Markus Armbruster
2017-09-04 10:01 ` [Qemu-devel] [PULL v2 00/47] QAPI patches for 2017-09-01 Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170901153758.8628-2-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).