All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: "Daniel P. Berrange" <berrange@redhat.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org,
	"Max Reitz" <mreitz@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Andreas Färber" <afaerber@suse.de>
Subject: Re: [Qemu-devel] [PATCH v14 07/21] qapi: permit scalar type conversions in QObjectInputVisitor
Date: Wed, 12 Oct 2016 17:05:37 +0200	[thread overview]
Message-ID: <874m4hsj3y.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <87bmyptybk.fsf@dusky.pond.sub.org> (Markus Armbruster's message of "Wed, 12 Oct 2016 16:51:43 +0200")

Markus Armbruster <armbru@redhat.com> writes:

> Markus Armbruster <armbru@redhat.com> writes:
>
>> "Daniel P. Berrange" <berrange@redhat.com> writes:
>>
>>> Currently the QObjectInputVisitor assumes that all scalar
>>> values are directly represented as the final types declared
>>> by the thing being visited. ie it assumes an 'int' is using
>>
>> i.e.
>>
>>> QInt, and a 'bool' is using QBool, etc.  This is good when
>>> QObjectInputVisitor is fed a QObject that came from a JSON
>>> document on the QMP monitor, as it will strictly validate
>>> correctness.
>>>
>>> To allow QObjectInputVisitor to be reused for visiting
>>> a QObject originating from QemuOpts, an alternative mode
>>> is needed where all the scalars types are represented as
>>> QString and converted on the fly to the final desired
>>> type.
>>>
>>> Reviewed-by: Kevin Wolf <kwolf@redhat.com>
>>> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> [...]
>>> diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
>>> index 5ff3db3..cf41df6 100644
>>> --- a/qapi/qobject-input-visitor.c
>>> +++ b/qapi/qobject-input-visitor.c
>>> @@ -20,6 +20,7 @@
>>>  #include "qemu-common.h"
>>>  #include "qapi/qmp/types.h"
>>>  #include "qapi/qmp/qerror.h"
>>> +#include "qemu/cutils.h"
>>>  
>>>  #define QIV_STACK_SIZE 1024
>>>  
>>> @@ -263,6 +264,28 @@ static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
>>>      *obj = qint_get_int(qint);
>>>  }
>>>  
>>> +
>>> +static void qobject_input_type_int64_autocast(Visitor *v, const char *name,
>>> +                                              int64_t *obj, Error **errp)
>>> +{
>>> +    QObjectInputVisitor *qiv = to_qiv(v);
>>> +    QString *qstr = qobject_to_qstring(qobject_input_get_object(qiv, name,
>>> +                                                                true));
>>
>> Needs a rebase for commit 1382d4a.  Same elsewhere.
>>
>>> +    int64_t ret;
>>> +
>>> +    if (!qstr || !qstr->string) {
>>
>> I don't think !qstr->string can happen.  Same elsewhere.
>>
>>> +        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
>>> +                   "string");
>>> +        return;
>>> +    }
>>
>> So far, this is basically qobject_input_type_str() less the g_strdup().
>> Worth factoring out?
>>
>> Now we're entering out parsing swamp:
>>
>>> +
>>> +    if (qemu_strtoll(qstr->string, NULL, 0, &ret) < 0) {
>>> +        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
>
> "integer", actually.

Wait!  You're using QERR_INVALID_PARAMETER_VALUE here, so it's "an
integer".

To be pedantically correct, we'd have to complain about the type when
qemu_strtoll() fails to parse, and about the value when it parses okay,
but the value is out of range.

>>> +        return;
>>> +    }
>>
>> To serve as replacement for the options visitor, this needs to parse
>> exactly like opts_type_int64().
>>
>> It should also match the JSON parser as far as possible, to minimize
>> difference between the two QObject input visitor variants, and the
>> QemuOpts parser, for command line consistency.
>>
>> opts_type_int64() uses strtoll() directly.  It carefully checks for no
>> conversion (both ways, EINVAL and endptr == str), range, and string not
>> fully consumed.
>>
>> Your code uses qemu_strtoll().  Bug#1: qemu_strtoll() assumes long long
>> is exactly 64 bits.  If it's wider, we fail to diagnose overflow.  If
>> it's narrower, we can't parse all values.  Bug#2: your code fails to
>> check the string is fully consumed.
>>
>> The JSON parser also uses strtoll() directly, in parse_literal().  When
>> we get there, we know that the string consists only of decimal digits,
>> possibly prefixed by a minus sign.  Therefore, strtoll() can only fail
>> with ERANGE, and parse_literal() handles that correctly.
>>
>> QemuOpts doesn't do signed integers.
>>
>>> +    *obj = ret;
>>> +}
>>> +
>>>  static void qobject_input_type_uint64(Visitor *v, const char *name,
>>>                                        uint64_t *obj, Error **errp)
>>>  {
>>> @@ -279,6 +302,27 @@ static void qobject_input_type_uint64(Visitor *v, const char *name,
>>>      *obj = qint_get_int(qint);
>>>  }
>>>  
>>> +static void qobject_input_type_uint64_autocast(Visitor *v, const char *name,
>>> +                                               uint64_t *obj, Error **errp)
>>> +{
>>> +    QObjectInputVisitor *qiv = to_qiv(v);
>>> +    QString *qstr = qobject_to_qstring(qobject_input_get_object(qiv, name,
>>> +                                                                true));
>>> +    unsigned long long ret;
>>> +
>>> +    if (!qstr || !qstr->string) {
>>> +        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
>>> +                   "string");
>>> +        return;
>>> +    }
>>> +
>>> +    if (parse_uint_full(qstr->string, &ret, 0) < 0) {
>>> +        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name, "a number");
>
> "integer".

Likewise.

>>> +        return;
>>> +    }
>>> +    *obj = ret;
>>
>> Differently wrong :)
>>
>> To serve as replacement for the options visitor, this needs to parse
>> exactly like opts_type_uint64().
>>
>> Again, this should also match the JSON parser and the QemuOpts parser as
>> far as possible.
>>
>> opts_type_uint64() uses parse_uint().  It carefully checks for no
>> conversion (EINVAL; parse_uint() normalizes), range, and string not
>> fully consumed.
>>
>> You use parse_uint_full().  You therefore don't have bug#2 here.  You do
>> have bug#1: you assume unsigned long long is exactly 64 bits.  If it's
>> wider, we fail to diagnose overflow.  If it's narrower, we can't parse
>> all values.
>>
>> There's a discrepancy with the JSON parser, but it's not your fault: the
>> JSON parser represents JSON numbers that fit into int64_t to QInt, and
>> any others as QFloat.  In particular, the integers between INT64_MAX+1
>> and UINT64_MAX are represented as QFloat.  qmp_input_type_uint64()
>> accepts only QInt.  You can declare things as uint64 in the schema, but
>> you're still limited to 0..UINT64_MAX in QMP.
>>
>> QemuOpts uses strtoull() directly, in parse_option_number().  Bug (not
>> yours): it happily ignores errors other than "string not fully
>> consumed".
>>
>>> +}
>>> +
>>>  static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj,
>>>                                      Error **errp)
>>>  {
> [...]

  reply	other threads:[~2016-10-12 15:05 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-30 14:45 [Qemu-devel] [PATCH v14 00/21] QAPI/QOM work for non-scalar object properties Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 01/21] option: make parse_option_bool/number non-static Daniel P. Berrange
2016-10-21 16:55   ` Markus Armbruster
2016-10-21 17:12     ` Eric Blake
2016-10-21 17:51       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 02/21] qdict: implement a qdict_crumple method for un-flattening a dict Daniel P. Berrange
2016-10-18 14:32   ` Markus Armbruster
2016-10-20 14:11     ` Daniel P. Berrange
2016-10-21  9:58       ` Markus Armbruster
2016-10-21 18:31         ` Max Reitz
2016-10-24  9:18           ` Markus Armbruster
2016-10-24 10:28             ` Daniel P. Berrange
2016-10-24 12:38               ` Markus Armbruster
2016-10-25 10:03           ` Markus Armbruster
2016-10-25 10:20             ` Daniel P. Berrange
2016-10-25 12:29               ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 03/21] qapi: add trace events for visitor Daniel P. Berrange
2016-09-30 15:49   ` Eric Blake
2016-10-06 14:39   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-07 13:59   ` [Qemu-devel] " Markus Armbruster
2016-10-07 14:16     ` Daniel P. Berrange
2016-10-21 10:52       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 04/21] qapi: rename QmpInputVisitor to QObjectInputVisitor Daniel P. Berrange
2016-10-25 13:41   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 05/21] qapi: rename QmpOutputVisitor to QObjectOutputVisitor Daniel P. Berrange
2016-10-25 13:36   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 06/21] qapi: don't pass two copies of TestInputVisitorData to tests Daniel P. Berrange
2016-09-30 17:43   ` Eric Blake
2016-10-06 14:39   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 07/21] qapi: permit scalar type conversions in QObjectInputVisitor Daniel P. Berrange
2016-09-30 17:48   ` Eric Blake
2016-10-11 16:20   ` Markus Armbruster
2016-10-12 14:51     ` Markus Armbruster
2016-10-12 15:05       ` Markus Armbruster [this message]
2016-10-12 15:26         ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 08/21] qapi: allow QObjectInputVisitor to be created with QemuOpts Daniel P. Berrange
2016-09-30 17:55   ` Eric Blake
2016-10-06 14:56   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-12  8:08   ` [Qemu-devel] " Markus Armbruster
2016-10-13  7:23     ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 09/21] qapi: permit auto-creating single element lists Daniel P. Berrange
2016-09-30 17:59   ` Eric Blake
2016-10-12  9:18   ` Markus Armbruster
2016-10-20 14:23     ` Daniel P. Berrange
2016-10-21 11:58       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 10/21] qapi: permit auto-creating nested structs Daniel P. Berrange
2016-09-30 18:23   ` Eric Blake
2016-10-06 15:10   ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-06 15:18     ` Daniel P. Berrange
2016-10-06 15:30       ` Kevin Wolf
2016-10-06 15:39         ` Daniel P. Berrange
2016-10-06 15:51           ` Kevin Wolf
2016-10-06 15:57             ` Daniel P. Berrange
2016-10-12 14:00               ` Markus Armbruster
2016-10-06 17:54         ` Eric Blake
2016-10-12 14:12   ` [Qemu-devel] " Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 11/21] qapi: add integer range support for QObjectInputVisitor Daniel P. Berrange
2016-09-30 19:45   ` Eric Blake
2016-10-12 15:50   ` Markus Armbruster
2016-10-12 16:03     ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2016-10-12 18:14       ` Markus Armbruster
2016-10-20 14:28     ` [Qemu-devel] " Daniel P. Berrange
2016-10-21 10:58       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 12/21] option: allow qemu_opts_to_qdict to merge repeated options Daniel P. Berrange
2016-09-30 20:08   ` Eric Blake
2016-10-12 17:46   ` Markus Armbruster
2016-10-13  9:21     ` Markus Armbruster
2016-10-20 14:29     ` Daniel P. Berrange
2016-10-21 11:09       ` Markus Armbruster
2016-10-21 11:14         ` Daniel P. Berrange
2016-10-13  8:31   ` Markus Armbruster
2016-10-20 14:37     ` Daniel P. Berrange
2016-10-21 11:28       ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 13/21] qdict: allow qdict_crumple to accept compound types as values Daniel P. Berrange
2016-10-13 12:35   ` Markus Armbruster
2016-10-13 14:46     ` Kevin Wolf
2016-10-17 14:50       ` Markus Armbruster
2016-10-17 15:43         ` Paolo Bonzini
2016-10-17 17:48           ` Markus Armbruster
2016-10-17 17:38         ` Eric Blake
2016-10-18 10:59           ` Markus Armbruster
2016-10-18  9:34         ` Kevin Wolf
2016-10-18 15:35           ` Markus Armbruster
2016-10-19  9:25             ` Kevin Wolf
2016-10-19  9:42               ` Daniel P. Berrange
2016-10-19 13:31             ` [Qemu-devel] [Qemu-block] " Eric Blake
2016-10-20 14:46     ` [Qemu-devel] " Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 14/21] qapi: allow repeated opts with qobject_input_visitor_new_opts Daniel P. Berrange
2016-10-18 17:13   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 15/21] qom: support non-scalar properties with -object Daniel P. Berrange
2016-10-19 16:54   ` Markus Armbruster
2017-07-10 19:30   ` Manos Pitsidianakis
2017-07-11  8:10     ` Markus Armbruster
2017-07-11 14:44       ` Markus Armbruster
2017-07-11 14:49         ` Daniel P. Berrange
2017-07-12 17:56           ` Manos Pitsidianakis
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 16/21] hmp: support non-scalar properties with object_add Daniel P. Berrange
2016-10-20  6:43   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 17/21] numa: convert to use QObjectInputVisitor for -numa Daniel P. Berrange
2016-10-20  6:57   ` Markus Armbruster
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 18/21] block: convert crypto driver to use QObjectInputVisitor Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 19/21] acpi: convert to QObjectInputVisitor for -acpi parsing Daniel P. Berrange
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 20/21] net: convert to QObjectInputVisitor for -net/-netdev parsing Daniel P. Berrange
2016-10-20  7:38   ` Markus Armbruster
2016-10-20 13:43     ` [Qemu-devel] [Qemu-block] " Eric Blake
2016-09-30 14:45 ` [Qemu-devel] [PATCH v14 21/21] qapi: delete unused OptsVisitor code Daniel P. Berrange
2016-09-30 15:45 ` [Qemu-devel] [PATCH v14 00/21] QAPI/QOM work for non-scalar object properties no-reply
2016-09-30 18:50   ` Eric Blake
2016-10-21 18:30 ` Markus Armbruster

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=874m4hsj3y.fsf@dusky.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=afaerber@suse.de \
    --cc=berrange@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.