qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

qapi: Fix QemuOpts visitor regression on unvisited input

An off-by-one in commit 15c2f669e meant that we were failing to
check for unparsed input in all QemuOpts visitors. Recent testsuite
additions show that fixing the obvious bug with bogus fields will
also fix the case of an incomplete list visit; update the tests to
match the new behavior.

Simple testcase:

./x86_64-softmmu/qemu-system-x86_64 -nodefaults -nographic -qmp stdio -numa node,size=1g

failed to diagnose that 'size' is not a valid argument to -numa, and
now once again reports:

qemu-system-x86_64: -numa node,size=1g: Invalid parameter 'size'

See also https://bugzilla.redhat.com/show_bug.cgi?id=1434666

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
Message-Id: <20170322144525.18964-4-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>

authored by

Eric Blake and committed by
Markus Armbruster
21f88d02 9a6d1acb

+11 -8
+3 -3
qapi/opts-visitor.c
··· 164 164 GHashTableIter iter; 165 165 GQueue *any; 166 166 167 - if (ov->depth > 0) { 167 + if (ov->depth > 1) { 168 168 return; 169 169 } 170 170 ··· 276 276 opts_check_list(Visitor *v, Error **errp) 277 277 { 278 278 /* 279 - * FIXME should set error when unvisited elements remain. Mostly 280 - * harmless, as the generated visits always visit all elements. 279 + * Unvisited list elements will be reported later when checking 280 + * whether unvisited struct members remain. 281 281 */ 282 282 } 283 283
+8 -5
tests/test-opts-visitor.c
··· 175 175 static void 176 176 test_opts_range_unvisited(void) 177 177 { 178 + Error *err = NULL; 178 179 intList *list = NULL; 179 180 intList *tail; 180 181 QemuOpts *opts; ··· 199 200 g_assert_cmpint(tail->value, ==, 1); 200 201 tail = (intList *)visit_next_list(v, (GenericList *)tail, sizeof(*list)); 201 202 g_assert(tail); 202 - visit_check_list(v, &error_abort); /* BUG: unvisited tail not reported */ 203 + visit_check_list(v, &error_abort); /* unvisited tail ignored until... */ 203 204 visit_end_list(v, (void **)&list); 204 205 205 - visit_check_struct(v, &error_abort); 206 + visit_check_struct(v, &err); /* ...here */ 207 + error_free_or_abort(&err); 206 208 visit_end_struct(v, NULL); 207 209 208 210 qapi_free_intList(list); ··· 250 252 static void 251 253 test_opts_dict_unvisited(void) 252 254 { 255 + Error *err = NULL; 253 256 QemuOpts *opts; 254 257 Visitor *v; 255 258 UserDefOptions *userdef; ··· 258 261 &error_abort); 259 262 260 263 v = opts_visitor_new(opts); 261 - /* BUG: bogus should be diagnosed */ 262 - visit_type_UserDefOptions(v, NULL, &userdef, &error_abort); 264 + visit_type_UserDefOptions(v, NULL, &userdef, &err); 265 + error_free_or_abort(&err); 263 266 visit_free(v); 264 267 qemu_opts_del(opts); 265 - qapi_free_UserDefOptions(userdef); 268 + g_assert(!userdef); 266 269 } 267 270 268 271 int