mirror of https://gitee.com/openkylin/qemu.git
tests: add QMP input visitor test for unions with no discriminator
This is more of an exercise of the dealloc visitor, where it may erroneously use an uninitialized discriminator field as indication that union fields corresponding to that discriminator field/type are present, which can lead to attempts to free random chunks of heap memory. Cc: qemu-stable@nongnu.org Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
146db9f919
commit
cb55111b4e
|
@ -33,6 +33,9 @@
|
|||
{ 'type': 'UserDefB',
|
||||
'data': { 'integer': 'int' } }
|
||||
|
||||
{ 'type': 'UserDefC',
|
||||
'data': { 'string1': 'str', 'string2': 'str' } }
|
||||
|
||||
{ 'union': 'UserDefUnion',
|
||||
'base': 'UserDefZero',
|
||||
'data': { 'a' : 'UserDefA', 'b' : 'UserDefB' } }
|
||||
|
@ -47,6 +50,13 @@
|
|||
# FIXME generated struct UserDefFlatUnion has members for direct base
|
||||
# UserDefOne, but lacks members for indirect base UserDefZero
|
||||
|
||||
# this variant of UserDefFlatUnion defaults to a union that uses fields with
|
||||
# allocated types to test corner cases in the cleanup/dealloc visitor
|
||||
{ 'union': 'UserDefFlatUnion2',
|
||||
'base': 'UserDefUnionBase',
|
||||
'discriminator': 'enum1',
|
||||
'data': { 'value1' : 'UserDefC', 'value2' : 'UserDefB', 'value3' : 'UserDefA' } }
|
||||
|
||||
{ 'union': 'UserDefAnonUnion',
|
||||
'discriminator': {},
|
||||
'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
|
||||
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
|
||||
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
|
||||
OrderedDict([('union', 'UserDefUnion'), ('base', 'UserDefZero'), ('data', OrderedDict([('a', 'UserDefA'), ('b', 'UserDefB')]))]),
|
||||
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
|
||||
OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), ('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
|
||||
OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), ('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
|
||||
OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
|
||||
OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
|
||||
OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
|
||||
|
@ -32,6 +34,7 @@
|
|||
OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
|
||||
OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
|
||||
OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
|
||||
OrderedDict([('type', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
|
||||
OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
|
||||
OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
|
||||
OrderedDict([('type', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))])]
|
||||
|
|
|
@ -260,6 +260,21 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
|
|||
qapi_free_UserDefFlatUnion(tmp);
|
||||
}
|
||||
|
||||
static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
UserDefFlatUnion2 *tmp = NULL;
|
||||
Error *err = NULL;
|
||||
Visitor *v;
|
||||
|
||||
/* test situation where discriminator field ('enum1' here) is missing */
|
||||
v = validate_test_init(data, "{ 'string': 'c', 'string1': 'd', 'string2': 'e' }");
|
||||
|
||||
visit_type_UserDefFlatUnion2(v, &tmp, NULL, &err);
|
||||
g_assert(err);
|
||||
qapi_free_UserDefFlatUnion2(tmp);
|
||||
}
|
||||
|
||||
static void test_validate_fail_union_anon(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
|
@ -310,6 +325,8 @@ int main(int argc, char **argv)
|
|||
&testdata, test_validate_fail_union);
|
||||
validate_test_add("/visitor/input-strict/fail/union-flat",
|
||||
&testdata, test_validate_fail_union_flat);
|
||||
validate_test_add("/visitor/input-strict/fail/union-flat-no-discriminator",
|
||||
&testdata, test_validate_fail_union_flat_no_discrim);
|
||||
validate_test_add("/visitor/input-strict/fail/union-anon",
|
||||
&testdata, test_validate_fail_union_anon);
|
||||
|
||||
|
|
Loading…
Reference in New Issue