Now that there are no callers of dynamic JSON parsing, the lexer does not need to special-case escape sequences.
Since the lexer is directly invoked on user-provided input, this changes behavior when a QMP client passes (bad) JSON, from: {'execute':'qmp_capabilities','id':%s} {"error": {"class": "GenericError", "desc": "Invalid JSON syntax"}} to the noisier: {'execute':'qmp_capabilities','id':%s} {"error": {"class": "GenericError", "desc": "Invalid JSON syntax"}} {"error": {"class": "GenericError", "desc": "JSON parse error, invalid keyword 's'"}} {"error": {"class": "GenericError", "desc": "JSON parse error, expecting value"}} But we've always known our parser is rather noisy when it comes to dealing with invalid JSON, and valid clients won't see the difference. Signed-off-by: Eric Blake <ebl...@redhat.com> --- include/qapi/qmp/json-lexer.h | 1 - qobject/json-lexer.c | 40 ---------------------------------------- qobject/json-parser.c | 32 -------------------------------- 3 files changed, 73 deletions(-) diff --git a/include/qapi/qmp/json-lexer.h b/include/qapi/qmp/json-lexer.h index afee782..a872f57 100644 --- a/include/qapi/qmp/json-lexer.h +++ b/include/qapi/qmp/json-lexer.h @@ -27,7 +27,6 @@ typedef enum json_token_type { JSON_FLOAT, JSON_KEYWORD, JSON_STRING, - JSON_ESCAPE, JSON_SKIP, JSON_ERROR, } JSONTokenType; diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c index af4a75e..3207306 100644 --- a/qobject/json-lexer.c +++ b/qobject/json-lexer.c @@ -58,12 +58,6 @@ enum json_lexer_state { IN_NONZERO_NUMBER, IN_NEG_NONZERO_NUMBER, IN_KEYWORD, - IN_ESCAPE, - IN_ESCAPE_L, - IN_ESCAPE_LL, - IN_ESCAPE_I, - IN_ESCAPE_I6, - IN_ESCAPE_I64, IN_WHITESPACE, IN_START, }; @@ -224,38 +218,6 @@ static const uint8_t json_lexer[][256] = { ['\n'] = IN_WHITESPACE, }, - /* escape */ - [IN_ESCAPE_LL] = { - ['d'] = JSON_ESCAPE, - }, - - [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, - ['p'] = JSON_ESCAPE, - ['s'] = JSON_ESCAPE, - ['f'] = JSON_ESCAPE, - ['l'] = IN_ESCAPE_L, - ['I'] = IN_ESCAPE_I, - }, - /* top level rule */ [IN_START] = { ['"'] = IN_DQ_STRING, @@ -270,7 +232,6 @@ static const uint8_t json_lexer[][256] = { [','] = JSON_COMMA, [':'] = JSON_COLON, ['a' ... 'z'] = IN_KEYWORD, - ['%'] = IN_ESCAPE, [' '] = IN_WHITESPACE, ['\t'] = IN_WHITESPACE, ['\r'] = IN_WHITESPACE, @@ -311,7 +272,6 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush) case JSON_RSQUARE: case JSON_COLON: case JSON_COMMA: - case JSON_ESCAPE: case JSON_INTEGER: case JSON_FLOAT: case JSON_KEYWORD: diff --git a/qobject/json-parser.c b/qobject/json-parser.c index c18e48a..fec1dae 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -450,36 +450,6 @@ static QObject *parse_keyword(JSONParserContext *ctxt) return NULL; } -static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap) -{ - JSONToken *token; - - if (ap == NULL) { - return NULL; - } - - token = parser_context_pop_token(ctxt); - assert(token && token->type == JSON_ESCAPE); - - 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")) { - 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; -} - static QObject *parse_literal(JSONParserContext *ctxt) { JSONToken *token; @@ -537,8 +507,6 @@ static QObject *parse_value(JSONParserContext *ctxt, va_list *ap) return parse_object(ctxt, ap); case JSON_LSQUARE: return parse_array(ctxt, ap); - case JSON_ESCAPE: - return parse_escape(ctxt, ap); case JSON_INTEGER: case JSON_FLOAT: case JSON_STRING: -- 2.7.4