From: Markus Armbruster <armbru@redhat.com>
To: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
Cc: Markus Armbruster <armbru@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 11/20] tests: Clean up string interpolation into QMP input (simple cases)
Date: Mon, 16 Jul 2018 08:27:02 +0200 [thread overview]
Message-ID: <87tvozitl5.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <7ae3d760-7097-c95e-67a5-266cc9357964@amsat.org> ("Philippe Mathieu-Daudé"'s message of "Thu, 12 Jul 2018 11:30:30 -0300")
Philippe Mathieu-Daudé <f4bug@amsat.org> writes:
> Hi Markus,
>
> On 07/12/2018 08:12 AM, Markus Armbruster wrote:
>> When you build QMP input manually like this
>>
>> cmd = g_strdup_printf("{ 'execute': 'migrate',"
>> "'arguments': { 'uri': '%s' } }",
>> uri);
>> rsp = qmp(cmd);
>> g_free(cmd);
>>
>> you're responsible for escaping the interpolated values for JSON. Not
>> done here, and therefore works only for sufficiently nice @uri. For
>> instance, if @uri contained a single "'", qobject_from_vjsonf_nofail()
>> would abort. A sufficiently nasty @uri could even inject unwanted
>> members into the arguments object.
>>
>> Leaving interpolation into JSON to qmp() is more robust:
>>
>> rsp = qmp("{ 'execute': 'migrate', 'arguments': { 'uri': %s } }", uri);
>>
>> It's also more concise.
>>
>> Clean up the simple cases where we interpolate exactly a JSON value.
>>
>> Bonus: gets rid of non-literal format strings. A step towards
>> compile-time format string checking without triggering
>> -Wformat-nonliteral.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>> tests/libqos/pci-pc.c | 9 +--
>> tests/libqtest.c | 7 +-
>> tests/migration-test.c | 8 +--
>> tests/test-qga.c | 150 ++++++++++++++++++----------------------
>> tests/tpm-util.c | 9 +--
>> tests/vhost-user-test.c | 6 +-
>> 6 files changed, 77 insertions(+), 112 deletions(-)
>>
>> diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
>> index a7803308b7..585f5289ec 100644
>> --- a/tests/libqos/pci-pc.c
>> +++ b/tests/libqos/pci-pc.c
>> @@ -160,14 +160,9 @@ void qpci_free_pc(QPCIBus *bus)
>> void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
>> {
>> QDict *response;
>> - char *cmd;
>>
>> - cmd = g_strdup_printf("{'execute': 'device_del',"
>> - " 'arguments': {"
>> - " 'id': '%s'"
>> - "}}", id);
>> - response = qmp(cmd);
>> - g_free(cmd);
>> + response = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}",
>> + id);
>> g_assert(response);
>> g_assert(!qdict_haskey(response, "error"));
>> qobject_unref(response);
>> diff --git a/tests/libqtest.c b/tests/libqtest.c
>> index 3bfb062fcb..e36cc5ede3 100644
>> --- a/tests/libqtest.c
>> +++ b/tests/libqtest.c
>> @@ -1079,12 +1079,9 @@ void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt,
>> void qtest_qmp_device_del(const char *id)
>> {
>> QDict *response1, *response2, *event = NULL;
>> - char *cmd;
>>
>> - cmd = g_strdup_printf("{'execute': 'device_del',"
>> - " 'arguments': { 'id': '%s' }}", id);
>> - response1 = qmp(cmd);
>> - g_free(cmd);
>> + response1 = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}",
>> + id);
>> g_assert(response1);
>> g_assert(!qdict_haskey(response1, "error"));
>>
>> diff --git a/tests/migration-test.c b/tests/migration-test.c
>> index 086f727b34..bbb9d3da31 100644
>> --- a/tests/migration-test.c
>> +++ b/tests/migration-test.c
>> @@ -529,14 +529,12 @@ static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest)
>> static void deprecated_set_downtime(QTestState *who, const double value)
>> {
>> QDict *rsp;
>> - gchar *cmd;
>> char *expected;
>> int64_t result_int;
>>
>> - cmd = g_strdup_printf("{ 'execute': 'migrate_set_downtime',"
>> - "'arguments': { 'value': %g } }", value);
>> - rsp = qtest_qmp(who, cmd);
>> - g_free(cmd);
>> + rsp = qtest_qmp(who,
>> + "{ 'execute': 'migrate_set_downtime',"
>> + " 'arguments': { 'value': %f } }", value);
>
> I suppose you changed %g -> %f because the downtime is expected
> to be greater than 1e-4 :)
Actually, I changed it to %f, because %g would crash :)
qtest_qmp()'s function comment provides a clue:
* @fmt...: QMP message to send to qemu; formats arguments through
* json-lexer.c (only understands '%((l|ll|I64)?d|[ipsf])').
This isn't your ordinary printf()-like formatting, it's JSON
interpolation. JSON interpolation borrows its escapes from printf() to
get some compile-time checking out of GCC function attribute 'format',
namely catching arguments that don't match escapes. It can't catch
escapes JSON interpolation doesn't support. Much better than nothing.
In particular, JSON interpolation supports %f but not %g.
Hmm, the comment's claim "json-lexer.c" is perhaps overly specific.
json-lexer.c recognizes valid %-escapes, but the actual interpolation is
done by json-parser.c's parse_escape().
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Thanks!
[...]
next prev parent reply other threads:[~2018-07-16 6:27 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-12 11:12 [Qemu-devel] [PATCH 00/20] tests: Compile-time format string checking for libqtest.h Markus Armbruster
2018-07-12 11:12 ` [Qemu-devel] [PATCH 01/20] libqtest: Document calling conventions Markus Armbruster
2018-07-12 11:12 ` [Qemu-devel] [PATCH 02/20] libqtest: Rename functions to send QMP messages Markus Armbruster
2018-07-12 14:21 ` Philippe Mathieu-Daudé
2018-07-12 11:12 ` [Qemu-devel] [PATCH 03/20] libqtest: Clean up how we read device_del messages Markus Armbruster
2018-07-12 14:22 ` Philippe Mathieu-Daudé
2018-07-12 16:24 ` Thomas Huth
2018-07-12 11:12 ` [Qemu-devel] [PATCH 04/20] libqtest: Clean up how we read the QMP greeting Markus Armbruster
2018-07-12 16:26 ` Thomas Huth
2018-07-16 6:16 ` Markus Armbruster
2018-07-12 11:12 ` [Qemu-devel] [PATCH 05/20] qobject: Replace qobject_from_jsonf() by qobject_from_jsonf_nofail() Markus Armbruster
2018-07-12 18:17 ` Thomas Huth
2018-07-16 6:17 ` Markus Armbruster
2018-07-12 11:12 ` [Qemu-devel] [PATCH 06/20] qobject: New qobject_from_vjsonf_nofail(), qdict_from_vjsonf_nofail() Markus Armbruster
2018-07-12 14:06 ` Philippe Mathieu-Daudé
2018-07-12 11:12 ` [Qemu-devel] [PATCH 07/20] libqtest: Simplify qmp_fd_vsend() a bit Markus Armbruster
2018-07-12 14:07 ` Philippe Mathieu-Daudé
2018-07-12 11:12 ` [Qemu-devel] [PATCH 08/20] test-qobject-input-visitor: Avoid format string ambiguity Markus Armbruster
2018-07-12 11:12 ` [Qemu-devel] [PATCH 09/20] qobject: qobject_from_jsonv() is dangerous, hide it away Markus Armbruster
2018-07-12 14:09 ` Philippe Mathieu-Daudé
2018-07-12 11:12 ` [Qemu-devel] [PATCH 10/20] tests: Pass literal format strings directly to qmp_FOO() Markus Armbruster
2018-07-12 14:03 ` Philippe Mathieu-Daudé
2018-07-12 11:12 ` [Qemu-devel] [PATCH 11/20] tests: Clean up string interpolation into QMP input (simple cases) Markus Armbruster
2018-07-12 14:30 ` Philippe Mathieu-Daudé
2018-07-16 6:27 ` Markus Armbruster [this message]
2018-07-12 11:12 ` [Qemu-devel] [PATCH 12/20] cpu-plug-test: Don't pass integers as strings to device_add Markus Armbruster
2018-07-12 14:31 ` Philippe Mathieu-Daudé
2018-07-12 15:38 ` Thomas Huth
2018-07-12 11:12 ` [Qemu-devel] [PATCH 13/20] tests: Clean up string interpolation around qtest_qmp_device_add() Markus Armbruster
2018-07-12 11:12 ` [Qemu-devel] [PATCH 14/20] migration-test: Make wait_command() return the "return" member Markus Armbruster
2018-07-12 11:21 ` Juan Quintela
2018-07-12 11:12 ` [Qemu-devel] [PATCH 15/20] tests: New helper qtest_qmp_receive_success() Markus Armbruster
2018-07-12 11:22 ` Juan Quintela
2018-07-13 1:35 ` Stefan Berger
2018-07-12 11:12 ` [Qemu-devel] [PATCH 16/20] migration-test: Make wait_command() cope with '%' Markus Armbruster
2018-07-12 11:23 ` Juan Quintela
2018-07-12 11:12 ` [Qemu-devel] [PATCH 17/20] migration-test: Clean up string interpolation into QMP, part 1 Markus Armbruster
2018-07-12 11:25 ` Juan Quintela
2018-07-16 6:37 ` Markus Armbruster
2018-07-12 11:12 ` [Qemu-devel] [PATCH 18/20] migration-test: Clean up string interpolation into QMP, part 2 Markus Armbruster
2018-07-12 11:27 ` Juan Quintela
2018-07-12 11:12 ` [Qemu-devel] [PATCH 19/20] migration-test: Clean up string interpolation into QMP, part 3 Markus Armbruster
2018-07-12 11:31 ` Juan Quintela
2018-07-12 11:12 ` [Qemu-devel] [PATCH 20/20] libqtest: Enable compile-time format string checking Markus Armbruster
2018-07-12 14:16 ` Philippe Mathieu-Daudé
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=87tvozitl5.fsf@dusky.pond.sub.org \
--to=armbru@redhat.com \
--cc=f4bug@amsat.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.