From f873bcc4e1b2d39edb9ca91ea60db24e6b6e42f2 Mon Sep 17 00:00:00 2001 From: Jason Nader Date: Mon, 18 Oct 2021 18:41:11 +0900 Subject: swaymsg: use INT_MAX max JSON depth when parsing IPC response Same reasoning as fe11caeac946cecda491d592044a6b9519ef2035. Without this, swaymsg would fail with a cryptic error message when the JSON was nested too deep. --- swaymsg/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'swaymsg') diff --git a/swaymsg/main.c b/swaymsg/main.c index 574d3b75..ce5d7d71 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 200809L +#include #include #include #include @@ -480,7 +481,9 @@ int main(int argc, char **argv) { char *resp = ipc_single_command(socketfd, type, command, &len); // pretty print the json - json_object *obj = json_tokener_parse(resp); + json_tokener *tok = json_tokener_new_ex(INT_MAX); + json_object *obj = json_tokener_parse_ex(tok, resp, -1); + json_tokener_free(tok); if (obj == NULL) { if (!quiet) { fprintf(stderr, "ERROR: Could not parse json response from ipc. " @@ -517,7 +520,9 @@ int main(int argc, char **argv) { break; } - json_object *obj = json_tokener_parse(reply->payload); + json_tokener *tok = json_tokener_new_ex(INT_MAX); + json_object *obj = json_tokener_parse_ex(tok, reply->payload, -1); + json_tokener_free(tok); if (obj == NULL) { if (!quiet) { fprintf(stderr, "ERROR: Could not parse json response from" -- cgit v1.2.3 From 55cd8abd76cf6a31ca7edf67473c048f90f99140 Mon Sep 17 00:00:00 2001 From: Jason Nader Date: Mon, 18 Oct 2021 18:44:41 +0900 Subject: swaymsg: be explicit about the json parser error --- swaymsg/main.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'swaymsg') diff --git a/swaymsg/main.c b/swaymsg/main.c index ce5d7d71..c3468a16 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -483,12 +483,12 @@ int main(int argc, char **argv) { // pretty print the json json_tokener *tok = json_tokener_new_ex(INT_MAX); json_object *obj = json_tokener_parse_ex(tok, resp, -1); + enum json_tokener_error err = json_tokener_get_error(tok); json_tokener_free(tok); - if (obj == NULL) { + if (obj == NULL || err != json_tokener_success) { if (!quiet) { - fprintf(stderr, "ERROR: Could not parse json response from ipc. " - "This is a bug in sway."); - printf("%s\n", resp); + sway_log(SWAY_ERROR, "failed to parse payload as json: %s", + json_tokener_error_desc(err)); } ret = 1; } else { @@ -522,11 +522,12 @@ int main(int argc, char **argv) { json_tokener *tok = json_tokener_new_ex(INT_MAX); json_object *obj = json_tokener_parse_ex(tok, reply->payload, -1); + enum json_tokener_error err = json_tokener_get_error(tok); json_tokener_free(tok); - if (obj == NULL) { + if (obj == NULL || err != json_tokener_success) { if (!quiet) { - fprintf(stderr, "ERROR: Could not parse json response from" - " ipc. This is a bug in sway."); + sway_log(SWAY_ERROR, "failed to parse payload as json: %s", + json_tokener_error_desc(err)); ret = 1; } break; -- cgit v1.2.3 From db70f6496c7be38edff5d5594d1fb5a7895a23bc Mon Sep 17 00:00:00 2001 From: Jason Nader Date: Mon, 18 Oct 2021 18:45:40 +0900 Subject: swaymsg: fix misplaced return value --- swaymsg/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'swaymsg') diff --git a/swaymsg/main.c b/swaymsg/main.c index c3468a16..5f7854f5 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -528,8 +528,8 @@ int main(int argc, char **argv) { if (!quiet) { sway_log(SWAY_ERROR, "failed to parse payload as json: %s", json_tokener_error_desc(err)); - ret = 1; } + ret = 1; break; } else if (quiet) { json_object_put(obj); -- cgit v1.2.3 From 944d7031c5a1ffebb105fb1fed3f957903abe8da Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 21 Oct 2021 18:20:26 +0200 Subject: fix: handle NULL from json_tokener_new_ex if there is not enough memory to fit json_tokener and (depth * json_tokener_srec) in RAM, don't segfault. --- swaymsg/main.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'swaymsg') diff --git a/swaymsg/main.c b/swaymsg/main.c index 5f7854f5..3698294a 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -482,28 +482,33 @@ int main(int argc, char **argv) { // pretty print the json json_tokener *tok = json_tokener_new_ex(INT_MAX); - json_object *obj = json_tokener_parse_ex(tok, resp, -1); - enum json_tokener_error err = json_tokener_get_error(tok); - json_tokener_free(tok); - if (obj == NULL || err != json_tokener_success) { - if (!quiet) { - sway_log(SWAY_ERROR, "failed to parse payload as json: %s", - json_tokener_error_desc(err)); - } + if (tok == NULL) { + sway_log(SWAY_ERROR, "failed allocating json_tokener"); ret = 1; } else { - if (!success(obj, true)) { - ret = 2; - } - if (!quiet && (type != IPC_SUBSCRIBE || ret != 0)) { - if (raw) { - printf("%s\n", json_object_to_json_string_ext(obj, - JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); - } else { - pretty_print(type, obj); + json_object *obj = json_tokener_parse_ex(tok, resp, -1); + enum json_tokener_error err = json_tokener_get_error(tok); + json_tokener_free(tok); + if (obj == NULL || err != json_tokener_success) { + if (!quiet) { + sway_log(SWAY_ERROR, "failed to parse payload as json: %s", + json_tokener_error_desc(err)); } + ret = 1; + } else { + if (!success(obj, true)) { + ret = 2; + } + if (!quiet && (type != IPC_SUBSCRIBE || ret != 0)) { + if (raw) { + printf("%s\n", json_object_to_json_string_ext(obj, + JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); + } else { + pretty_print(type, obj); + } + } + json_object_put(obj); } - json_object_put(obj); } free(command); free(resp); @@ -521,6 +526,11 @@ int main(int argc, char **argv) { } json_tokener *tok = json_tokener_new_ex(INT_MAX); + if (tok == NULL) { + sway_log(SWAY_ERROR, "failed allocating json_tokener"); + ret = 1; + break; + } json_object *obj = json_tokener_parse_ex(tok, reply->payload, -1); enum json_tokener_error err = json_tokener_get_error(tok); json_tokener_free(tok); -- cgit v1.2.3 From 96baef8ae9955dd7ffd85c6b769a14df1f95bc97 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 21 Oct 2021 18:22:50 +0200 Subject: fix: use sane value for json_tokener max_depth INT_MAX causes a NULL pointer if there is not enough memory available to fit (INT_MAX * sizeof(struct json_tokener_srec)). --- swaymsg/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'swaymsg') diff --git a/swaymsg/main.c b/swaymsg/main.c index 3698294a..dcf42cb6 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -1,4 +1,8 @@ #define _POSIX_C_SOURCE 200809L + +// arbitrary number, it's probably sufficient, higher number = more memory usage +#define JSON_MAX_DEPTH 512 + #include #include #include @@ -481,7 +485,7 @@ int main(int argc, char **argv) { char *resp = ipc_single_command(socketfd, type, command, &len); // pretty print the json - json_tokener *tok = json_tokener_new_ex(INT_MAX); + json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH); if (tok == NULL) { sway_log(SWAY_ERROR, "failed allocating json_tokener"); ret = 1; @@ -525,7 +529,7 @@ int main(int argc, char **argv) { break; } - json_tokener *tok = json_tokener_new_ex(INT_MAX); + json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH); if (tok == NULL) { sway_log(SWAY_ERROR, "failed allocating json_tokener"); ret = 1; -- cgit v1.2.3 From b223f702500d7cda6336e948062d680f07f34f66 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Thu, 21 Oct 2021 22:47:35 +0200 Subject: refactor: use sway_abort instead --- swaymsg/main.c | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'swaymsg') diff --git a/swaymsg/main.c b/swaymsg/main.c index dcf42cb6..e469319a 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -487,32 +487,33 @@ int main(int argc, char **argv) { // pretty print the json json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH); if (tok == NULL) { - sway_log(SWAY_ERROR, "failed allocating json_tokener"); + if (quiet) { + exit(EXIT_FAILURE); + } + sway_abort("failed allocating json_tokener"); + } + json_object *obj = json_tokener_parse_ex(tok, resp, -1); + enum json_tokener_error err = json_tokener_get_error(tok); + json_tokener_free(tok); + if (obj == NULL || err != json_tokener_success) { + if (!quiet) { + sway_log(SWAY_ERROR, "failed to parse payload as json: %s", + json_tokener_error_desc(err)); + } ret = 1; } else { - json_object *obj = json_tokener_parse_ex(tok, resp, -1); - enum json_tokener_error err = json_tokener_get_error(tok); - json_tokener_free(tok); - if (obj == NULL || err != json_tokener_success) { - if (!quiet) { - sway_log(SWAY_ERROR, "failed to parse payload as json: %s", - json_tokener_error_desc(err)); - } - ret = 1; - } else { - if (!success(obj, true)) { - ret = 2; - } - if (!quiet && (type != IPC_SUBSCRIBE || ret != 0)) { - if (raw) { - printf("%s\n", json_object_to_json_string_ext(obj, - JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); - } else { - pretty_print(type, obj); - } + if (!success(obj, true)) { + ret = 2; + } + if (!quiet && (type != IPC_SUBSCRIBE || ret != 0)) { + if (raw) { + printf("%s\n", json_object_to_json_string_ext(obj, + JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); + } else { + pretty_print(type, obj); } - json_object_put(obj); } + json_object_put(obj); } free(command); free(resp); @@ -531,9 +532,10 @@ int main(int argc, char **argv) { json_tokener *tok = json_tokener_new_ex(JSON_MAX_DEPTH); if (tok == NULL) { - sway_log(SWAY_ERROR, "failed allocating json_tokener"); - ret = 1; - break; + if (quiet) { + exit(EXIT_FAILURE); + } + sway_abort("failed allocating json_tokener"); } json_object *obj = json_tokener_parse_ex(tok, reply->payload, -1); enum json_tokener_error err = json_tokener_get_error(tok); -- cgit v1.2.3 From 9303bed4d4523d158b33c44f534a53b21d7688d6 Mon Sep 17 00:00:00 2001 From: Jason Nader Date: Mon, 25 Oct 2021 13:28:32 +0900 Subject: refactor: use JSON_MAX_DEPTH everywhere --- swaymsg/main.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'swaymsg') diff --git a/swaymsg/main.c b/swaymsg/main.c index e469319a..0d9dc5a0 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -1,8 +1,5 @@ #define _POSIX_C_SOURCE 200809L -// arbitrary number, it's probably sufficient, higher number = more memory usage -#define JSON_MAX_DEPTH 512 - #include #include #include -- cgit v1.2.3