diff mbox

[1/4] qobject-input-visitor: Reject non-finite numbers with keyval

Message ID 1495471335-23707-2-git-send-email-armbru@redhat.com
State New
Headers show

Commit Message

Markus Armbruster May 22, 2017, 4:42 p.m. UTC
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 <armbru@redhat.com>
---
 qapi/qobject-input-visitor.c       | 3 ++-
 tests/test-qobject-input-visitor.c | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

Comments

Eric Blake May 22, 2017, 5:46 p.m. UTC | #1
On 05/22/2017 11:42 AM, Markus Armbruster wrote:
> 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.

I also posted patches once (and should revive them) to add more
assertions in our code base that we aren't passing non-finite numbers to
the JSON outputter.

> 
> 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 <armbru@redhat.com>
> ---
>  qapi/qobject-input-visitor.c       | 3 ++-
>  tests/test-qobject-input-visitor.c | 6 ++++++
>  2 files changed, 8 insertions(+), 1 deletion(-)

Reviewed-by: Eric Blake <eblake@redhat.com>
diff mbox

Patch

diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index d0f0002..eac40f6 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -13,6 +13,7 @@ 
  */
 
 #include "qemu/osdep.h"
+#include <math.h>
 #include "qapi/error.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/visitor-impl.h"
@@ -568,7 +569,7 @@  static void qobject_input_type_number_keyval(Visitor *v, const char *name,
 
     errno = 0;
     *obj = strtod(str, &endp);
-    if (errno || endp == str || *endp) {
+    if (errno || endp == str || *endp || !isfinite(*obj)) {
         /* TODO report -ERANGE more nicely */
         error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
                    full_name(qiv, name), "number");
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index f965743..e2aabbe 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,