libwebsockets
Lightweight C library for HTML5 websockets
Loading...
Searching...
No Matches
lws-lejp.h
Go to the documentation of this file.
1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
32struct lejp_ctx;
33struct lwsac;
34
35#if !defined(LWS_ARRAY_SIZE)
36#define LWS_ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0]))
37#endif
38#define LEJP_FLAG_WS_KEEP 64
39#define LEJP_FLAG_WS_COMMENTLINE 32
40
59
87
88#define LEJP_FLAG_CB_IS_VALUE 64
89
118
189LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason);
190
191typedef signed char (*lejp_callback)(struct lejp_ctx *ctx, char reason);
192
193#ifndef LEJP_MAX_PARSING_STACK_DEPTH
194#define LEJP_MAX_PARSING_STACK_DEPTH 10
195#endif
196#ifndef LEJP_MAX_DEPTH
197#if defined(LWS_ESP_PLATFORM)
198#define LEJP_MAX_DEPTH 16
199#else
200#define LEJP_MAX_DEPTH 64
201#endif
202#endif
203#ifndef LEJP_MAX_INDEX_DEPTH
204#if defined(LWS_ESP_PLATFORM)
205#define LEJP_MAX_INDEX_DEPTH 12
206#else
207#define LEJP_MAX_INDEX_DEPTH 64
208#endif
209#endif
210#ifndef LEJP_MAX_PATH
211#define LEJP_MAX_PATH 192
212#endif
213#ifndef LEJP_STRING_CHUNK
214/* must be >= 30 to assemble floats */
215#define LEJP_STRING_CHUNK 254
216#endif
217
218/*
219 * These are tunable, but every index into the arrays they size is a uint8_t
220 * in struct lejp_ctx, so they are hard-capped: LEJP_MAX_PATH, LEJP_MAX_DEPTH,
221 * LEJP_MAX_INDEX_DEPTH and LEJP_MAX_PARSING_STACK_DEPTH must each be <= 255,
222 * and LEJP_STRING_CHUNK <= 254. Raising one past its cap does not overflow
223 * the array, but the bounds checks stop firing and the parser silently
224 * corrupts what it collected.
225 */
226
227#if LEJP_MAX_PATH > 255 || LEJP_MAX_DEPTH > 255 || \
228 LEJP_MAX_INDEX_DEPTH > 255 || LEJP_MAX_PARSING_STACK_DEPTH > 255 || \
229 LEJP_STRING_CHUNK > 254
230#error "LEJP_ size knob is larger than its uint8_t index can represent"
231#endif
232
234 LEJP_SEEN_MINUS = (1 << 0),
235 LEJP_SEEN_POINT = (1 << 1),
237 LEJP_SEEN_EXP = (1 << 3)
238};
239
241 char s; /* lejp_state stack*/
242 uint8_t p; /* path length, 0 .. LEJP_MAX_PATH - 1 */
243 char i; /* index array length */
244 char b; /* user bitfield */
245};
246
248 void *user; /* private to the stack level */
249 signed char (*callback)(struct lejp_ctx *ctx, char reason);
250 const char * const *paths;
254 /*
255 * ctx->sp when this level was pushed, and if it was pushed by the
256 * ARRAY_START callback, in which case the ']' closing that array pops
257 * it (these fit in what was padding before)
258 */
261 /*
262 * Where in ctx->path_save the path of the level below this one was
263 * kept when this level was pushed, and its length, so it can be put
264 * back in ctx->path when this level is popped (also in what was
265 * padding before)
266 */
269};
270
276
284
285struct lejp_ctx {
286
287 /* sorted by type for most compact alignment
288 *
289 * pointers
290 */
291 void *user;
292
293 /* arrays */
294
297 uint16_t i[LEJP_MAX_INDEX_DEPTH]; /* index array */
300 /*
301 * A pushed parser writes its paths from path[0], over the top of the
302 * paths of the levels below it: their paths as they were at each push
303 * are kept here, one after the other, and put back at each pop
304 */
307
309
310 /* size_t */
311
312 size_t path_stride; /* 0 means default ptr size, else stride */
313
314 /* int */
315
317
318 /* short */
319
321 uint16_t uni_hi; /* pending \uD800-\uDBFF surrogate half, or 0 */
322#define LEJP_FLAG_FEAT_OBJECT_INDEXES (1 << 0)
323#define LEJP_FLAG_FEAT_LEADING_WC (1 << 1)
324/*
325 * Reject object key names containing the characters lejp uses to represent
326 * the document structure in ctx->path, ie, '.', '[' and ']'. Without this,
327 * a peer can choose a key name that synthesizes the same path as a completely
328 * different document shape, eg, {"s[].foo":1} produces the same path as
329 * {"s":[{"foo":1}]}. It's optional since a key legitimately containing '.'
330 * (eg, a hostname) is not that unusual; set it if your paths care.
331 */
332#define LEJP_FLAG_FEAT_STRICT_KEY_CHARS (1 << 2)
333/*
334 * Accept lejp's nonstandard '#' to-end-of-line comment extension, outside of
335 * strings, at any depth. RFC 8259 has no comments, so with this set lejp
336 * assigns a meaning to documents every conformant JSON parser rejects, eg,
337 * {"a":1#,"b":2 LF } is {"a":1} to lejp and a syntax error to everybody else.
338 * Wherever the same bytes are also seen by another parser - a JOSE header the
339 * relying party also reads, a policy a management tool also reads - the two
340 * disagree about what the document says, and lejp's view is the one the
341 * security decision is made on. So it's off by default and network-facing
342 * parses must leave it off; it exists for hand-written, locally-owned config
343 * files. In-tree, lejp-conf.c (the lwsws config parser) sets it, and so does
344 * the Secure Streams policy parser in policy-json.c: policies are
345 * operator-authored, even when fetched from the operator's own server, and
346 * their format has always allowed comments.
347 *
348 * Deliberately not part of LEJP_FLAG_LATEST, which means "the best current
349 * behaviours", ie, the strictest.
350 */
351#define LEJP_FLAG_FEAT_COMMENTS (1 << 3)
352#define LEJP_FLAG_LATEST \
353 (LEJP_FLAG_FEAT_OBJECT_INDEXES | \
354 LEJP_FLAG_FEAT_LEADING_WC | \
355 LEJP_FLAG_FEAT_STRICT_KEY_CHARS)
357
358 /* char */
359
363 uint8_t sp; /* stack head */
364 uint8_t ipos; /* index stack depth */
369 uint8_t pst_sp; /* parsing stack head */
371 int8_t failed; /* 0, or the LEJP_REJECT_... this ctx failed with */
372};
373
376 signed char (*callback)(struct lejp_ctx *ctx, char reason),
377 void *user, const char * const *paths, unsigned char paths_count);
378
381
383lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len);
384
387 signed char (*callback)(struct lejp_ctx *ctx, char reason));
388
389/*
390 * push the current paths / paths_count and lejp_cb to a stack in the ctx, and
391 * start using the new ones
392 *
393 * The new parser sees paths relative to where it was pushed, starting from
394 * ctx->path[0]; the path the current parser had reached is kept and restored
395 * for it when the new one is popped. Returns -1 without changing anything if
396 * the parsing stack is full, or if the paths kept for all the pushed levels
397 * would add up to more than LEJP_MAX_PATH.
398 */
400lejp_parser_push(struct lejp_ctx *ctx, void *user, const char * const *paths,
401 unsigned char paths_count, lejp_callback lejp_cb);
402
403/*
404 * pop the previously used paths / paths_count and lejp_cb, and continue
405 * parsing using those as before, with ctx->path back to what they had reached
406 * when the popped parser was pushed
407 */
410
411/* exported for use when reevaluating a path for use with a subcontext */
414
416lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);
417
418LWS_VISIBLE LWS_EXTERN const char *
420
422lejp_string_unify(struct lejp_ctx *ctx, struct lwsac **ac);
423
425lejp_string_unify_part(struct lejp_ctx *ctx, struct lwsac **ac, char reason);
unsigned short uint16_t
unsigned int uint32_t
#define LWS_EXTERN
unsigned char uint8_t
#define LWS_VISIBLE
lejp_states
Definition lws-lejp.h:41
@ LEJP_MP_VALUE_TOK
Definition lws-lejp.h:55
@ LEJP_MP_STRING
Definition lws-lejp.h:45
@ LEJP_M_P
Definition lws-lejp.h:44
@ LEJP_MP_STRING_ESC_U4
Definition lws-lejp.h:50
@ LEJP_MP_VALUE_NUM_EXP
Definition lws-lejp.h:54
@ LEJP_MEMBERS
Definition lws-lejp.h:43
@ LEJP_MP_STRING_ESC_U1
Definition lws-lejp.h:47
@ LEJP_MP_DELIM
Definition lws-lejp.h:51
@ LEJP_IDLE
Definition lws-lejp.h:42
@ LEJP_MP_VALUE_NUM_INT
Definition lws-lejp.h:53
@ LEJP_MP_STRING_ESC_U3
Definition lws-lejp.h:49
@ LEJP_MP_ARRAY_END
Definition lws-lejp.h:57
@ LEJP_MP_COMMA_OR_END
Definition lws-lejp.h:56
@ LEJP_MP_STRING_ESC
Definition lws-lejp.h:46
@ LEJP_MP_VALUE
Definition lws-lejp.h:52
@ LEJP_MP_STRING_ESC_U2
Definition lws-lejp.h:48
size_t path_stride
Definition lws-lejp.h:312
int8_t failed
Definition lws-lejp.h:371
LWS_VISIBLE LWS_EXTERN void lejp_construct(struct lejp_ctx *ctx, signed char(*callback)(struct lejp_ctx *ctx, char reason), void *user, const char *const *paths, unsigned char paths_count)
uint16_t uni_hi
Definition lws-lejp.h:321
struct _lejp_stack st[LEJP_MAX_DEPTH]
Definition lws-lejp.h:296
signed char(* callback)(struct lejp_ctx *ctx, char reason)
Definition lws-lejp.h:249
uint8_t path_save_len
Definition lws-lejp.h:268
char path_save[LEJP_MAX_PATH]
Definition lws-lejp.h:305
uint8_t outer_array
Definition lws-lejp.h:370
uint8_t f
Definition lws-lejp.h:362
LWS_VISIBLE LWS_EXTERN int lejp_string_unify_part(struct lejp_ctx *ctx, struct lwsac **ac, char reason)
uint8_t path_match
Definition lws-lejp.h:366
uint16_t uni
Definition lws-lejp.h:320
#define LEJP_MAX_PATH
Definition lws-lejp.h:211
#define LEJP_MAX_PARSING_STACK_DEPTH
Definition lws-lejp.h:194
uint8_t sp
Definition lws-lejp.h:363
uint8_t pst_sp
Definition lws-lejp.h:369
uint8_t ipos
Definition lws-lejp.h:364
LWS_VISIBLE LWS_EXTERN int lejp_parser_pop(struct lejp_ctx *ctx)
lejp_reasons
Definition lws-lejp.h:60
@ LEJP_REJECT_ILLEGAL_HEX
Definition lws-lejp.h:68
@ LEJP_REJECT_MP_C_OR_E_NEITHER
Definition lws-lejp.h:81
@ LEJP_REJECT_MP_VAL_NUM_FORMAT
Definition lws-lejp.h:72
@ LEJP_REJECT_MP_ARRAY_END_MISSING
Definition lws-lejp.h:77
@ LEJP_REJECT_UNKNOWN
Definition lws-lejp.h:82
@ LEJP_REJECT_MP_KEY_ILLEGAL_CHAR
Definition lws-lejp.h:84
@ LEJP_CONTINUE
Definition lws-lejp.h:61
@ LEJP_REJECT_MP_DELIM_MISSING_COLON
Definition lws-lejp.h:69
@ LEJP_REJECT_MP_C_OR_E_UNDERF
Definition lws-lejp.h:75
@ LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC
Definition lws-lejp.h:67
@ LEJP_REJECT_MP_VAL_TOK_UNKNOWN
Definition lws-lejp.h:74
@ LEJP_REJECT_MP_C_OR_E_NOTARRAY
Definition lws-lejp.h:76
@ LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC
Definition lws-lejp.h:71
@ LEJP_REJECT_MEMBERS_NO_CLOSE
Definition lws-lejp.h:63
@ LEJP_REJECT_MP_DELIM_ISTACK
Definition lws-lejp.h:79
@ LEJP_REJECT_IDLE_NO_BRACE
Definition lws-lejp.h:62
@ LEJP_REJECT_CALLBACK
Definition lws-lejp.h:83
@ LEJP_REJECT_NUM_TOO_LONG
Definition lws-lejp.h:80
@ LEJP_REJECT_MP_STRING_UNDERRUN
Definition lws-lejp.h:65
@ LEJP_REJECT_MP_NO_OPEN_QUOTE
Definition lws-lejp.h:64
@ LEJP_REJECT_MP_ILLEGAL_CTRL
Definition lws-lejp.h:66
@ LEJP_REJECT_STACK_OVERFLOW
Definition lws-lejp.h:78
@ LEJP_REJECT_MP_DELIM_BAD_VALUE_START
Definition lws-lejp.h:70
@ LEJP_REJECT_PATH_TOO_LONG
Definition lws-lejp.h:85
@ LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP
Definition lws-lejp.h:73
uint8_t count_paths
Definition lws-lejp.h:365
lejp_callbacks
Definition lws-lejp.h:90
@ LEJPCB_VAL_FALSE
Definition lws-lejp.h:101
@ LEJPCB_USER_DESTROYING
Definition lws-lejp.h:116
@ LEJPCB_OBJECT_END
Definition lws-lejp.h:113
@ LEJPCB_USER_START
Definition lws-lejp.h:115
@ LEJPCB_START
Definition lws-lejp.h:94
@ LEJPCB_VAL_NUM_FLOAT
Definition lws-lejp.h:104
@ LEJPCB_ARRAY_END
Definition lws-lejp.h:110
@ LEJPCB_OBJECT_START
Definition lws-lejp.h:112
@ LEJPCB_VAL_TRUE
Definition lws-lejp.h:100
@ LEJPCB_VAL_NUM_INT
Definition lws-lejp.h:103
@ LEJPCB_CONSTRUCTED
Definition lws-lejp.h:91
@ LEJPCB_FAILED
Definition lws-lejp.h:96
@ LEJPCB_COMPLETE
Definition lws-lejp.h:95
@ LEJPCB_ARRAY_START
Definition lws-lejp.h:109
@ LEJPCB_VAL_STR_END
Definition lws-lejp.h:107
@ LEJPCB_VAL_NULL
Definition lws-lejp.h:102
@ LEJPCB_VAL_STR_CHUNK
Definition lws-lejp.h:106
@ LEJPCB_VAL_STR_START
Definition lws-lejp.h:105
@ LEJPCB_DESTRUCTED
Definition lws-lejp.h:92
@ LEJPCB_PAIR_NAME
Definition lws-lejp.h:98
lejp_string_piece_t * sph
Definition lws-lejp.h:278
LWS_VISIBLE LWS_EXTERN int lejp_string_unify(struct lejp_ctx *ctx, struct lwsac **ac)
LWS_VISIBLE LWS_EXTERN void lejp_check_path_match(struct lejp_ctx *ctx)
num_flags
Definition lws-lejp.h:233
@ LEJP_SEEN_EXP
Definition lws-lejp.h:237
@ LEJP_SEEN_POINT
Definition lws-lejp.h:235
@ LEJP_SEEN_MINUS
Definition lws-lejp.h:234
@ LEJP_SEEN_POST_POINT
Definition lws-lejp.h:236
LWS_VISIBLE LWS_EXTERN int lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len)
uint16_t wild[LEJP_MAX_INDEX_DEPTH]
Definition lws-lejp.h:298
const char * piece
Definition lws-lejp.h:273
void * user
Definition lws-lejp.h:291
const char *const * paths
Definition lws-lejp.h:250
LWS_VISIBLE LWS_EXTERN void lejp_change_callback(struct lejp_ctx *ctx, signed char(*callback)(struct lejp_ctx *ctx, char reason))
uint8_t pushed_at_array
Definition lws-lejp.h:260
struct lejp_string_piece lejp_string_piece_t
lejp_string_unifier_t su
Definition lws-lejp.h:308
LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason)
#define LEJP_STRING_CHUNK
Definition lws-lejp.h:215
uint8_t path_match_len
Definition lws-lejp.h:367
LWS_VISIBLE LWS_EXTERN const char * lejp_error_to_string(int e)
uint8_t path_save_ofs
Definition lws-lejp.h:267
lejp_string_piece_t ** sp_next
Definition lws-lejp.h:279
uint8_t npos
Definition lws-lejp.h:360
uint8_t wildcount
Definition lws-lejp.h:368
LWS_VISIBLE LWS_EXTERN int lejp_parser_push(struct lejp_ctx *ctx, void *user, const char *const *paths, unsigned char paths_count, lejp_callback lejp_cb)
struct lejp_string_piece * next
Definition lws-lejp.h:272
#define LEJP_FLAG_CB_IS_VALUE
Definition lws-lejp.h:88
uint8_t p
Definition lws-lejp.h:242
#define LEJP_MAX_DEPTH
Definition lws-lejp.h:200
LWS_VISIBLE LWS_EXTERN void lejp_destruct(struct lejp_ctx *ctx)
signed char(* lejp_callback)(struct lejp_ctx *ctx, char reason)
Definition lws-lejp.h:191
uint16_t i[LEJP_MAX_INDEX_DEPTH]
Definition lws-lejp.h:297
uint16_t flags
Definition lws-lejp.h:356
uint8_t dcount
Definition lws-lejp.h:361
#define LEJP_MAX_INDEX_DEPTH
Definition lws-lejp.h:207
#define LEJP_FLAG_WS_KEEP
Definition lws-lejp.h:38
char buf[LEJP_STRING_CHUNK+1]
Definition lws-lejp.h:306
char path[LEJP_MAX_PATH]
Definition lws-lejp.h:299
uint32_t line
Definition lws-lejp.h:316
struct _lejp_parsing_stack pst[LEJP_MAX_PARSING_STACK_DEPTH]
Definition lws-lejp.h:295
LWS_VISIBLE LWS_EXTERN int lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len)