snac2

Fork of https://codeberg.org/grunfink/snac2
git clone https://git.inz.fi/snac2
Log | Files | Refs | README | LICENSE

commit af8a95bbf0b3709d605175da92b93ad1d0aa0bd3
parent 09803021648ea958a889cc2aa743d5f8c65ecbae
Author: Santtu Lakkala <inz@inz.fi>
Date:   Thu, 13 Feb 2025 08:36:34 +0100

Limit JSON depth

Diffstat:
Msnac.h | 4++++
Mxs_json.h | 36+++++++++++++++++++-----------------
2 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/snac.h b/snac.h @@ -16,6 +16,10 @@ #define MAX_THREADS 256 #endif +#ifndef MAX_JSON_DEPTH +#define MAX_JSON_DEPTH 8 +#endif + #ifndef MAX_CONVERSATION_LEVELS #define MAX_CONVERSATION_LEVELS 48 #endif diff --git a/xs_json.h b/xs_json.h @@ -7,14 +7,16 @@ int xs_json_dump(const xs_val *data, int indent, FILE *f); xs_str *xs_json_dumps(const xs_val *data, int indent); -xs_val *xs_json_load(FILE *f); -xs_val *xs_json_loads(const xs_str *json); +xs_val *xs_json_load_full(FILE *f, int maxdepth); +xs_val *xs_json_loads_full(const xs_str *json, int maxdepth); +#define xs_json_load(f) xs_json_load_full(f, MAX_JSON_DEPTH) +#define xs_json_loads(s) xs_json_loads_full(s, MAX_JSON_DEPTH) xstype xs_json_load_type(FILE *f); int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c); int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, int *c); -xs_list *xs_json_load_array(FILE *f); -xs_dict *xs_json_load_object(FILE *f); +xs_list *xs_json_load_array(FILE *f, int maxdepth); +xs_dict *xs_json_load_object(FILE *f, int maxdepth); #ifdef XS_IMPLEMENTATION @@ -371,7 +373,7 @@ int xs_json_load_array_iter(FILE *f, xs_val **value, xstype *pt, int *c) } -xs_list *xs_json_load_array(FILE *f) +xs_list *xs_json_load_array(FILE *f, int maxdepth) /* loads a full JSON array (after the initial OBRACK) */ { xstype t; @@ -387,12 +389,12 @@ xs_list *xs_json_load_array(FILE *f) if (r == 1) { /* partial load? */ - if (v == NULL) { + if (v == NULL && maxdepth != 0) { if (t == XSTYPE_LIST) - v = xs_json_load_array(f); + v = xs_json_load_array(f, maxdepth - 1); else if (t == XSTYPE_DICT) - v = xs_json_load_object(f); + v = xs_json_load_object(f, maxdepth - 1); } /* still null? fail */ @@ -459,7 +461,7 @@ int xs_json_load_object_iter(FILE *f, xs_str **key, xs_val **value, xstype *pt, } -xs_dict *xs_json_load_object(FILE *f) +xs_dict *xs_json_load_object(FILE *f, int maxdepth) /* loads a full JSON object (after the initial OCURLY) */ { xstype t; @@ -476,12 +478,12 @@ xs_dict *xs_json_load_object(FILE *f) if (r == 1) { /* partial load? */ - if (v == NULL) { + if (v == NULL && maxdepth != 0) { if (t == XSTYPE_LIST) - v = xs_json_load_array(f); + v = xs_json_load_array(f, maxdepth - 1); else if (t == XSTYPE_DICT) - v = xs_json_load_object(f); + v = xs_json_load_object(f, maxdepth - 1); } /* still null? fail */ @@ -500,14 +502,14 @@ xs_dict *xs_json_load_object(FILE *f) } -xs_val *xs_json_loads(const xs_str *json) +xs_val *xs_json_loads_full(const xs_str *json, int maxdepth) /* loads a string in JSON format and converts to a multiple data */ { FILE *f; xs_val *v = NULL; if ((f = fmemopen((char *)json, strlen(json), "r")) != NULL) { - v = xs_json_load(f); + v = xs_json_load_full(f, maxdepth); fclose(f); } @@ -533,17 +535,17 @@ xstype xs_json_load_type(FILE *f) } -xs_val *xs_json_load(FILE *f) +xs_val *xs_json_load_full(FILE *f, int maxdepth) /* loads a JSON file */ { xs_val *v = NULL; xstype t = xs_json_load_type(f); if (t == XSTYPE_LIST) - v = xs_json_load_array(f); + v = xs_json_load_array(f, maxdepth); else if (t == XSTYPE_DICT) - v = xs_json_load_object(f); + v = xs_json_load_object(f, maxdepth); return v; }