tests: Clean up string interpolation into QMP input (simple cases)

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>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180806065344.7103-13-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2018-08-06 08:53:33 +02:00
parent 62fff696d5
commit 015715f554
6 changed files with 77 additions and 112 deletions

View File

@ -160,14 +160,9 @@ void qpci_free_pc(QPCIBus *bus)
void qpci_unplug_acpi_device_test(const char *id, uint8_t slot) void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
{ {
QDict *response; QDict *response;
char *cmd;
cmd = g_strdup_printf("{'execute': 'device_del'," response = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}",
" 'arguments': {" id);
" 'id': '%s'"
"}}", id);
response = qmp(cmd);
g_free(cmd);
g_assert(response); g_assert(response);
g_assert(!qdict_haskey(response, "error")); g_assert(!qdict_haskey(response, "error"));
qobject_unref(response); qobject_unref(response);

View File

@ -1054,12 +1054,9 @@ void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt,
void qtest_qmp_device_del(const char *id) void qtest_qmp_device_del(const char *id)
{ {
QDict *response1, *response2, *event = NULL; QDict *response1, *response2, *event = NULL;
char *cmd;
cmd = g_strdup_printf("{'execute': 'device_del'," response1 = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}",
" 'arguments': { 'id': '%s' }}", id); id);
response1 = qmp(cmd);
g_free(cmd);
g_assert(response1); g_assert(response1);
g_assert(!qdict_haskey(response1, "error")); g_assert(!qdict_haskey(response1, "error"));

View File

@ -532,14 +532,12 @@ static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest)
static void deprecated_set_downtime(QTestState *who, const double value) static void deprecated_set_downtime(QTestState *who, const double value)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd;
char *expected; char *expected;
int64_t result_int; int64_t result_int;
cmd = g_strdup_printf("{ 'execute': 'migrate_set_downtime'," rsp = qtest_qmp(who,
"'arguments': { 'value': %g } }", value); "{ 'execute': 'migrate_set_downtime',"
rsp = qtest_qmp(who, cmd); " 'arguments': { 'value': %f } }", value);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
result_int = value * 1000L; result_int = value * 1000L;

View File

