@@ -61,9 +61,6 @@ enum json_lexer_state {
IN_ESCAPE,
IN_ESCAPE_L,
IN_ESCAPE_LL,
- IN_ESCAPE_I,
- IN_ESCAPE_I6,
- IN_ESCAPE_I64,
IN_WHITESPACE,
IN_START,
};
@@ -230,22 +227,9 @@ static const uint8_t json_lexer[][256] = {
},
[IN_ESCAPE_L] = {
- ['d'] = JSON_ESCAPE,
['l'] = IN_ESCAPE_LL,
},
- [IN_ESCAPE_I64] = {
- ['d'] = JSON_ESCAPE,
- },
-
- [IN_ESCAPE_I6] = {
- ['4'] = IN_ESCAPE_I64,
- },
-
- [IN_ESCAPE_I] = {
- ['6'] = IN_ESCAPE_I6,
- },
-
[IN_ESCAPE] = {
['d'] = JSON_ESCAPE,
['i'] = JSON_ESCAPE,
@@ -253,7 +237,6 @@ static const uint8_t json_lexer[][256] = {
['s'] = JSON_ESCAPE,
['f'] = JSON_ESCAPE,
['l'] = IN_ESCAPE_L,
- ['I'] = IN_ESCAPE_I,
},
/* top level rule */
@@ -461,23 +461,22 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap)
token = parser_context_pop_token(ctxt);
assert(token && token->type == JSON_ESCAPE);
+ /* We only accept a fixed subset of printf. In particular, PRId64
+ * is not guaranteed to work; use long long instead of int64_t. */
if (!strcmp(token->str, "%p")) {
return va_arg(*ap, QObject *);
} else if (!strcmp(token->str, "%i")) {
return QOBJECT(qbool_from_bool(va_arg(*ap, int)));
} else if (!strcmp(token->str, "%d")) {
return QOBJECT(qint_from_int(va_arg(*ap, int)));
- } else if (!strcmp(token->str, "%ld")) {
- return QOBJECT(qint_from_int(va_arg(*ap, long)));
- } else if (!strcmp(token->str, "%lld") ||
- !strcmp(token->str, "%I64d")) {
+ } else if (!strcmp(token->str, "%lld")) {
return QOBJECT(qint_from_int(va_arg(*ap, long long)));
} else if (!strcmp(token->str, "%s")) {
return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
} else if (!strcmp(token->str, "%f")) {
return QOBJECT(qfloat_from_double(va_arg(*ap, double)));
}
- return NULL;
+ assert(false);
}
static QObject *parse_literal(JSONParserContext *ctxt)
The qobject_from_jsonf() function implements a pseudo-printf language for creating a QObject; however, it is hard-coded to only parse a subset of formats understood by printf(). In particular, any use of an int64_t integer works only if the system's definition of PRId64 matches what the parser expects; which works on glibc (%lld or %ld depending on 32- vs. 64-bit) and mingw (%I64d), but not on Mac OS (%qd). Rather than enhance the parser, we have already eliminated all clients that were using int64_t, and therefore all uses of %I64d. No one should be using long (%ld), since the size of that type differs between 32- and 64-bit. Therefore, reducing the parser to accept ONLY %lld allows us to still accept 64-bit integers (passed in as long long, not int64_t), while removing %ld and %I64d support gives us a few more platforms (more than just the infrequent Mac OS' %qd) that will fail if a later use picks an unrecognized format string. There are few enough uses of qobject_from_json[fv]() that it is easy to audit that all callers in the main code body are correct, and all remaining callers in the testsuite are covered by a successful 'make check'. This patch gives confidence that the earlier patches are appropriate for 2.8 on Mac OS, but this particular patch is not hard freeze material, and should be deferred to 2.9 (or else dynamic JSON pseudo-printf ripped out in its entirety, rather than just unused formats). Reported by: G 3 <programmingkidx@gmail.com> Signed-off-by: Eric Blake <eblake@redhat.com> --- qobject/json-lexer.c | 17 ----------------- qobject/json-parser.c | 9 ++++----- 2 files changed, 4 insertions(+), 22 deletions(-)