diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-06-02 14:41:51 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-06-02 14:42:10 +0100 |
commit | c1184c7823b41ee51750d7551403bbd9499a71ff (patch) | |
tree | 7a6d54c4b6993ffc5d2ad70f6ea69b9bafd4664b /contrib/libucl | |
parent | eda600d5632e65b3a97b2faa794dc1aeb6689f96 (diff) | |
download | rspamd-c1184c7823b41ee51750d7551403bbd9499a71ff.tar.gz rspamd-c1184c7823b41ee51750d7551403bbd9499a71ff.zip |
[Fix] Fix objects merging in UCL
Diffstat (limited to 'contrib/libucl')
-rw-r--r-- | contrib/libucl/ucl_util.c | 98 |
1 files changed, 83 insertions, 15 deletions
diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c index 07af232d9..812655d2e 100644 --- a/contrib/libucl/ucl_util.c +++ b/contrib/libucl/ucl_util.c @@ -2195,7 +2195,7 @@ ucl_object_insert_key_common (ucl_object_t *top, ucl_object_t *elt, while ((cur = ucl_object_iterate (elt, &it, true)) != NULL) { tmp = ucl_object_ref (cur); ucl_object_insert_key_common (found, tmp, cur->key, - cur->keylen, copy_key, false, false); + cur->keylen, copy_key, true, false); } ucl_object_unref (elt); } @@ -2292,30 +2292,98 @@ ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy) ucl_object_t *cur = NULL, *cp = NULL, *found = NULL; ucl_object_iter_t iter = NULL; - if (top == NULL || top->type != UCL_OBJECT || elt == NULL || elt->type != UCL_OBJECT) { + if (top == NULL || elt == NULL) { return false; } - /* Mix two hashes */ - while ((cur = (ucl_object_t*)ucl_hash_iterate (elt->value.ov, &iter))) { - if (copy) { - cp = ucl_object_copy (cur); + if (top->type == UCL_ARRAY) { + if (elt->type == UCL_ARRAY) { + /* Merge two arrays */ + return ucl_array_merge (top, elt, copy); } else { - cp = ucl_object_ref (cur); + if (copy) { + ucl_array_append (top, ucl_object_copy (elt)); + + return true; + } + else { + ucl_array_append (top, ucl_object_ref (elt)); + + return true; + } } - found = __DECONST(ucl_object_t *, ucl_hash_search (top->value.ov, cp->key, cp->keylen)); - if (found == NULL) { - /* The key does not exist */ - top->value.ov = ucl_hash_insert_object (top->value.ov, cp, false); - top->len ++; + } + else if (top->type == UCL_OBJECT) { + if (elt->type == UCL_OBJECT) { + /* Mix two hashes */ + while ((cur = (ucl_object_t *) ucl_hash_iterate (elt->value.ov, + &iter))) { + + if (copy) { + cp = ucl_object_copy (cur); + } else { + cp = ucl_object_ref (cur); + } + + found = __DECONST(ucl_object_t *, + ucl_hash_search (top->value.ov, cp->key, cp->keylen)); + + if (found == NULL) { + /* The key does not exist */ + top->value.ov = ucl_hash_insert_object (top->value.ov, cp, + false); + top->len++; + } + else { + /* The key already exists, merge it recursively */ + if (found->type == UCL_OBJECT || found->type == UCL_ARRAY) { + if (!ucl_object_merge (found, cp, copy)) { + return false; + } + } + else { + ucl_hash_replace (top->value.ov, found, cp); + ucl_object_unref (found); + } + } + } } else { - /* The key already exists, replace it */ - ucl_hash_replace (top->value.ov, found, cp); - ucl_object_unref (found); + if (copy) { + cp = ucl_object_copy (elt); + } + else { + cp = ucl_object_ref (elt); + } + + found = __DECONST(ucl_object_t *, + ucl_hash_search (top->value.ov, cp->key, cp->keylen)); + + if (found == NULL) { + /* The key does not exist */ + top->value.ov = ucl_hash_insert_object (top->value.ov, cp, + false); + top->len++; + } + else { + /* The key already exists, merge it recursively */ + if (found->type == UCL_OBJECT || found->type == UCL_ARRAY) { + if (!ucl_object_merge (found, cp, copy)) { + return false; + } + } + else { + ucl_hash_replace (top->value.ov, found, cp); + ucl_object_unref (found); + } + } } } + else { + /* Cannot merge trivial objects */ + return false; + } return true; } |