aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanttu Lakkala <inz@inz.fi>2025-02-13 08:36:34 +0100
committerdefault <nobody@localhost>2025-02-13 08:36:34 +0100
commitaf8a95bbf0b3709d605175da92b93ad1d0aa0bd3 (patch)
treee42906a03f0d8cd45cad46803512b50bafc4956a
parent09803021648ea958a889cc2aa743d5f8c65ecbae (diff)
Limit JSON depth
-rw-r--r--snac.h4
-rw-r--r--xs_json.h36
2 files changed, 23 insertions, 17 deletions
diff --git a/snac.h b/snac.h
index 9d349fd..d2d73af 100644
--- 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
index d1b18e4..b9421e4 100644
--- 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;
}