Re: [PATCH 2/3] perf tools: Make the JSON parser more conformant when in strict mode
From: Arnaldo Carvalho de Melo <acme@kernel.org>
Date: 2021-10-08 18:56:35
Also in:
linux-perf-users, lkml
Em Fri, Oct 08, 2021 at 03:12:03PM +0200, Jiri Olsa escreveu:
On Fri, Oct 08, 2021 at 11:08:25AM +0100, James Clark wrote:quoted
On 07/10/2021 18:52, Jiri Olsa wrote:quoted
On Thu, Oct 07, 2021 at 12:05:41PM +0100, James Clark wrote:quoted
Return an error when a trailing comma is found or a new item is encountered before a comma or an opening brace. This ensures that the perf json files conform more closely to the spec at https://www.json.org Signed-off-by: James Clark <redacted> --- tools/perf/pmu-events/jsmn.c | 42 ++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-)diff --git a/tools/perf/pmu-events/jsmn.c b/tools/perf/pmu-events/jsmn.c index 11d1fa18bfa5..8124d2d3ff0c 100644 --- a/tools/perf/pmu-events/jsmn.c +++ b/tools/perf/pmu-events/jsmn.c@@ -176,6 +176,14 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, jsmnerr_t r; int i; jsmntok_t *token; +#ifdef JSMN_STRICTI might have missed some discussion on this, but do we need the JSMN_STRICT define, if you enable it in the next patch? why can't we be more strict by default.. do you plan to disable it in future?I didn't plan on disabling it, I was just trying to keep to the existing style of the jsmn project. I could have added the trailing comma detection by default and not inside any #ifdef JSMN_STRICT blocks, but I would like to enable JSMN_STRICT anyway, because it enables some additional built in checking that was already there. So I thought it made sense to put my new strict stuff inside the existing strict option. One option would be to remove all (including the existing) #ifdef JSMN_STRICT blocks and have everything strict by default. But it would be a further deviation from jsmn.ok, I think it makes sense to have JSMN_STRICT then.. thanks for explanation Acked-by: Jiri Olsa <redacted>
So, is this for the whole patchset? b4 picked it just for this message. - Arnaldo
jirkaquoted
Thanks Jamesquoted
thanks, jirkaquoted
+ /* + * Keeps track of whether a new object/list/primitive is expected. New items are only + * allowed after an opening brace, comma or colon. A closing brace after a comma is not + * valid JSON. + */ + int expecting_item = 1; +#endif for (; parser->pos < len; parser->pos++) { char c;@@ -185,6 +193,10 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, switch (c) { case '{': case '[': +#ifdef JSMN_STRICT + if (!expecting_item) + return JSMN_ERROR_INVAL; +#endif token = jsmn_alloc_token(parser, tokens, num_tokens); if (token == NULL) return JSMN_ERROR_NOMEM;@@ -196,6 +208,10 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, break; case '}': case ']': +#ifdef JSMN_STRICT + if (expecting_item) + return JSMN_ERROR_INVAL; +#endif type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); for (i = parser->toknext - 1; i >= 0; i--) { token = &tokens[i];@@ -219,6 +235,11 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, } break; case '\"': +#ifdef JSMN_STRICT + if (!expecting_item) + return JSMN_ERROR_INVAL; + expecting_item = 0; +#endif r = jsmn_parse_string(parser, js, len, tokens, num_tokens); if (r < 0)@@ -229,11 +250,15 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, case '\t': case '\r': case '\n': - case ':': - case ',': case ' ': break; #ifdef JSMN_STRICT + case ':': + case ',': + if (expecting_item) + return JSMN_ERROR_INVAL; + expecting_item = 1; + break; /* * In strict mode primitives are: * numbers and booleans.@@ -253,6 +278,9 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, case 'f': case 'n': #else + case ':': + case ',': + break; /* * In non-strict mode every unquoted value * is a primitive.@@ -260,6 +288,12 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, /*FALL THROUGH */ default: #endif + +#ifdef JSMN_STRICT + if (!expecting_item) + return JSMN_ERROR_INVAL; + expecting_item = 0; +#endif r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); if (r < 0)@@ -282,7 +316,11 @@ jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, size_t len, return JSMN_ERROR_PART; } +#ifdef JSMN_STRICT + return expecting_item ? JSMN_ERROR_INVAL : JSMN_SUCCESS; +#else return JSMN_SUCCESS; +#endif } /*-- 2.28.0
-- - Arnaldo _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel