From 5891c388bbdd48ba0440d2738155f364589a432a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 22 May 2017 18:42:12 +0200 Subject: qobject-input-visitor: Reject non-finite numbers with keyval The QObject input visitor can produce only finite numbers when its input comes out of the JSON parser, because the the JSON parser implements RFC 7159, which provides no syntax for infinity and NaN. However, it can produce infinity and NaN when its input comes out of keyval_parse(), because we parse with strtod() then. The keyval variant should not be able to express things the JSON variant can't. Rejecting non-finite numbers there is the conservative fix. It's also minimally invasive. We could instead extend our JSON dialect to provide for infinity and NaN. Not today. Note that the JSON formatter can emit non-finite numbers (marked FIXME in commit 6e8e5cb). Signed-off-by: Markus Armbruster Message-Id: <1495471335-23707-2-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake Reviewed-by: Marc-André Lureau --- tests/test-qobject-input-visitor.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests/test-qobject-input-visitor.c') diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index f965743b6e..e2aabbe972 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -278,11 +278,17 @@ static void test_visitor_in_number_str_keyval(TestInputVisitorData *data, { double res = 0, value = 3.14; Visitor *v; + Error *err = NULL; v = visitor_input_test_init_full(data, true, "\"3.14\""); visit_type_number(v, NULL, &res, &error_abort); g_assert_cmpfloat(res, ==, value); + + v = visitor_input_test_init_full(data, true, "\"inf\""); + + visit_type_number(v, NULL, &res, &err); + error_free_or_abort(&err); } static void test_visitor_in_number_str_fail(TestInputVisitorData *data, -- cgit v1.2.3-55-g7522 From 8168ca8ea3699b9fca4d8c948c7fa6ecdedc4a97 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 22 May 2017 18:42:14 +0200 Subject: tests/qapi-schema: Avoid 'str' in alternate test cases The next commit is going to make alternate members of type 'str' conflict with other scalar types. Would break a few test cases that don't actually require 'str'. Flip them from 'str' to 'bool' or 'EnumOne'. Signed-off-by: Markus Armbruster Message-Id: <1495471335-23707-4-git-send-email-armbru@redhat.com> Reviewed-by: Eric Blake Reviewed-by: Marc-André Lureau --- tests/qapi-schema/alternate-clash.json | 2 +- tests/qapi-schema/alternate-nested.json | 2 +- tests/qapi-schema/args-alternate.json | 2 +- tests/qapi-schema/doc-bad-alternate-member.json | 2 +- tests/qapi-schema/qapi-schema-test.json | 9 ++-- tests/qapi-schema/qapi-schema-test.out | 30 +++++++------ tests/qapi-schema/returns-alternate.json | 2 +- tests/test-clone-visitor.c | 23 +++++----- tests/test-qobject-input-visitor.c | 56 ++++++++++++------------- tests/test-qobject-output-visitor.c | 4 +- 10 files changed, 68 insertions(+), 64 deletions(-) (limited to 'tests/test-qobject-input-visitor.c') diff --git a/tests/qapi-schema/alternate-clash.json b/tests/qapi-schema/alternate-clash.json index 6d73bc527b..9a59b88ced 100644 --- a/tests/qapi-schema/alternate-clash.json +++ b/tests/qapi-schema/alternate-clash.json @@ -5,4 +5,4 @@ # the implicit Alt1Kind enum, we would still have a collision with the # resulting C union trying to have two members named 'a_b'. { 'alternate': 'Alt1', - 'data': { 'a-b': 'str', 'a_b': 'int' } } + 'data': { 'a-b': 'bool', 'a_b': 'int' } } diff --git a/tests/qapi-schema/alternate-nested.json b/tests/qapi-schema/alternate-nested.json index 8e22186491..f2b9632f75 100644 --- a/tests/qapi-schema/alternate-nested.json +++ b/tests/qapi-schema/alternate-nested.json @@ -1,5 +1,5 @@ # we reject a nested alternate branch { 'alternate': 'Alt1', - 'data': { 'name': 'str', 'value': 'int' } } + 'data': { 'name': 'bool', 'value': 'int' } } { 'alternate': 'Alt2', 'data': { 'nested': 'Alt1', 'b': 'bool' } } diff --git a/tests/qapi-schema/args-alternate.json b/tests/qapi-schema/args-alternate.json index 69e94d4819..824d69c1d5 100644 --- a/tests/qapi-schema/args-alternate.json +++ b/tests/qapi-schema/args-alternate.json @@ -1,3 +1,3 @@ # we do not allow alternate arguments -{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'str' } } +{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'bool' } } { 'command': 'oops', 'data': 'Alt' } diff --git a/tests/qapi-schema/doc-bad-alternate-member.json b/tests/qapi-schema/doc-bad-alternate-member.json index 738635ca8f..fa4143da4c 100644 --- a/tests/qapi-schema/doc-bad-alternate-member.json +++ b/tests/qapi-schema/doc-bad-alternate-member.json @@ -6,4 +6,4 @@ # @bb: b ## { 'alternate': 'AorB', - 'data': { 'a': 'str', 'b': 'int' } } + 'data': { 'a': 'bool', 'b': 'int' } } diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 842ea3c5e3..303f2b23cd 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -93,16 +93,17 @@ { 'struct': 'WrapAlternate', 'data': { 'alt': 'UserDefAlternate' } } { 'alternate': 'UserDefAlternate', - 'data': { 'udfu': 'UserDefFlatUnion', 's': 'str', 'i': 'int' } } + 'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int' } } { 'struct': 'UserDefC', 'data': { 'string1': 'str', 'string2': 'str' } } # for testing use of 'number' within alternates -{ 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } } -{ 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } } +{ 'alternate': 'AltEnumBool', 'data': { 'e': 'EnumOne', 'b': 'bool' } } +{ 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } } { 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } } -{ 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } } +{ 'alternate': 'AltNumEnum', 'data': { 'n': 'number', 'e': 'EnumOne' } } +{ 'alternate': 'AltEnumInt', 'data': { 'e': 'EnumOne', 'i': 'int' } } { 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } } { 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 9d99c4eebb..3081091818 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -1,7 +1,23 @@ +alternate AltEnumBool + tag type + case e: EnumOne + case b: bool +alternate AltEnumInt + tag type + case e: EnumOne + case i: int +alternate AltEnumNum + tag type + case e: EnumOne + case n: number alternate AltIntNum tag type case i: int case n: number +alternate AltNumEnum + tag type + case n: number + case e: EnumOne alternate AltNumInt tag type case n: number @@ -10,18 +26,6 @@ alternate AltNumStr tag type case n: number case s: str -alternate AltStrBool - tag type - case s: str - case b: bool -alternate AltStrInt - tag type - case s: str - case i: int -alternate AltStrNum - tag type - case s: str - case n: number event EVENT_A None boxed=False event EVENT_B None @@ -66,7 +70,7 @@ object UserDefA alternate UserDefAlternate tag type case udfu: UserDefFlatUnion - case s: str + case e: EnumOne case i: int object UserDefB member intb: int optional=False diff --git a/tests/qapi-schema/returns-alternate.json b/tests/qapi-schema/returns-alternate.json index 972390c06b..f87371811b 100644 --- a/tests/qapi-schema/returns-alternate.json +++ b/tests/qapi-schema/returns-alternate.json @@ -1,3 +1,3 @@ # we reject returns if it is an alternate type -{ 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'str' } } +{ 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'bool' } } { 'command': 'oops', 'returns': 'Alt' } diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c index df0c045512..96982163e4 100644 --- a/tests/test-clone-visitor.c +++ b/tests/test-clone-visitor.c @@ -42,29 +42,28 @@ static void test_clone_struct(void) static void test_clone_alternate(void) { - AltStrBool *b_src, *s_src, *b_dst, *s_dst; + AltEnumBool *b_src, *s_src, *b_dst, *s_dst; - b_src = g_new0(AltStrBool, 1); + b_src = g_new0(AltEnumBool, 1); b_src->type = QTYPE_QBOOL; b_src->u.b = true; - s_src = g_new0(AltStrBool, 1); + s_src = g_new0(AltEnumBool, 1); s_src->type = QTYPE_QSTRING; - s_src->u.s = g_strdup("World"); + s_src->u.e = ENUM_ONE_VALUE1; - b_dst = QAPI_CLONE(AltStrBool, b_src); + b_dst = QAPI_CLONE(AltEnumBool, b_src); g_assert(b_dst); g_assert_cmpint(b_dst->type, ==, b_src->type); g_assert_cmpint(b_dst->u.b, ==, b_src->u.b); - s_dst = QAPI_CLONE(AltStrBool, s_src); + s_dst = QAPI_CLONE(AltEnumBool, s_src); g_assert(s_dst); g_assert_cmpint(s_dst->type, ==, s_src->type); - g_assert_cmpstr(s_dst->u.s, ==, s_src->u.s); - g_assert(s_dst->u.s != s_src->u.s); + g_assert_cmpint(s_dst->u.e, ==, s_src->u.e); - qapi_free_AltStrBool(b_src); - qapi_free_AltStrBool(s_src); - qapi_free_AltStrBool(b_dst); - qapi_free_AltStrBool(s_dst); + qapi_free_AltEnumBool(b_src); + qapi_free_AltEnumBool(s_src); + qapi_free_AltEnumBool(b_dst); + qapi_free_AltEnumBool(s_dst); } static void test_clone_native_list(void) diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index e2aabbe972..6b997a177d 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -537,10 +537,10 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, g_assert_cmpint(tmp->u.i, ==, 42); qapi_free_UserDefAlternate(tmp); - v = visitor_input_test_init(data, "'string'"); + v = visitor_input_test_init(data, "'value1'"); visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); - g_assert_cmpstr(tmp->u.s, ==, "string"); + g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " @@ -565,10 +565,10 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, g_assert_cmpint(wrap->alt->u.i, ==, 42); qapi_free_WrapAlternate(wrap); - v = visitor_input_test_init(data, "{ 'alt': 'string' }"); + v = visitor_input_test_init(data, "{ 'alt': 'value1' }"); visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); - g_assert_cmpstr(wrap->alt->u.s, ==, "string"); + g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1); qapi_free_WrapAlternate(wrap); v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " @@ -588,37 +588,37 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, { Visitor *v; Error *err = NULL; - AltStrBool *asb; - AltStrNum *asn; - AltNumStr *ans; - AltStrInt *asi; + AltEnumBool *aeb; + AltEnumNum *aen; + AltNumEnum *ans; + AltEnumInt *asi; AltIntNum *ain; AltNumInt *ani; /* Parsing an int */ v = visitor_input_test_init(data, "42"); - visit_type_AltStrBool(v, NULL, &asb, &err); + visit_type_AltEnumBool(v, NULL, &aeb, &err); error_free_or_abort(&err); - qapi_free_AltStrBool(asb); + qapi_free_AltEnumBool(aeb); v = visitor_input_test_init(data, "42"); - visit_type_AltStrNum(v, NULL, &asn, &error_abort); - g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); - g_assert_cmpfloat(asn->u.n, ==, 42); - qapi_free_AltStrNum(asn); + visit_type_AltEnumNum(v, NULL, &aen, &error_abort); + g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT); + g_assert_cmpfloat(aen->u.n, ==, 42); + qapi_free_AltEnumNum(aen); v = visitor_input_test_init(data, "42"); - visit_type_AltNumStr(v, NULL, &ans, &error_abort); + visit_type_AltNumEnum(v, NULL, &ans, &error_abort); g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ans->u.n, ==, 42); - qapi_free_AltNumStr(ans); + qapi_free_AltNumEnum(ans); v = visitor_input_test_init(data, "42"); - visit_type_AltStrInt(v, NULL, &asi, &error_abort); + visit_type_AltEnumInt(v, NULL, &asi, &error_abort); g_assert_cmpint(asi->type, ==, QTYPE_QINT); g_assert_cmpint(asi->u.i, ==, 42); - qapi_free_AltStrInt(asi); + qapi_free_AltEnumInt(asi); v = visitor_input_test_init(data, "42"); visit_type_AltIntNum(v, NULL, &ain, &error_abort); @@ -635,26 +635,26 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, /* Parsing a double */ v = visitor_input_test_init(data, "42.5"); - visit_type_AltStrBool(v, NULL, &asb, &err); + visit_type_AltEnumBool(v, NULL, &aeb, &err); error_free_or_abort(&err); - qapi_free_AltStrBool(asb); + qapi_free_AltEnumBool(aeb); v = visitor_input_test_init(data, "42.5"); - visit_type_AltStrNum(v, NULL, &asn, &error_abort); - g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); - g_assert_cmpfloat(asn->u.n, ==, 42.5); - qapi_free_AltStrNum(asn); + visit_type_AltEnumNum(v, NULL, &aen, &error_abort); + g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT); + g_assert_cmpfloat(aen->u.n, ==, 42.5); + qapi_free_AltEnumNum(aen); v = visitor_input_test_init(data, "42.5"); - visit_type_AltNumStr(v, NULL, &ans, &error_abort); + visit_type_AltNumEnum(v, NULL, &ans, &error_abort); g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ans->u.n, ==, 42.5); - qapi_free_AltNumStr(ans); + qapi_free_AltNumEnum(ans); v = visitor_input_test_init(data, "42.5"); - visit_type_AltStrInt(v, NULL, &asi, &err); + visit_type_AltEnumInt(v, NULL, &asi, &err); error_free_or_abort(&err); - qapi_free_AltStrInt(asi); + qapi_free_AltEnumInt(asi); v = visitor_input_test_init(data, "42.5"); visit_type_AltIntNum(v, NULL, &ain, &error_abort); diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c index 94b9518e40..4e8fdf1397 100644 --- a/tests/test-qobject-output-visitor.c +++ b/tests/test-qobject-output-visitor.c @@ -406,12 +406,12 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data, visitor_reset(data); tmp = g_new0(UserDefAlternate, 1); tmp->type = QTYPE_QSTRING; - tmp->u.s = g_strdup("hello"); + tmp->u.e = ENUM_ONE_VALUE1; visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort); qstr = qobject_to_qstring(visitor_get(data)); g_assert(qstr); - g_assert_cmpstr(qstring_get_str(qstr), ==, "hello"); + g_assert_cmpstr(qstring_get_str(qstr), ==, "value1"); qapi_free_UserDefAlternate(tmp); -- cgit v1.2.3-55-g7522