From 98875443ea96361eb4da7890c87922ccb3571f51 Mon Sep 17 00:00:00 2001 From: Geoff Greer Date: Sun, 22 Oct 2017 01:00:32 -0700 Subject: swaygrab: Increase max depth of JSON parsing to 256. Prevent segfault if IPC response can't be parsed. The default max nesting depth of json-c is 32, which can cause some valid trees to fail to be parsed, so increase that. Also instead of segfaulting, just abort and print the error returned by json-c. --- swaygrab/json.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'swaygrab') diff --git a/swaygrab/json.c b/swaygrab/json.c index 80dae299..32b68612 100644 --- a/swaygrab/json.c +++ b/swaygrab/json.c @@ -4,6 +4,7 @@ #include #include #include +#include "log.h" #include "ipc-client.h" #include "swaygrab/json.h" @@ -12,7 +13,15 @@ static json_object *tree; void init_json_tree(int socketfd) { uint32_t len = 0; char *res = ipc_single_command(socketfd, IPC_GET_TREE, NULL, &len); - tree = json_tokener_parse(res); + struct json_tokener *tok = json_tokener_new_ex(256); + if (!tok) { + sway_abort("Unable to get json tokener."); + } + tree = json_tokener_parse_ex(tok, res, len); + if (!tree || tok->err != json_tokener_success) { + sway_abort("Unable to parse IPC response as JSON: %s", json_tokener_error_desc(tok->err)); + } + json_tokener_free(tok); } void free_json_tree() { -- cgit v1.2.3-54-g00ecf From 29f27c7cdc9e11aa560a5d49d110fc705dbc21cb Mon Sep 17 00:00:00 2001 From: Geoff Greer Date: Sun, 22 Oct 2017 18:03:45 -0700 Subject: swaygrab: Add some error handling. - If IPC response contains `success: false`, abort and print error message. - If tree has no nodes, abort with error msg instead of segfaulting. --- swaygrab/json.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'swaygrab') diff --git a/swaygrab/json.c b/swaygrab/json.c index 32b68612..286085c3 100644 --- a/swaygrab/json.c +++ b/swaygrab/json.c @@ -21,6 +21,14 @@ void init_json_tree(int socketfd) { if (!tree || tok->err != json_tokener_success) { sway_abort("Unable to parse IPC response as JSON: %s", json_tokener_error_desc(tok->err)); } + json_object *success; + json_object_object_get_ex(tree, "success", &success); + if (success && !json_object_get_boolean(success)) { + json_object *error; + json_object_object_get_ex(tree, "error", &error); + sway_abort("IPC request failed: %s", json_object_get_string(error)); + } + json_object_put(success); json_tokener_free(tok); } @@ -72,7 +80,9 @@ json_object *get_focused_container() { char *get_focused_output() { json_object *outputs, *output, *name; json_object_object_get_ex(tree, "nodes", &outputs); - + if (!outputs) { + sway_abort("Unabled to get focused output. No nodes in tree."); + } for (int i = 0; i < json_object_array_length(outputs); i++) { output = json_object_array_get_idx(outputs, i); -- cgit v1.2.3-54-g00ecf From 02da9c4e7cafb36083566e511cc7913d8922aaa6 Mon Sep 17 00:00:00 2001 From: Björn Esser Date: Thu, 14 Dec 2017 17:14:47 +0100 Subject: Adaptions for API change in json-c v0.13 --- include/sway_json_helper.h | 16 ++++++++++++++++ include/swaygrab/json.h | 2 +- sway/ipc-server.c | 4 ++-- swaybar/status_line.c | 5 ++--- swaygrab/json.c | 9 ++++----- swaylock/main.c | 4 ++-- swaymsg/main.c | 4 ++-- 7 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 include/sway_json_helper.h (limited to 'swaygrab') diff --git a/include/sway_json_helper.h b/include/sway_json_helper.h new file mode 100644 index 00000000..66f9cff1 --- /dev/null +++ b/include/sway_json_helper.h @@ -0,0 +1,16 @@ +#ifndef _SWAY_JSON_HELPER_H +#define _SWAY_JSON_HELPER_H + +#include + +// Macros for checking a specific version. +#define JSON_C_VERSION_013 (13 << 8) + +// json-c v0.13 uses size_t for array_list_length(). +#if defined(JSON_C_VERSION_NUM) && JSON_C_VERSION_NUM >= JSON_C_VERSION_013 +typedef size_t json_ar_len_t; +#else +typedef int json_ar_len_t; +#endif + +#endif // _SWAY_JSON_HELPER_H diff --git a/include/swaygrab/json.h b/include/swaygrab/json.h index c1093ef1..c0bd8587 100644 --- a/include/swaygrab/json.h +++ b/include/swaygrab/json.h @@ -1,4 +1,4 @@ -#include +#include "sway_json_helper.h" #include "wlc/wlc.h" void init_json_tree(int socketfd); diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 80f4e5d0..e10445cf 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #ifdef __linux__ @@ -25,6 +24,7 @@ struct ucred { gid_t gid; }; #endif +#include "sway_json_helper.h" #include "sway/ipc-json.h" #include "sway/ipc-server.h" #include "sway/security.h" @@ -724,7 +724,7 @@ void ipc_client_handle_command(struct ipc_client *client) { } // parse requested event types - for (int i = 0; i < json_object_array_length(request); i++) { + for (json_ar_len_t i = 0; i < json_object_array_length(request); i++) { const char *event_type = json_object_get_string(json_object_array_get_idx(request, i)); if (strcmp(event_type, "workspace") == 0) { client->subscribed_events |= event_mask(IPC_EVENT_WORKSPACE); diff --git a/swaybar/status_line.c b/swaybar/status_line.c index 87e90caf..e3cc0bf4 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c @@ -2,8 +2,8 @@ #include #include #include -#include +#include "sway_json_helper.h" #include "swaybar/config.h" #include "swaybar/status_line.h" #include "log.h" @@ -70,8 +70,7 @@ static void parse_json(struct bar *bar, const char *text) { bar->status->block_line = create_list(); - int i; - for (i = 0; i < json_object_array_length(results); ++i) { + for (json_ar_len_t i = 0; i < json_object_array_length(results); ++i) { json_object *full_text, *short_text, *color, *min_width, *align, *urgent; json_object *name, *instance, *separator, *separator_block_width; json_object *background, *border, *border_top, *border_bottom; diff --git a/swaygrab/json.c b/swaygrab/json.c index 286085c3..f0e8fa90 100644 --- a/swaygrab/json.c +++ b/swaygrab/json.c @@ -50,8 +50,7 @@ static json_object *get_focused_container_r(json_object *c) { } else { json_object *nodes, *node, *child; json_object_object_get_ex(c, "nodes", &nodes); - int i; - for (i = 0; i < json_object_array_length(nodes); i++) { + for (json_ar_len_t i = 0; i < json_object_array_length(nodes); i++) { node = json_object_array_get_idx(nodes, i); if ((child = get_focused_container_r(node))) { @@ -60,7 +59,7 @@ static json_object *get_focused_container_r(json_object *c) { } json_object_object_get_ex(c, "floating_nodes", &nodes); - for (i = 0; i < json_object_array_length(nodes); i++) { + for (json_ar_len_t i = 0; i < json_object_array_length(nodes); i++) { node = json_object_array_get_idx(nodes, i); if ((child = get_focused_container_r(node))) { @@ -83,7 +82,7 @@ char *get_focused_output() { if (!outputs) { sway_abort("Unabled to get focused output. No nodes in tree."); } - for (int i = 0; i < json_object_array_length(outputs); i++) { + for (json_ar_len_t i = 0; i < json_object_array_length(outputs); i++) { output = json_object_array_get_idx(outputs, i); if (get_focused_container_r(output)) { @@ -131,7 +130,7 @@ json_object *get_output_container(const char *output) { json_object *outputs, *json_output, *name; json_object_object_get_ex(tree, "nodes", &outputs); - for (int i = 0; i < json_object_array_length(outputs); i++) { + for (json_ar_len_t i = 0; i < json_object_array_length(outputs); i++) { json_output = json_object_array_get_idx(outputs, i); json_object_object_get_ex(json_output, "name", &name); diff --git a/swaylock/main.c b/swaylock/main.c index c2615951..7b7dd601 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -13,6 +12,7 @@ #include #include #include +#include "sway_json_helper.h" #include "client/window.h" #include "client/registry.h" #include "client/cairo.h" @@ -584,7 +584,7 @@ int main(int argc, char **argv) { for (i = 0; i < registry->outputs->length; ++i) { if (displays_paths[i * 2] != NULL) { - for (int j = 0;; ++j) { + for (json_ar_len_t j = 0;; ++j) { if (j >= json_object_array_length(json_outputs)) { sway_log(L_ERROR, "%s is not an extant output", displays_paths[i * 2]); exit(EXIT_FAILURE); diff --git a/swaymsg/main.c b/swaymsg/main.c index 2f9cfb14..0ee7c76f 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include "sway_json_helper.h" #include "stringop.h" #include "ipc-client.h" #include "readline.h" @@ -149,7 +149,7 @@ static void pretty_print_version(json_object *v) { static void pretty_print_clipboard(json_object *v) { if (success(v, true)) { if (json_object_is_type(v, json_type_array)) { - for (int i = 0; i < json_object_array_length(v); ++i) { + for (json_ar_len_t i = 0; i < json_object_array_length(v); ++i) { json_object *o = json_object_array_get_idx(v, i); printf("%s\n", json_object_get_string(o)); } -- cgit v1.2.3-54-g00ecf