- Feb 04, 2021
-
-
Zhang Han authored
Add braces {} for arms of if/for statement Signed-off-by:
Zhang Han <zhanghan64@huawei.com> Message-Id: <20201228071129.24563-5-zhanghan64@huawei.com> Reviewed-by:
Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by:
Markus Armbruster <armbru@redhat.com> Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
Zhang Han authored
Add spaces around operators. Signed-off-by:
Zhang Han <zhanghan64@huawei.com> Message-Id: <20201228071129.24563-4-zhanghan64@huawei.com> Reviewed-by:
Markus Armbruster <armbru@redhat.com> Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
Zhang Han authored
Transfer tabs to spaces. Signed-off-by:
Zhang Han <zhanghan64@huawei.com> Message-Id: <20201228071129.24563-3-zhanghan64@huawei.com> Reviewed-by:
Markus Armbruster <armbru@redhat.com> Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
Zhang Han authored
Put open brace '{' on the same line of struct. Signed-off-by:
Zhang Han <zhanghan64@huawei.com> Message-Id: <20201228071129.24563-2-zhanghan64@huawei.com> Reviewed-by:
Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by:
Markus Armbruster <armbru@redhat.com> Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
- Dec 19, 2020
-
-
Markus Armbruster authored
The functions to modify a QString's string are all unused now. Drop them, and make the string immutable. Saves 16 bytes per QString on my system. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-21-armbru@redhat.com>
-
Markus Armbruster authored
QString supports modifying its string, but it's quite limited: you can only append. The remaining callers use it for building an initial string, never for modifying it later. Change parse_string() to do build the initial string with GString. This is another step towards making QString immutable. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-18-armbru@redhat.com>
-
Markus Armbruster authored
We have two JSON writers written in C: qobject/qjson.c provides qobject_to_json(), and migration/qjson.c provides a more low level imperative interface. They don't share code. The latter tacitly limits numbers to int64_t, and strings contents to characters that don't need escaping. Factor out qobject_to_json()'s JSON writer as qobject/json-writer.c. Straightforward, except for numbers: since the writer is to be independent of QObject, it can't use qnum_to_string(). Open-code it instead. This is actually an improvement of sorts, because it liberates qnum_to_string() from JSON's needs: its JSON-related FIXMEs move to the JSON writer, where they belong. The next commit will replace migration/qjson.c. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-16-armbru@redhat.com>
-
Markus Armbruster authored
Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-15-armbru@redhat.com>
-
Markus Armbruster authored
No users left outside tests/, and the ones in tests/ can just as well use qstring_get_str(). Do that, and drop the function. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-14-armbru@redhat.com>
-
Markus Armbruster authored
Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-13-armbru@redhat.com>
-
Markus Armbruster authored
Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-9-armbru@redhat.com>
-
Markus Armbruster authored
This reverts commit 164c374b. A free function for a reference-counted object is in bad taste. Fortunately, this one is now also unused. Drop it. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-7-armbru@redhat.com>
-
Markus Armbruster authored
qobject_to_json() and qobject_to_json_pretty() build a GString, then covert it to QString. Just one of the callers actually needs a QString: qemu_rbd_parse_filename(). A few others need a string they can modify: qmp_send_response(), qga's send_response(), to_json_str(), and qmp_fd_vsend_fds(). The remainder just need a string. Change qobject_to_json() and qobject_to_json_pretty() to return the GString. qemu_rbd_parse_filename() now has to convert to QString. All others save a QString temporary. to_json_str() actually becomes a bit simpler, because GString provides more convenient modification functions. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-6-armbru@redhat.com>
-
Markus Armbruster authored
QString supports modifying its string, but it's quite limited: you can only append. The remaining callers use it for building an initial string, never for modifying it later. Use of GString for building the initial string is actually more convenient here. Change qobject_to_json() & friends to do that. Once all such uses are replaced this way, QString can become immutable. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-5-armbru@redhat.com>
-
Markus Armbruster authored
Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201211171152.146877-4-armbru@redhat.com>
-
Markus Armbruster authored
We should serialize numbers to JSON so that they deserialize back to the same number. We fail to do so. The culprit is qnum_to_string(): it uses format %f with trailing '0' trimmed. Results in pretty output for "nice" numbers, but is prone to nasty rounding errors. For instance, numbers between 0 and 0.0000005 get flushed to zero. Where exactly the incorrect rounding can bite is tiresome to gauge. Here's my take. * In QMP output, type 'number': - query-blockstats value avg_rd_queue_depth - QMP query-migrate values mbps, cache-miss-rate, encoding-rate, busy-rate, compression-rate. Relatively harmless, I guess. * In tracing QMP input. Harmless. * In qemu-ga output, type 'number': guest-get-users value login-time. Harmless. * In output of HMP qom-get. Harmless. Not affected, because double values don't actually occur there (I think): * QMP output, type 'any': * qom-get value * qom-list, qom-list-properties value default-value * query-cpu-model-comparison, query-cpu-model-baseline, query-cpu-model-expansion value props. * qemu-img --output json output. * "json:" pseudo-filenames generated by bdrv_refresh_filename(). * The rbd block driver's "=keyvalue-pairs" hack. * In -object help on property default values. Aside: use of JSON feels inappropriate here. * Output of HMP qom-get. * Argument conversion to QemuOpts for qdev_device_add() and HMP with qemu_opts_from_qdict() QMP and HMP device_add, virtio-net failover primary creation, xen-usb "usb-host" creation, HMP netdev_add, object_add. * The uses of qobject_input_visitor_new_flat_confused() As far as I can tell, none of the visited types contain double values. * Dumping ImageInfoSpecific with dump_qobject() Fix by formatting with %.17g. 17 decimal digits always suffice for IEEE double. The change to expected test output illustrates the effect: the rounding errors are gone, but some seemingly "nice" numbers now get converted to not so nice strings, e.g. 0.42 to "0.41999999999999998". This is because 0.42 is not representable exactly in double. It's more accurate in this example than strictly necessary, though. If ugly accuracy bothers us, we can we can try using the least number of digits that still converts back to the same double. In this example, "0.42" would do. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201210161452.2813491-7-armbru@redhat.com>
-
- Nov 17, 2020
-
-
Alex Chen authored
In qobject_type(), NULL is returned when the 'QObject' returned from parse_value() is not of QString type, and this 'QObject' memory will leaked. So we need to first cache the 'QObject' returned from parse_value(), and finally free 'QObject' memory at the end of the function. Also, we add a testcast about invalid dict key. The memleak stack is as follows: Direct leak of 32 byte(s) in 1 object(s) allocated from: #0 0xfffe4b3c34fb in __interceptor_malloc (/lib64/libasan.so.4+0xd34fb) #1 0xfffe4ae48aa3 in g_malloc (/lib64/libglib-2.0.so.0+0x58aa3) #2 0xaaab3557d9f7 in qnum_from_int qemu/qobject/qnum.c:25 #3 0xaaab35584d23 in parse_literal qemu/qobject/json-parser.c:511 #4 0xaaab35584d23 in parse_value qemu/qobject/json-parser.c:554 #5 0xaaab35583d77 in parse_pair qemu/qobject/json-parser.c:270 #6 0xaaab355845db in parse_object qemu/qobject/json-parser.c:327 #7 0xaaab355845db in parse_value qemu/qobject/json-parser.c:546 #8 0xaaab35585b1b in json_parser_parse qemu/qobject/json-parser.c:580 #9 0xaaab35583703 in json_message_process_token qemu/qobject/json-streamer.c:92 #10 0xaaab355ddccf in json_lexer_feed_char qemu/qobject/json-lexer.c:313 #11 0xaaab355de0eb in json_lexer_feed qemu/qobject/json-lexer.c:350 #12 0xaaab354aff67 in tcp_chr_read qemu/chardev/char-socket.c:525 #13 0xfffe4ae429db in g_main_context_dispatch (/lib64/libglib-2.0.so.0+0x529db) #14 0xfffe4ae42d8f (/lib64/libglib-2.0.so.0+0x52d8f) #15 0xfffe4ae430df in g_main_loop_run (/lib64/libglib-2.0.so.0+0x530df) #16 0xaaab34d70bff in iothread_run qemu/iothread.c:82 #17 0xaaab3559d71b in qemu_thread_start qemu/util/qemu-thread-posix.c:519 Fixes: 532fb532 ("qapi: Make more of qobject_to()") Reported-by:
Euler Robot <euler.robot@huawei.com> Signed-off-by:
Alex Chen <alex.chen@huawei.com> Signed-off-by:
Chen Qun <kuhn.chenqun@huawei.com> Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20201113145525.85151-1-alex.chen@huawei.com> [Commit message tweaked]
-
- Sep 17, 2020
-
-
zhaolichang authored
I found that there are many spelling errors in the comments of qemu, so I used the spellcheck tool to check the spelling errors and finally found some spelling errors in the folder. Signed-off-by:
zhaolichang <zhaolichang@huawei.com> Reviewed-by:
Alex Bennee <alex.bennee@linaro.org> Message-Id: <20200917075029.313-2-zhaolichang@huawei.com> Signed-off-by:
Laurent Vivier <laurent@vivier.eu>
-
- Aug 21, 2020
-
-
Paolo Bonzini authored
This shows how to do some "computations" in meson.build using its array and dictionary data structures, and also a basic usage of the sourceset module for conditional compilation. Notice the new "if have_system" part of util/meson.build, which fixes a bug in the old build system was buggy: util/dbus.c was built even for non-softmmu builds, but the dependency on -lgio was lost when the linking was done through libqemuutil.a. Because all of its users required gio otherwise, the bug was hidden. Meson instead propagates libqemuutil's dependencies down to its users, and shows the problem. Signed-off-by:
Paolo Bonzini <pbonzini@redhat.com>
-
- Apr 30, 2020
-
-
Markus Armbruster authored
qdict_iter() has just three uses and no test coverage. Replace by qdict_first(), qdict_next() for more concise code and less type punning. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20200415083048.14339-5-armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com>
-
Markus Armbruster authored
qlist_iter() has just three uses outside tests/. Replace by QLIST_FOREACH_ENTRY() for more concise code and less type punning. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20200415083048.14339-4-armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com>
-
Markus Armbruster authored
Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20200415083048.14339-3-armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> [Coding style in moved code tidied up]
-
- Apr 07, 2020
-
-
Simran Singhal authored
We immediately diagnose unbalanced right curly brace: $ qemu-kvm --nodefaults --nographic --qmp stdio {"QMP": {"version": {"qemu": {"micro": 91, "minor": 2, "major": 4}, "package": "v5.0.0-rc1-1-gf6ce4a439a08"}, "capabilities": ["oob"]}} } {"error": {"class": "GenericError", "desc": "JSON parse error, expecting value"}} except within square bracket: [} The check for unbalanced braces has a typo. Fix it. Fixes: 8d3265b3 Signed-off-by:
Simran Singhal <singhalsimran0@gmail.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20200402182848.GA3023@simran-Inspiron-5558> Reviewed-by:
Markus Armbruster <armbru@redhat.com> [Commit message rewritten to explain what's broken] Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
- Jan 24, 2020
-
-
Marc-André Lureau authored
Similar to g_string_free(), optionally return the underlying char*. Signed-off-by:
Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20200110153039.1379601-10-marcandre.lureau@redhat.com> Signed-off-by:
Paolo Bonzini <pbonzini@redhat.com>
-
- Aug 21, 2019
-
-
Philippe Mathieu-Daudé authored
Reported by GCC9 when building with CFLAG -Wimplicit-fallthrough=2: qobject/json-parser.c: In function ‘parse_literal’: qobject/json-parser.c:492:24: error: this statement may fall through [-Werror=implicit-fallthrough=] 492 | case JSON_INTEGER: { | ^ qobject/json-parser.c:524:5: note: here 524 | case JSON_FLOAT: | ^~~~ Correctly place the 'fall through' comment. Reported-by:
Stefan Weil <sw@weilnetz.de> Signed-off-by:
Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20190719131425.10835-2-philmd@redhat.com> Signed-off-by:
Laurent Vivier <laurent@vivier.eu>
-
- Jun 11, 2019
-
-
Markus Armbruster authored
Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20190523143508.25387-3-armbru@redhat.com> Reviewed-by:
Richard Henderson <richard.henderson@linaro.org>
-
- Mar 26, 2019
-
-
Liam Merwick authored
The assert checking if the value of lexer->state in next_state(), which is used as an index to the 'json_lexer' array, incorrectly checks for an index value less than or equal to ARRAY_SIZE(json_lexer). Fix assert so that it just checks for an index less than the array size. Signed-off-by:
Liam Merwick <liam.merwick@oracle.com> Message-Id: <1553169472-25325-1-git-send-email-liam.merwick@oracle.com> Reviewed-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Li Qiang <liq3ea@gmail.com> Reviewed-by:
Stefano Garzarella <sgarzare@redhat.com> Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
- Jan 24, 2019
-
-
Christophe Fergeau authored
Commit 8bca4613 added support for %% in json strings when interpolating, but in doing so broke handling of % when not interpolating. When parse_string() is fed a string token containing '%', it skips the '%' regardless of ctxt->ap, i.e. even it's not interpolating. If the '%' is the string's last character, it fails an assertion. Else, it "merely" swallows the '%'. Fix parse_string() to handle '%' specially only when interpolating. To gauge the bug's impact, let's review non-interpolating users of this parser, i.e. code passing NULL context to json_message_parser_init(): * tests/check-qjson.c, tests/test-qobject-input-visitor.c, tests/test-visitor-serialization.c Plenty of tests, but we still failed to cover the buggy case. * monitor.c: QMP input * qga/main.c: QGA input * qobject_from_json(): - qobject-input-visitor.c: JSON command line option arguments of -display and -blockdev Reproducer: -blockdev '{"%"}' - block.c: JSON pseudo-filenames starting with "json:" Reproducer: https://bugzilla.redhat.com/show_bug.cgi?id=1668244#c3 - block/rbd.c: JSON key pairs Pseudo-filenames starting with "rbd:". Command line, QMP and QGA input are trusted. Filenames are trusted when they come from command line, QMP or HMP. They are untrusted when they come from from image file headers. Example: QCOW2 backing file name. Note that this is *not* the security boundary between host and guest. It's the boundary between host and an image file from an untrusted source. Neither failing an assertion nor skipping a character in a filename of your choice looks exploitable. Note that we don't support compiling with NDEBUG. Fixes: 8bca4613 Cc: qemu-stable@nongnu.org Signed-off-by:
Christophe Fergeau <cfergeau@redhat.com> Message-Id: <20190102140535.11512-1-cfergeau@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Tested-by:
Richard W.M. Jones <rjones@redhat.com> [Commit message extended to discuss impact] Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
- Dec 13, 2018
-
-
Markus Armbruster authored
The JSON parser happily accepts duplicate object member names. The last value wins. Reproducer #1: $ qemu-system-x86_64 -qmp stdio {"QMP": {"version": {"qemu": {"micro": 93, "minor": 0, "major": 3}, "package": "v3.1.0-rc3-7-g87a45d86ed"}, "capabilities": []}} {'execute':'qmp_capabilities'} {"return": {}} {'execute':'blockdev-add','arguments':{'driver':'null-co', 'node-name':'foo','node-name':'bar'}} {"return": {}} {'execute':'query-named-block-nodes'} {"return": [{ [...] "node-name": "bar" [...] }]} Reproducer #2 is iotest 229. Fix the parser to reject duplicates, and fix iotest 229 not to use them. Reported-by:
Max Reitz <mreitz@redhat.com> Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20181206121743.20762-1-armbru@redhat.com> Reviewed-by:
Daniel P. Berrangé <berrange@redhat.com> Reviewed-by:
Philippe Mathieu-Daudé <philmd@redhat.com> [Trailing whitespace tidied up] Signed-off-by:
Markus Armbruster <armbru@redhat.com>
-
- Oct 26, 2018
-
-
Philippe Mathieu-Daudé authored
Patch created mechanically by rerunning: $ spatch --sp-file scripts/coccinelle/qobject.cocci \ --macro-file scripts/cocci-macro-file.h \ --dir . --in-place Signed-off-by:
Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by:
Markus Armbruster <armbru@redhat.com> Acked-by:
Michael S. Tsirkin <mst@redhat.com> Message-Id: <20180705155811.20366-2-f4bug@amsat.org> Signed-off-by:
Laurent Vivier <laurent@vivier.eu>
-
- Sep 24, 2018
-
-
Markus Armbruster authored
The lexer ignores whitespace like this: on whitespace on non-ws spontaneously IN_START --> IN_WHITESPACE --> JSON_SKIP --> IN_START ^ | \__/ on whitespace This accumulates a whitespace token in state IN_WHITESPACE, only to throw it away on the transition via JSON_SKIP to the start state. Wasteful. Go from IN_START to IN_START on whitespace directly, dropping the whitespace character. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180831075841.13363-7-armbru@redhat.com>
-
Markus Armbruster authored
Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180831075841.13363-6-armbru@redhat.com>
-
Markus Armbruster authored
When the lexer chokes on an input character, it consumes the character, emits a JSON error token, and enters its start state. This can lead to suboptimal error recovery. For instance, input 0123 , produces the tokens JSON_ERROR 01 JSON_INTEGER 23 JSON_COMMA , Make the lexer skip characters after a lexical error until a structural character ('[', ']', '{', '}', ':', ','), an ASCII control character, or '\xFE', or '\xFF'. Note that we must not skip ASCII control characters, '\xFE', '\xFF', because those are documented to force the JSON parser into known-good state, by docs/interop/qmp-spec.txt. The lexer now produces JSON_ERROR 01 JSON_COMMA , Update qmp-test for the nicer error recovery: QMP now reports just one error for input %p instead of two. Also drop the newline after %p; it was needed to tease out the second error. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180831075841.13363-5-armbru@redhat.com> [Conflict with commit ebb4d82d resolved]
-
Markus Armbruster authored
The lexer uses macro TERMINAL_NEEDED_LOOKAHEAD() to decide whether a state transition consumes the input character. It returns true when the state transition is defined with the TERMINAL() macro. To detect that, it checks whether input '\0' would have resulted in the same state transition, and the new state is not IN_ERROR. Why does that even work? For all states, the new state on input '\0' is either IN_ERROR or defined with TERMINAL(). If the state transition equals the one we'd get for input '\0', it goes to IN_ERROR or to the argument of TERMINAL(). We never use TERMINAL(IN_ERROR), because it makes no sense. Thus, if it doesn't go to IN_ERROR, it must be defined with TERMINAL(). Since this isn't quite confusing enough, we negate the result to get @char_consumed, and ignore it when @flush is true. Instead of deriving the lookahead bit from the state transition, make it explicit. This is easier to understand, and a bit more flexible, too. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180831075841.13363-4-armbru@redhat.com>
-
Markus Armbruster authored
When the lexer isn't in its start state at the end of input, it's working on a token. To flush it out, it needs to transit to its start state on "end of input" lookahead. There are two ways to the start state, depending on the current state: * If the lexer is in a TERMINAL(JSON_FOO) state, it can emit a JSON_FOO token. * Else, it can go to IN_ERROR state, and emit a JSON_ERROR token. There are complications, however: * The transition to IN_ERROR state consumes the input character and adds it to the JSON_ERROR token. The latter is inappropriate for the "end of input" character, so we suppress that. See also recent commit a2ec6be7 "json: Fix lexer to include the bad character in JSON_ERROR token". * The transition to a TERMINAL(JSON_FOO) state doesn't consume the input character. In that case, the lexer normally loops until it is consumed. We have to suppress that for the "end of input" input character. If we didn't, the lexer would consume it by entering IN_ERROR state, emitting a bogus JSON_ERROR token. We fixed that in commit bd3924a3. However, simply breaking the loop this way assumes that the lexer needs exactly one state transition to reach its start state. That assumption is correct now, but it's unclean, and I'll soon break it. Clean up: instead of breaking the loop after one iteration, break it after it reached the start state. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180831075841.13363-3-armbru@redhat.com>
-
Markus Armbruster authored
The lexer fails to end a valid token when the lookahead character is beyond '\x7F'. For instance, input true\xC2\xA2 produces the tokens JSON_ERROR true\xC2 JSON_ERROR \xA2 This should be JSON_KEYWORD true JSON_ERROR \xC2 JSON_ERROR \xA2 instead. The culprit is #define TERMINAL(state) [0 ... 0x7F] = (state) It leaves [0x80..0xFF] zero, i.e. IN_ERROR. Has always been broken. Fix it to initialize the complete array. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180831075841.13363-2-armbru@redhat.com>
-
- Aug 24, 2018
-
-
Markus Armbruster authored
RFC 8259 (December 2017) obsoletes RFC 7159 (March 2014). Signed-off-by:
Markus Armbruster <armbru@redhat.com> Message-Id: <20180823164025.12553-59-armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com>
-
Markus Armbruster authored
The previous commit makes JSON strings containing '%' awkward to express in templates: you'd have to mask the '%' with an Unicode escape \u0025. No template currently contains such JSON strings. Support the printf conversion specification %% in JSON strings as a convenience anyway, because it's trivially easy to do. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-58-armbru@redhat.com>
-
Markus Armbruster authored
The JSON parser optionally supports interpolation. This is used to build QObjects by parsing string templates. The templates are C literals, so parse errors (such as invalid interpolation specifications) are actually programming errors. Consequently, the functions providing parsing with interpolation (qobject_from_jsonf_nofail(), qobject_from_vjsonf_nofail(), qdict_from_jsonf_nofail(), qdict_from_vjsonf_nofail()) pass &error_abort to the parser. However, there's another, more dangerous kind of programming error: since we use va_arg() to get the value to interpolate, behavior is undefined when the variable argument isn't consistent with the interpolation specification. The same problem exists with printf()-like functions, and the solution is to have the compiler check consistency. This is what GCC_FMT_ATTR() is about. To enable this type checking for interpolation as well, we carefully chose our interpolation specifications to match printf conversion specifications, and decorate functions parsing templates with GCC_FMT_ATTR(). Note that this only protects against undefined behavior due to type errors. It can't protect against use of invalid interpolation specifications that happen to be valid printf conversion specifications. However, there's still a gaping hole in the type checking: GCC recognizes '%' as start of printf conversion specification anywhere in the template, but the parser recognizes it only outside JSON strings. For instance, if someone were to pass a "{ '%s': %d }" template, GCC would require a char * and an int argument, but the parser would va_arg() only an int argument, resulting in undefined behavior. Avoid undefined behavior by catching the programming error at run time: have the parser recognize and reject '%' in JSON strings. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-57-armbru@redhat.com>
-
Markus Armbruster authored
The recursive descent parser passes along a pointer to JSONParserContext. It additionally passes a pointer to interpolation state (a va_alist *) as needed to reach its consumer parse_interpolation(). Stuffing the latter pointer into JSONParserContext saves us the trouble of passing it along, so do that. Signed-off-by:
Markus Armbruster <armbru@redhat.com> Reviewed-by:
Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-56-armbru@redhat.com>
-