diff --git a/READMEs/README.json-lejp.md b/READMEs/README.json-lejp.md index 45a4a1e40..6e0acf2e7 100644 --- a/READMEs/README.json-lejp.md +++ b/READMEs/README.json-lejp.md @@ -37,6 +37,7 @@ newer options |lejp flags|Meaning| |---|---| |LEJP_FLAG_FEAT_OBJECT_INDEXES|Provide indexes for { x, y, x } lists same as for arrays| +|LEJP_FLAG_FEAT_LEADING_WC|Allow path matches involving leading wildcards, like `*[]`| |LEJP_FLAG_LATEST|Alias indicating you want the "best" current options, even if incompatible with old behaviours| ## Type handling @@ -99,8 +100,7 @@ or the match index from your path array starting from 1 for the first entry. |JSON Array|`[]`| |JSON Map|`.`| |JSON Map entry key string|`keystring`| - - +|Wildcard|`*[]`, or `abc.*[]` etc (depends on `ctx.flags` with `LEJP_FLAG_FEAT_LEADING_WC`)| ## Details of object and array indexes diff --git a/include/libwebsockets/lws-lejp.h b/include/libwebsockets/lws-lejp.h index 89d4c4c22..98bce344f 100644 --- a/include/libwebsockets/lws-lejp.h +++ b/include/libwebsockets/lws-lejp.h @@ -246,8 +246,10 @@ struct lejp_ctx { uint16_t uni; #define LEJP_FLAG_FEAT_OBJECT_INDEXES (1 << 0) +#define LEJP_FLAG_FEAT_LEADING_WC (1 << 1) #define LEJP_FLAG_LATEST \ - (LEJP_FLAG_FEAT_OBJECT_INDEXES) + (LEJP_FLAG_FEAT_OBJECT_INDEXES | \ + LEJP_FLAG_FEAT_LEADING_WC) uint16_t flags; /* char */ diff --git a/lib/misc/lejp.c b/lib/misc/lejp.c index a3ba232d2..c1fbde4c9 100644 --- a/lib/misc/lejp.c +++ b/lib/misc/lejp.c @@ -155,7 +155,7 @@ lejp_check_path_match(struct lejp_ctx *ctx) s = ctx->path_stride; /* we only need to check if a match is not active */ - for (n = 0; !ctx->path_match && + for (n = 0; //!ctx->path_match && n < ctx->pst[ctx->pst_sp].count_paths; n++) { ctx->wildcount = 0; p = ctx->path; @@ -180,7 +180,7 @@ lejp_check_path_match(struct lejp_ctx *ctx) * x.* * if both options are possible */ - while (*p && (*p != '.' || !*q)) + while (*p && ((*p != '.' && *p != '[') || !*q)) p++; } if (*p || *q) @@ -275,9 +275,14 @@ lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len) ctx->path[ctx->pst[ctx->pst_sp].ppos++] = '['; ctx->path[ctx->pst[ctx->pst_sp].ppos++] = ']'; ctx->path[ctx->pst[ctx->pst_sp].ppos] = '\0'; + + if (ctx->flags & LEJP_FLAG_FEAT_LEADING_WC) + lejp_check_path_match(ctx); if (ctx->pst[ctx->pst_sp].callback(ctx, LEJPCB_ARRAY_START)) goto reject_callback; ctx->i[ctx->ipos++] = 0; + if (ctx->flags & LEJP_FLAG_FEAT_LEADING_WC) + lejp_check_path_match(ctx); if (ctx->ipos > LWS_ARRAY_SIZE(ctx->i)) { ret = LEJP_REJECT_MP_DELIM_ISTACK; goto reject; @@ -496,8 +501,12 @@ lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len) ctx->path[ctx->pst[ctx->pst_sp].ppos++] = '['; ctx->path[ctx->pst[ctx->pst_sp].ppos++] = ']'; ctx->path[ctx->pst[ctx->pst_sp].ppos] = '\0'; + if (ctx->flags & LEJP_FLAG_FEAT_LEADING_WC) + lejp_check_path_match(ctx); if (ctx->pst[ctx->pst_sp].callback(ctx, LEJPCB_ARRAY_START)) goto reject_callback; + if (ctx->flags & LEJP_FLAG_FEAT_LEADING_WC) + lejp_check_path_match(ctx); ctx->i[ctx->ipos++] = 0; if (ctx->ipos > LWS_ARRAY_SIZE(ctx->i)) { ret = LEJP_REJECT_MP_DELIM_ISTACK; @@ -534,6 +543,8 @@ lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len) ctx->path_match = 0; if (ctx->pst_sp && !ctx->sp) lejp_parser_pop(ctx); + if (ctx->flags & LEJP_FLAG_FEAT_LEADING_WC) + lejp_check_path_match(ctx); if (ctx->outer_array && !ctx->sp) { /* ended on ] */ n = LEJPCB_ARRAY_END; goto completed; @@ -751,7 +762,8 @@ lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len) if (!ctx->sp) { n = LEJPCB_OBJECT_END; completed: - lejp_check_path_match(ctx); + ctx->path_match = 0; + //lejp_check_path_match(ctx); if (ctx->pst[ctx->pst_sp].callback(ctx, (char)n) || ctx->pst[ctx->pst_sp].callback(ctx, LEJPCB_COMPLETE)) diff --git a/minimal-examples-lowlevel/api-tests/api-test-lejp/main.c b/minimal-examples-lowlevel/api-tests/api-test-lejp/main.c index c4eeec1a4..de6963ca6 100644 --- a/minimal-examples-lowlevel/api-tests/api-test-lejp/main.c +++ b/minimal-examples-lowlevel/api-tests/api-test-lejp/main.c @@ -464,8 +464,10 @@ struct lejp_results_pkg { { r8, LWS_ARRAY_SIZE(r8), tok, LWS_ARRAY_SIZE(tok), 0 }, { r9, LWS_ARRAY_SIZE(r9), tok, LWS_ARRAY_SIZE(tok), 0 }, { r10, LWS_ARRAY_SIZE(r10), tok, LWS_ARRAY_SIZE(tok), 0 }, - { r11, LWS_ARRAY_SIZE(r11), tok_test11, LWS_ARRAY_SIZE(tok_test11), 0 }, + { r11, LWS_ARRAY_SIZE(r11), tok_test11, LWS_ARRAY_SIZE(tok_test11), + LEJP_FLAG_FEAT_LEADING_WC}, { r12, LWS_ARRAY_SIZE(r12), tok_test11, LWS_ARRAY_SIZE(tok_test11), + LEJP_FLAG_FEAT_LEADING_WC | LEJP_FLAG_FEAT_OBJECT_INDEXES }, };