Daniel P. Berrangé <berrange(a)redhat.com> writes:
On Mon, Feb 22, 2021 at 06:47:30PM +0100, Paolo Bonzini wrote:
> On 22/02/21 16:24, Daniel P. Berrangé wrote:
> > This problem isn't unique to QEMU. Any app using JSON from the
> > shell will have the tedium of quote escaping. JSON is incredibly
> > widespread and no other apps felt it neccessary to introduce single
> > quoting support, because the benefit doesn't outweigh the interop
> > problem it introduces.
>
> The quotes were introduced for C code (and especially qtest), not for the
> shell. We have something like
>
> response = qmp("{ 'execute': 'qom-get', 'arguments':
{ 'path': %s, "
> "'property': 'temperature' } }", id);
>
> These are sent to QEMU as double-quoted strings (the single-quoted JSON is
> parsed to get interpolation and printed back; commit 563890c7c7, "libqtest:
> escape strings in QMP commands, fix leak", 2014-07-01). However, doing the
> interpolation requires a parser that recognizes the single-quoted strings.
IMHO this is the wrong solution to the problem. Consider the equivalent
libvirt code that uses a standard JSON library underneath and has a high
level API to serialize args into the command
qemuMonitorJSONMakeCommand("qom-get",
"s:path", id,
"s:property", "temperature");
Of course this example is reasonably easy since it is a flat set of
arguments. Nested args get slightly more complicated, but still always
preferrable to doing string interpolation IMHO.
Misunderstanding: our JSON interpolation feature is *not* string
interpolation! It interpolates *objects* into the QObject built by the
parser.
Best explained with an example. The qmp() call above internally builds
the following QObject:
QDict mapping
key "execute" to a QString for "qom-get"
key "arguments" to a QDict mapping
key "path" to a QString for @id (interpolation!)
key "property" to a QString for "temperature"
Unlike string interpolation, this is safe for any valid C string @id.
If you think like a hacker, you might try shenanigans like
"{'execute': '%s'}"
You will then find that somebody has thought like a hacker before
you[*].
The %-sequences are cleverly chosen to get some protection against
common mistakes from the compiler.
This interpolation has worked quite well for us, and I have no plans to
replace it. Doesn't mean I'm against replacing it, only that I want to
see benefits exceeding the costs.
A bigger stumbling block for replacement is our need for a streaming
interface: we feed the parser characters, and expect to be called back
when an expression is complete.
[*] Commit 16a4859921 "json: Improve safety of
qobject_from_jsonf_nofail() & friends", fixed up in commit bbc0586ced
"json: Fix % handling when not interpolating".