From: Sebastian Harl Date: Tue, 29 Jul 2014 20:49:44 +0000 (+0200) Subject: store: Fixed JSON serialization when skipping hosts due to filters. X-Git-Tag: sysdb-0.3.0~16 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=873812bad1b030d79da6402ed6d26d008179592d store: Fixed JSON serialization when skipping hosts due to filters. Previously, it might have happened that a comma was appended to a list of hosts even though all subsequent hosts were filtered out. This created invalid JSON. Now, don't let sdb_store_host_tojson ignore hosts entirely. Instead, always let it serialize the host passed to the function and only pass on the filter to child objects. The caller is now responsible for calling the filter and, at the same time, the caller is able to correctly handle skipped hosts. Fixed the unit-test which should have caught this. --- diff --git a/src/core/store.c b/src/core/store.c index bb6cb96..cc0927e 100644 --- a/src/core/store.c +++ b/src/core/store.c @@ -629,9 +629,6 @@ sdb_store_host_tojson(sdb_store_obj_t *h, sdb_strbuf_t *buf, if ((! h) || (h->type != SDB_HOST) || (! buf)) return -1; - if (filter && (! sdb_store_matcher_matches(filter, h, NULL))) - return 0; - sdb_strbuf_append(buf, "{\"name\": \"%s\", ", SDB_OBJ(host)->name); store_common_tojson(h, buf); @@ -653,6 +650,7 @@ int sdb_store_tojson(sdb_strbuf_t *buf, sdb_store_matcher_t *filter, int flags) { sdb_avltree_iter_t *host_iter; + size_t len; if (! buf) return -1; @@ -667,20 +665,22 @@ sdb_store_tojson(sdb_strbuf_t *buf, sdb_store_matcher_t *filter, int flags) sdb_strbuf_append(buf, "{\"hosts\":["); + len = sdb_strbuf_len(buf); while (sdb_avltree_iter_has_next(host_iter)) { sdb_store_obj_t *host; - size_t len = sdb_strbuf_len(buf); host = STORE_OBJ(sdb_avltree_iter_get_next(host_iter)); assert(host); - if (sdb_store_host_tojson(host, buf, filter, flags)) - return -1; + if (filter && (! sdb_store_matcher_matches(filter, host, NULL))) + continue; - /* sdb_store_host_tojson may leave the buffer unmodified */ - if ((sdb_avltree_iter_has_next(host_iter)) - && (sdb_strbuf_len(buf) != len)) + if (sdb_strbuf_len(buf) > len) sdb_strbuf_append(buf, ","); + len = sdb_strbuf_len(buf); + + if (sdb_store_host_tojson(host, buf, filter, flags)) + return -1; } sdb_strbuf_append(buf, "]}"); diff --git a/src/include/core/store.h b/src/include/core/store.h index 494f8d6..308523a 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -420,8 +420,9 @@ sdb_store_tojson(sdb_strbuf_t *buf, sdb_store_matcher_t *filter, int flags); * Serialize a host object to JSON and append the result to the specified * buffer. If specified, only objects matching the filter will be included in * the result. The filter is applied to each object individually and, thus, - * should not be of any object-type specific kind. If the filter rejects the - * host object, the function returns success but leaves the buffer unmodified. + * should not be of any object-type specific kind. The filter is never applied + * to the specified host object; the caller is responsible for this and for + * correctly handling skipped hosts. * * Returns: * - 0 on success diff --git a/t/unit/core/store_test.c b/t/unit/core/store_test.c index bc2066a..e5383b4 100644 --- a/t/unit/core/store_test.c +++ b/t/unit/core/store_test.c @@ -450,7 +450,7 @@ START_TEST(test_store_tojson) "\"last_update\": \"1970-01-01 00:00:00 +0000\", " "\"update_interval\": \"0s\", \"backends\": []}," "], " - "\"services\": []}," + "\"services\": []}" "]}" }, { { sdb_store_ge_matcher, SDB_FIELD_LAST_UPDATE, { SDB_TYPE_DATETIME, { .datetime = 3 } } }, 0,