@ -146,12 +146,11 @@ static void test_qga_sync_delimited(gconstpointer fix)
guint32 v, r = g_random_int(); guint32 v, r = g_random_int();
unsigned char c; unsigned char c;
QDict *ret; QDict *ret;
gchar *cmd;
cmd = g_strdup_printf("\xff{'execute': 'guest-sync-delimited'," qmp_fd_send(fixture->fd,
" 'arguments': {'id': %u } }", r); "\xff{'execute': 'guest-sync-delimited',"
qmp_fd_send(fixture->fd, cmd); " 'arguments': {'id': %u } }",
g_free(cmd); r);
/* /*
* Read and ignore garbage until resynchronized. * Read and ignore garbage until resynchronized.
@ -188,7 +187,6 @@ static void test_qga_sync(gconstpointer fix)
const TestFixture *fixture = fix; const TestFixture *fixture = fix;
guint32 v, r = g_random_int(); guint32 v, r = g_random_int();
QDict *ret; QDict *ret;
gchar *cmd;
/* /*
* TODO guest-sync is inherently limited: we cannot distinguish * TODO guest-sync is inherently limited: we cannot distinguish
@ -201,10 +199,9 @@ static void test_qga_sync(gconstpointer fix)
* invalid JSON. Testing of '\xff' handling is done in * invalid JSON. Testing of '\xff' handling is done in
* guest-sync-delimited instead. * guest-sync-delimited instead.
*/ */
cmd = g_strdup_printf("{'execute': 'guest-sync'," ret = qmp_fd(fixture->fd,
" 'arguments': {'id': %u } }", r); "{'execute': 'guest-sync', 'arguments': {'id': %u } }",
ret = qmp_fd(fixture->fd, cmd); r);
g_free(cmd);
g_assert_nonnull(ret); g_assert_nonnull(ret);
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
@ -428,7 +425,7 @@ static void test_qga_file_ops(gconstpointer fix)
const TestFixture *fixture = fix; const TestFixture *fixture = fix;
const unsigned char helloworld[] = "Hello World!\n"; const unsigned char helloworld[] = "Hello World!\n";
const char *b64; const char *b64;
gchar *cmd, *path, *enc; gchar *path, *enc;
unsigned char *dec; unsigned char *dec;
QDict *ret, *val; QDict *ret, *val;
int64_t id, eof; int64_t id, eof;
@ -446,10 +443,10 @@ static void test_qga_file_ops(gconstpointer fix)
enc = g_base64_encode(helloworld, sizeof(helloworld)); enc = g_base64_encode(helloworld, sizeof(helloworld));
/* write */ /* write */
cmd = g_strdup_printf("{'execute': 'guest-file-write'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "," "{'execute': 'guest-file-write',"
" 'buf-b64': '%s' } }", id, enc); " 'arguments': { 'handle': %" PRId64 ", 'buf-b64': %s } }",
ret = qmp_fd(fixture->fd, cmd); id, enc);
g_assert_nonnull(ret); g_assert_nonnull(ret);
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
@ -459,23 +456,20 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert_cmpint(count, ==, sizeof(helloworld)); g_assert_cmpint(count, ==, sizeof(helloworld));
g_assert_cmpint(eof, ==, 0); g_assert_cmpint(eof, ==, 0);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* flush */ /* flush */
cmd = g_strdup_printf("{'execute': 'guest-file-flush'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-flush',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* close */ /* close */
cmd = g_strdup_printf("{'execute': 'guest-file-close'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-close',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* check content */ /* check content */
path = g_build_filename(fixture->test_dir, "foo", NULL); path = g_build_filename(fixture->test_dir, "foo", NULL);
@ -497,10 +491,10 @@ static void test_qga_file_ops(gconstpointer fix)
qobject_unref(ret); qobject_unref(ret);
/* read */ /* read */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
@ -510,14 +504,13 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert_cmpstr(b64, ==, enc); g_assert_cmpstr(b64, ==, enc);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
g_free(enc); g_free(enc);
/* read eof */ /* read eof */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
@ -526,14 +519,13 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert(eof); g_assert(eof);
g_assert_cmpstr(b64, ==, ""); g_assert_cmpstr(b64, ==, "");
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* seek */ /* seek */
cmd = g_strdup_printf("{'execute': 'guest-file-seek'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 ", " "{'execute': 'guest-file-seek',"
" 'offset': %d, 'whence': '%s' } }", " 'arguments': { 'handle': %" PRId64 ", "
id, 6, "set"); " 'offset': %d, 'whence': %s } }",
ret = qmp_fd(fixture->fd, cmd); id, 6, "set");
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "position"); count = qdict_get_int(val, "position");
@ -541,13 +533,12 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert_cmpint(count, ==, 6); g_assert_cmpint(count, ==, 6);
g_assert(!eof); g_assert(!eof);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* partial read */ /* partial read */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
@ -560,15 +551,13 @@ static void test_qga_file_ops(gconstpointer fix)
g_free(dec); g_free(dec);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* close */ /* close */
cmd = g_strdup_printf("{'execute': 'guest-file-close'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-close',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
} }
static void test_qga_file_write_read(gconstpointer fix) static void test_qga_file_write_read(gconstpointer fix)
@ -576,7 +565,7 @@ static void test_qga_file_write_read(gconstpointer fix)
const TestFixture *fixture = fix; const TestFixture *fixture = fix;
const unsigned char helloworld[] = "Hello World!\n"; const unsigned char helloworld[] = "Hello World!\n";
const char *b64; const char *b64;
gchar *cmd, *enc; gchar *enc;
QDict *ret, *val; QDict *ret, *val;
int64_t id, eof; int64_t id, eof;
gsize count; gsize count;
@ -591,10 +580,10 @@ static void test_qga_file_write_read(gconstpointer fix)
enc = g_base64_encode(helloworld, sizeof(helloworld)); enc = g_base64_encode(helloworld, sizeof(helloworld));
/* write */ /* write */
cmd = g_strdup_printf("{'execute': 'guest-file-write'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "," "{'execute': 'guest-file-write',"
" 'buf-b64': '%s' } }", id, enc); " 'arguments': { 'handle': %" PRId64 ","
ret = qmp_fd(fixture->fd, cmd); " 'buf-b64': %s } }", id, enc);
g_assert_nonnull(ret); g_assert_nonnull(ret);
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
@ -604,13 +593,12 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert_cmpint(count, ==, sizeof(helloworld)); g_assert_cmpint(count, ==, sizeof(helloworld));
g_assert_cmpint(eof, ==, 0); g_assert_cmpint(eof, ==, 0);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* read (check implicit flush) */ /* read (check implicit flush) */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
@ -619,14 +607,13 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert(eof); g_assert(eof);
g_assert_cmpstr(b64, ==, ""); g_assert_cmpstr(b64, ==, "");
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* seek to 0 */ /* seek to 0 */
cmd = g_strdup_printf("{'execute': 'guest-file-seek'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 ", " "{'execute': 'guest-file-seek',"
" 'offset': %d, 'whence': '%s' } }", " 'arguments': { 'handle': %" PRId64 ", "
id, 0, "set"); " 'offset': %d, 'whence': %s } }",
ret = qmp_fd(fixture->fd, cmd); id, 0, "set");
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "position"); count = qdict_get_int(val, "position");
@ -634,13 +621,12 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert_cmpint(count, ==, 0); g_assert_cmpint(count, ==, 0);
g_assert(!eof); g_assert(!eof);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* read */ /* read */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
@ -649,16 +635,14 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert(eof); g_assert(eof);
g_assert_cmpstr(b64, ==, enc); g_assert_cmpstr(b64, ==, enc);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
g_free(enc); g_free(enc);
/* close */ /* close */
cmd = g_strdup_printf("{'execute': 'guest-file-close'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-close',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
} }
static void test_qga_get_time(gconstpointer fix) static void test_qga_get_time(gconstpointer fix)
@ -814,7 +798,6 @@ static void test_qga_guest_exec(gconstpointer fix)
int64_t pid, now, exitcode; int64_t pid, now, exitcode;
gsize len; gsize len;
bool exited; bool exited;
char *cmd;
/* exec 'echo foo bar' */ /* exec 'echo foo bar' */
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
@ -829,10 +812,10 @@ static void test_qga_guest_exec(gconstpointer fix)
/* wait for completion */ /* wait for completion */
now = g_get_monotonic_time(); now = g_get_monotonic_time();
cmd = g_strdup_printf("{'execute': 'guest-exec-status',"
" 'arguments': { 'pid': %" PRId64 " } }", pid);
do { do {
ret = qmp_fd(fixture->fd, cmd); ret = qmp_fd(fixture->fd,
"{'execute': 'guest-exec-status',"
" 'arguments': { 'pid': %" PRId64 " } }", pid);
g_assert_nonnull(ret); g_assert_nonnull(ret);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
exited = qdict_get_bool(val, "exited"); exited = qdict_get_bool(val, "exited");
@ -842,7 +825,6 @@ static void test_qga_guest_exec(gconstpointer fix)
} while (!exited && } while (!exited &&
g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
g_assert(exited); g_assert(exited);
g_free(cmd);
/* check stdout */ /* check stdout */
exitcode = qdict_get_int(val, "exitcode"); exitcode = qdict_get_int(val, "exitcode");

View File

@ -239,13 +239,10 @@ void tpm_util_swtpm_kill(GPid pid)
void tpm_util_migrate(QTestState *who, const char *uri) void tpm_util_migrate(QTestState *who, const char *uri)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd;
cmd = g_strdup_printf("{ 'execute': 'migrate'," rsp = qtest_qmp(who,
"'arguments': { 'uri': '%s' } }", "{ 'execute': 'migrate', 'arguments': { 'uri': %s } }",
uri); uri);
rsp = qtest_qmp(who, cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
} }

View File

@ -709,11 +709,7 @@ static void test_migrate(void)
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
cmd = g_strdup_printf("{ 'execute': 'migrate'," rsp = qmp("{ 'execute': 'migrate', 'arguments': { 'uri': %s } }", uri);
"'arguments': { 'uri': '%s' } }",
uri);
rsp = qmp(cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);