From 2f4e7a21dc7fc2096b37179a677c1a765409cb51 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 11 Feb 2025 18:53:36 +0100 Subject: Bumped version. --- snac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'snac.h') diff --git a/snac.h b/snac.h index 2ff3235..9d349fd 100644 --- a/snac.h +++ b/snac.h @@ -1,7 +1,7 @@ /* snac - A simple, minimalistic ActivityPub instance */ /* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ -#define VERSION "2.72" +#define VERSION "2.73-dev" #define USER_AGENT "snac/" VERSION -- cgit From af8a95bbf0b3709d605175da92b93ad1d0aa0bd3 Mon Sep 17 00:00:00 2001 From: Santtu Lakkala Date: Thu, 13 Feb 2025 08:36:34 +0100 Subject: Limit JSON depth --- snac.h | 4 ++++ xs_json.h | 36 +++++++++++++++++++----------------- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'snac.h') 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; } -- cgit From 9a56475f4c1566925536bdf8bbd7a36c1d0c39f8 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 09:54:58 +0100 Subject: New function lang_str(). --- data.c | 25 +++++++++++++++++++++++++ snac.c | 1 + snac.h | 3 +++ 3 files changed, 29 insertions(+) (limited to 'snac.h') diff --git a/data.c b/data.c index 9fc54a0..3aba471 100644 --- a/data.c +++ b/data.c @@ -4064,3 +4064,28 @@ void badlogin_inc(const char *user, const char *addr) pthread_mutex_unlock(&data_mutex); } } + + +/** language strings **/ + +const char *lang_str(const char *str, const snac *user) +/* returns a translated string */ +{ + if (user && xs_is_string(str) && xs_is_dict(srv_langs)) { + /* get user preference */ + const char *lang = xs_dict_get(user->config, "lang"); + + if (xs_is_string(lang)) { + const xs_dict *strs = xs_dict_get(srv_langs, lang); + + if (xs_is_dict(strs)) { + const char *n_str = xs_dict_get(strs, str); + + if (xs_is_string(n_str)) + str = n_str; + } + } + } + + return str; +} diff --git a/snac.c b/snac.c index 9f5b50e..541828e 100644 --- a/snac.c +++ b/snac.c @@ -34,6 +34,7 @@ xs_str *srv_basedir = NULL; xs_dict *srv_config = NULL; xs_str *srv_baseurl = NULL; xs_str *srv_proxy_token_seed = NULL; +xs_dict *srv_langs = NULL; int dbglevel = 0; diff --git a/snac.h b/snac.h index d2d73af..69b1b74 100644 --- a/snac.h +++ b/snac.h @@ -33,6 +33,7 @@ extern xs_str *srv_basedir; extern xs_dict *srv_config; extern xs_str *srv_baseurl; extern xs_str *srv_proxy_token_seed; +extern xs_dict *srv_langs; extern int dbglevel; @@ -444,3 +445,5 @@ xs_str *make_url(const char *href, const char *proxy, int by_token); int badlogin_check(const char *user, const char *addr); void badlogin_inc(const char *user, const char *addr); + +const char *lang_str(const char *str, const snac *user); -- cgit From 02bc18eb118fcd93f5cd90a056f7b78dfe64382f Mon Sep 17 00:00:00 2001 From: default Date: Fri, 14 Feb 2025 10:04:46 +0100 Subject: Redefined L() to use lang_str(). --- html.c | 15 +++++++++++++-- httpd.c | 2 ++ snac.h | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'snac.h') diff --git a/html.c b/html.c index 140d955..f81cab2 100644 --- a/html.c +++ b/html.c @@ -627,6 +627,9 @@ static xs_html *html_instance_body(void) const char *email = xs_dict_get(srv_config, "admin_email"); const char *acct = xs_dict_get(srv_config, "admin_account"); + /* for L() */ + const snac *user = NULL; + xs *blurb = xs_replace(snac_blurb, "%host%", host); xs_html *dl; @@ -1486,7 +1489,7 @@ xs_html *html_top_controls(snac *user) } -static xs_html *html_button(char *clss, char *label, char *hint) +static xs_html *html_button(const char *clss, const char *label, const char *hint) { xs *c = xs_fmt("snac-btn-%s", clss); @@ -2584,6 +2587,8 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html *html_footer(void) { + const snac *user = NULL; + return xs_html_tag("div", xs_html_attr("class", "snac-footer"), xs_html_tag("a", @@ -2896,7 +2901,7 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, } -xs_html *html_people_list(snac *user, xs_list *list, char *header, char *t, const char *proxy) +xs_html *html_people_list(snac *user, xs_list *list, const char *header, const char *t, const char *proxy) { xs_html *snac_posts; xs_html *people = xs_html_tag("div", @@ -3327,6 +3332,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, { const char *accept = xs_dict_get(req, "accept"); int status = HTTP_STATUS_NOT_FOUND; + const snac *user = NULL; snac snac; xs *uid = NULL; const char *p_path; @@ -3393,6 +3399,8 @@ int html_get_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_NOT_FOUND; } + user = &snac; + if (xs_is_true(xs_dict_get(srv_config, "proxy_media"))) proxy = 1; @@ -4016,6 +4024,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, (void)ctype; int status = 0; + const snac *user = NULL; snac snac; const char *uid; const char *p_path; @@ -4039,6 +4048,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_UNAUTHORIZED; } + user = &snac; + p_vars = xs_dict_get(req, "p_vars"); if (p_path && strcmp(p_path, "admin/note") == 0) { /** **/ diff --git a/httpd.c b/httpd.c index d22bb14..22a148d 100644 --- a/httpd.c +++ b/httpd.c @@ -211,6 +211,8 @@ int server_get_handler(xs_dict *req, const char *q_path, { int status = 0; + const snac *user = NULL; + /* is it the server root? */ if (*q_path == '\0' || strcmp(q_path, "/") == 0) { const xs_dict *q_vars = xs_dict_get(req, "q_vars"); diff --git a/snac.h b/snac.h index 69b1b74..e2b6b5f 100644 --- a/snac.h +++ b/snac.h @@ -37,7 +37,7 @@ extern xs_dict *srv_langs; extern int dbglevel; -#define L(s) (s) +#define L(s) lang_str((s), user) #define POSTLIKE_OBJECT_TYPE "Note|Question|Page|Article|Video|Audio|Event" -- cgit From f0f93b84bec5373f9c6567b7b415ea77ca0bd064 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 15 Feb 2025 06:00:19 +0100 Subject: Optimized lang_str(). --- data.c | 19 ++++++------------- html.c | 17 +++++++++++++++-- snac.h | 1 + 3 files changed, 22 insertions(+), 15 deletions(-) (limited to 'snac.h') diff --git a/data.c b/data.c index f935b39..4308aa5 100644 --- a/data.c +++ b/data.c @@ -4072,21 +4072,14 @@ void badlogin_inc(const char *user, const char *addr) const char *lang_str(const char *str, const snac *user) /* returns a translated string */ { - if (user && xs_is_string(str) && xs_is_dict(srv_langs)) { - /* get user preference */ - const char *lang = xs_dict_get(user->config, "lang"); + const char *n_str = str; - if (xs_is_string(lang)) { - const xs_dict *strs = xs_dict_get(srv_langs, lang); + if (user && xs_is_dict(user->lang) && xs_is_string(str)) { + n_str = xs_dict_get(user->lang, str); - if (xs_is_dict(strs)) { - const char *n_str = xs_dict_get(strs, str); - - if (xs_is_string(n_str)) - str = n_str; - } - } + if (xs_is_null(n_str) || *n_str == '\0') + n_str = str; } - return str; + return n_str; } diff --git a/html.c b/html.c index e11abd1..5068b49 100644 --- a/html.c +++ b/html.c @@ -3326,6 +3326,17 @@ xs_str *html_notifications(snac *user, int skip, int show) } +void set_user_lang(snac *user) +/* sets the language dict according to user configuration */ +{ + user->lang = NULL; + const char *lang = xs_dict_get(user->config, "lang"); + + if (xs_is_string(lang)) + user->lang = xs_dict_get(srv_langs, lang); +} + + int html_get_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype, xs_str **etag, xs_str **last_modified) @@ -3399,7 +3410,8 @@ int html_get_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_NOT_FOUND; } - user = &snac; + user = &snac; /* for L() */ + set_user_lang(&snac); if (xs_is_true(xs_dict_get(srv_config, "proxy_media"))) proxy = 1; @@ -4048,7 +4060,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, return HTTP_STATUS_UNAUTHORIZED; } - user = &snac; + user = &snac; /* for L() */ + set_user_lang(&snac); p_vars = xs_dict_get(req, "p_vars"); diff --git a/snac.h b/snac.h index e2b6b5f..ac1abcd 100644 --- a/snac.h +++ b/snac.h @@ -60,6 +60,7 @@ typedef struct { xs_dict *links; /* validated links */ xs_str *actor; /* actor url */ xs_str *md5; /* actor url md5 */ + const xs_dict *lang;/* string translation dict */ } snac; typedef struct { -- cgit