From ba52f94929822b1968f05cfbb37985af2e0b83a4 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Tue, 13 Sep 2016 10:44:46 +0200 Subject: [PATCH] curl_json plugin: Skip unexpected non-map values. Assume, for example, the config `Key "*/foo"`. This config expects JSON in the form: { "bar": { "foo": 1337 } } If the available JSON is instead: { "error_code": 0, "bar": { "foo": 1337 } } the code will take a look at the zero associated with "error_code" and determine that a map (with key "foo") is expected instead. Previously the code would continue, eventually calling `cj_get_type()` which expects that `key->type` is a valid pointer, resulting in a segmentation fault. This patch does three things to ensure that this segmentation fault does not happen again: 1. `cj_get_type()` checks its argument to make sure it is valid before dereferencing any pointers. 2. In case a non-map is found when a map is expected, the code will return instead of limping on. 3. After calling `cj_cb_inc_array_index()`, which may update the key, make sure that it actually did and that key is valid now. Fixes: #1896 --- src/curl_json.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/curl_json.c b/src/curl_json.c index 4188f378..a547ddcd 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -143,6 +143,9 @@ static int cj_get_type (cj_key_t *key) { const data_set_t *ds; + if ((key == NULL) || !CJ_IS_KEY (key)) + return -EINVAL; + ds = plugin_get_ds (key->type); if (ds == NULL) { @@ -226,12 +229,15 @@ static int cj_cb_number (void *ctx, buffer[sizeof (buffer) - 1] = 0; if ((key == NULL) || !CJ_IS_KEY (key)) { - if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) + if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) { NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects" " a map.", buffer); + return (CJ_CB_CONTINUE); + } + cj_cb_inc_array_index (ctx, /* update_key = */ 1); key = db->state[db->depth].key; - if (key == NULL) { + if ((key == NULL) || !CJ_IS_KEY (key)) { return (CJ_CB_CONTINUE); } } -- 2.11.0