Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Update libucl to latest version which fixes an error reporting when reading an empty pkg.conf
Baptiste Daroussin committed 10 years ago
commit 8f046d174f2d0ba2533e156eb99ab5a33ffd9b2d
parent 290a89a
14 files changed +363 -191
modified external/libucl/ChangeLog.md
@@ -37,3 +37,31 @@

- Fixed a bug with macroes that come after an empty object
- Fixed a bug in include processing when an incorrect variable has been destroyed (use-after-free)
+

+
### Libucl 0.8.0
+

+
- Allow to save comments and macros when parsing UCL documents
+
- C++ API
+
- Python bindings (by Eitan Adler)
+
- Add msgpack support for parser and emitter
+
- Add Canonical S-expressions parser for libucl
+
- CLI interface for parsing and validation (by Maxim Ignatenko)
+
- Implement include with priority
+
- Add 'nested' functionality to .include macro (by Allan Jude)
+
- Allow searching an array of paths for includes (by Allan Jude)
+
- Add new .load macro (by Allan Jude)
+
- Implement .inherit macro (#100)
+
- Add merge strategies
+
- Add schema validation to lua API
+
- Add support for external references to schema validation
+
- Add coveralls integration to libucl
+
- Implement tests for 80% of libucl code lines
+
- Fix tonns of minor and major bugs
+
- Improve documentation
+
- Rework function names to the common conventions (old names are preserved for backwards compatibility)
+
- Add Coverity scan integration
+
- Add fuzz tests
+

+
**Incompatible changes**:
+

+
- `ucl_object_emit_full` now accepts additional argument `comments` that could be used to emit comments with UCL output

\ No newline at end of file
modified external/libucl/include/ucl++.h
@@ -26,7 +26,6 @@
#include <string>
#include <memory>
#include <iostream>
-
#include <strstream>

#include "ucl.h"

@@ -120,18 +119,19 @@ public:
			it = std::shared_ptr<void>(ucl_object_iterate_new (obj.obj.get()),
					ucl_iter_deleter());
			cur.reset (new Ucl(ucl_object_iterate_safe (it.get(), true)));
+
			if (!*cur) {
+
				it.reset ();
+
				cur.reset ();
+
			}
		}

		const_iterator() {}
-
		const_iterator(const const_iterator &other) {
-
			it = other.it;
-
		}
+
		const_iterator(const const_iterator &other) = delete;
+
		const_iterator(const_iterator &&other) = default;
		~const_iterator() {}

-
		const_iterator& operator=(const const_iterator &other) {
-
			it = other.it;
-
			return *this;
-
		}
+
		const_iterator& operator=(const const_iterator &other) = delete;
+
		const_iterator& operator=(const_iterator &&other) = default;

		bool operator==(const const_iterator &other) const
		{
@@ -264,45 +264,51 @@ public:
		return res;
	}

-
	double number_value () const
+
	double number_value (const double default_val = 0.0) const
	{
-
		if (obj) {
-
			return ucl_object_todouble (obj.get());
+
		double res;
+

+
		if (ucl_object_todouble_safe(obj.get(), &res)) {
+
			return res;
		}

-
		return 0.0;
+
		return default_val;
	}

-
	int64_t int_value () const
+
	int64_t int_value (const int64_t default_val = 0) const
	{
-
		if (obj) {
-
			return ucl_object_toint (obj.get());
+
		int64_t res;
+

+
		if (ucl_object_toint_safe(obj.get(), &res)) {
+
			return res;
		}

-
		return 0;
+
		return default_val;
	}

-
	bool bool_value () const
+
	bool bool_value (const bool default_val = false) const
	{
-
		if (obj) {
-
			return ucl_object_toboolean (obj.get());
+
		bool res;
+

+
		if (ucl_object_toboolean_safe(obj.get(), &res)) {
+
			return res;
		}

-
		return false;
+
		return default_val;
	}

-
	const std::string string_value () const
+
	const std::string string_value (const std::string& default_val = "") const
	{
-
		std::string res;
+
		const char* res = nullptr;

-
		if (obj) {
-
			res.assign (ucl_object_tostring (obj.get()));
+
		if (ucl_object_tostring_safe(obj.get(), &res)) {
+
			return res;
		}

-
		return res;
+
		return default_val;
	}

-
	const Ucl operator[] (size_t i) const
+
	const Ucl at (size_t i) const
	{
		if (type () == UCL_ARRAY) {
			return Ucl (ucl_array_find_index (obj.get(), i));
@@ -311,15 +317,25 @@ public:
		return Ucl (nullptr);
	}

-
	const Ucl operator[](const std::string &key) const
+
	const Ucl lookup (const std::string &key) const
	{
		if (type () == UCL_OBJECT) {
-
			return Ucl (ucl_object_find_keyl (obj.get(),
+
			return Ucl (ucl_object_lookup_len (obj.get(),
					key.data (), key.size ()));
		}

		return Ucl (nullptr);
	}
+

+
	inline const Ucl operator[] (size_t i) const
+
	{
+
		return at(i);
+
	}
+

+
	inline const Ucl operator[](const std::string &key) const
+
	{
+
		return lookup(key);
+
	}
	// Serialize.
	void dump (std::string &out, ucl_emitter_t type = UCL_EMIT_JSON) const
	{
@@ -328,7 +344,7 @@ public:
		cbdata = Ucl::default_emit_funcs();
		cbdata.ud = reinterpret_cast<void *>(&out);

-
		ucl_object_emit_full (obj.get(), type, &cbdata);
+
		ucl_object_emit_full (obj.get(), type, &cbdata, nullptr);
	}

	std::string dump (ucl_emitter_t type = UCL_EMIT_JSON) const
@@ -388,7 +404,7 @@ public:
	bool operator> (const Ucl &rhs) const { return (rhs < *this); }
	bool operator>= (const Ucl &rhs) const { return !(*this < rhs); }

-
	operator bool () const
+
	explicit operator bool () const
	{
		if (!obj || type() == UCL_NULL) {
			return false;
modified external/libucl/include/ucl.h
@@ -107,7 +107,8 @@ typedef enum ucl_error {
	UCL_ENESTED, /**< Input has too many recursion levels */
	UCL_EMACRO, /**< Error processing a macro */
	UCL_EINTERNAL, /**< Internal unclassified error */
-
	UCL_ESSL /**< SSL error */
+
	UCL_ESSL, /**< SSL error */
+
	UCL_EMERGE /**< A merge error occured */
} ucl_error_t;

/**
@@ -661,8 +662,9 @@ UCL_EXTERN const char* ucl_object_tolstring (const ucl_object_t *obj, size_t *tl
 * @param key key to search
 * @return object matching the specified key or NULL if key was not found
 */
-
UCL_EXTERN const ucl_object_t* ucl_object_find_key (const ucl_object_t *obj,
+
UCL_EXTERN const ucl_object_t* ucl_object_lookup (const ucl_object_t *obj,
		const char *key);
+
#define ucl_object_find_key ucl_object_lookup

/**
 * Return object identified by a key in the specified object, if the first key is
@@ -674,8 +676,9 @@ UCL_EXTERN const ucl_object_t* ucl_object_find_key (const ucl_object_t *obj,
 * @param ... list of alternative keys to search (NULL terminated)
 * @return object matching the specified key or NULL if key was not found
 */
-
UCL_EXTERN const ucl_object_t* ucl_object_find_any_key (const ucl_object_t *obj,
+
UCL_EXTERN const ucl_object_t* ucl_object_lookup_any (const ucl_object_t *obj,
		const char *key, ...);
+
#define ucl_object_find_any_key ucl_object_lookup_any

/**
 * Return object identified by a fixed size key in the specified object
@@ -684,8 +687,9 @@ UCL_EXTERN const ucl_object_t* ucl_object_find_any_key (const ucl_object_t *obj,
 * @param klen length of a key
 * @return object matching the specified key or NULL if key was not found
 */
-
UCL_EXTERN const ucl_object_t* ucl_object_find_keyl (const ucl_object_t *obj,
+
UCL_EXTERN const ucl_object_t* ucl_object_lookup_len (const ucl_object_t *obj,
		const char *key, size_t klen);
+
#define ucl_object_find_keyl ucl_object_lookup_len

/**
 * Return object identified by dot notation string
@@ -693,8 +697,9 @@ UCL_EXTERN const ucl_object_t* ucl_object_find_keyl (const ucl_object_t *obj,
 * @param path dot.notation.path to the path to lookup. May use numeric .index on arrays
 * @return object matched the specified path or NULL if path is not found
 */
-
UCL_EXTERN const ucl_object_t *ucl_lookup_path (const ucl_object_t *obj,
+
UCL_EXTERN const ucl_object_t *ucl_object_lookup_path (const ucl_object_t *obj,
		const char *path);
+
#define ucl_lookup_path ucl_object_lookup_path

/**
 * Return object identified by object notation string using arbitrary delimiter
@@ -703,8 +708,9 @@ UCL_EXTERN const ucl_object_t *ucl_lookup_path (const ucl_object_t *obj,
 * @param sep the sepatorator to use in place of . (incase keys have . in them)
 * @return object matched the specified path or NULL if path is not found
 */
-
UCL_EXTERN const ucl_object_t *ucl_lookup_path_char (const ucl_object_t *obj,
+
UCL_EXTERN const ucl_object_t *ucl_object_lookup_path_char (const ucl_object_t *obj,
		const char *path, char sep);
+
#define ucl_lookup_path_char ucl_object_lookup_path_char

/**
 * Returns a key of an object as a NULL terminated string
@@ -802,8 +808,9 @@ typedef void* ucl_object_iter_t;
 * while ((cur = ucl_iterate_object (obj, &it)) != NULL) ...
 * @return the next object or NULL
 */
-
UCL_EXTERN const ucl_object_t* ucl_iterate_object (const ucl_object_t *obj,
+
UCL_EXTERN const ucl_object_t* ucl_object_iterate (const ucl_object_t *obj,
		ucl_object_iter_t *iter, bool expand_values);
+
#define ucl_iterate_object ucl_object_iterate

/**
 * Create new safe iterator for the specified object
@@ -1072,34 +1079,34 @@ UCL_EXTERN ucl_object_t* ucl_parser_get_object (struct ucl_parser *parser);
 * @param parser parser object
 * @return error description
 */
-
UCL_EXTERN const char *ucl_parser_get_error(struct ucl_parser *parser);
+
UCL_EXTERN const char *ucl_parser_get_error (struct ucl_parser *parser);

/**
 * Get the code of the last error
 * @param parser parser object
 * @return error code
 */
-
UCL_EXTERN int ucl_parser_get_error_code(struct ucl_parser *parser);
+
UCL_EXTERN int ucl_parser_get_error_code (struct ucl_parser *parser);

/**
 * Get the current column number within parser
 * @param parser parser object
 * @return current column number
 */
-
UCL_EXTERN unsigned ucl_parser_get_column(struct ucl_parser *parser);
+
UCL_EXTERN unsigned ucl_parser_get_column (struct ucl_parser *parser);

/**
 * Get the current line number within parser
 * @param parser parser object
 * @return current line number
 */
-
UCL_EXTERN unsigned ucl_parser_get_linenum(struct ucl_parser *parser);
+
UCL_EXTERN unsigned ucl_parser_get_linenum (struct ucl_parser *parser);

/**
 * Clear the error in the parser
 * @param parser parser object
 */
-
UCL_EXTERN void ucl_parser_clear_error(struct ucl_parser *parser);
+
UCL_EXTERN void ucl_parser_clear_error (struct ucl_parser *parser);

/**
 * Free ucl parser object
@@ -1125,6 +1132,25 @@ UCL_EXTERN const ucl_object_t * ucl_comments_find (const ucl_object_t *comments,
		const ucl_object_t *srch);

/**
+
 * Move comment from `from` object to `to` object
+
 * @param comments comments object
+
 * @param what source object
+
 * @param whith destination object
+
 * @return `true` if `from` has comment and it has been moved to `to`
+
 */
+
UCL_EXTERN bool ucl_comments_move (ucl_object_t *comments,
+
		const ucl_object_t *from, const ucl_object_t *to);
+

+
/**
+
 * Adds a new comment for an object
+
 * @param comments comments object
+
 * @param obj object to add comment to
+
 * @param comment string representation of a comment
+
 */
+
UCL_EXTERN void ucl_comments_add (ucl_object_t *comments,
+
		const ucl_object_t *obj, const char *comment);
+

+
/**
 * Add new public key to parser for signatures check
 * @param parser parser object
 * @param key PEM representation of a key
@@ -1132,7 +1158,8 @@ UCL_EXTERN const ucl_object_t * ucl_comments_find (const ucl_object_t *comments,
 * @param err if *err is NULL it is set to parser error
 * @return true if a key has been successfully added
 */
-
UCL_EXTERN bool ucl_pubkey_add (struct ucl_parser *parser, const unsigned char *key, size_t len);
+
UCL_EXTERN bool ucl_parser_pubkey_add (struct ucl_parser *parser,
+
		const unsigned char *key, size_t len);

/**
 * Set FILENAME and CURDIR variables in parser
modified external/libucl/lua/lua_ucl.c
@@ -150,14 +150,14 @@ ucl_object_lua_push_object (lua_State *L, const ucl_object_t *obj,
	}

	/* Optimize allocation by preallocation of table */
-
	while (ucl_iterate_object (obj, &it, true) != NULL) {
+
	while (ucl_object_iterate (obj, &it, true) != NULL) {
		nelt ++;
	}

	lua_createtable (L, 0, nelt);
	it = NULL;

-
	while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) {
+
	while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
		ucl_object_lua_push_element (L, ucl_object_key (cur), cur);
	}

@@ -860,7 +860,7 @@ lua_ucl_object_validate (lua_State *L)
		}

		if (path) {
-
			schema_elt = ucl_lookup_path_char (schema, path, '/');
+
			schema_elt = ucl_object_lookup_path_char (schema, path, '/');
		}
		else {
			/* Use the top object */
modified external/libucl/src/ucl_emitter.c
@@ -268,7 +268,7 @@ ucl_emitter_common_start_array (struct ucl_emitter_context *ctx,

	if (obj->type == UCL_ARRAY) {
		/* explicit array */
-
		while ((cur = ucl_iterate_object (obj, &iter, true)) != NULL) {
+
		while ((cur = ucl_object_iterate (obj, &iter, true)) != NULL) {
			ucl_emitter_common_elt (ctx, cur, first, false, compact);
			first = false;
		}
@@ -381,7 +381,7 @@ ucl_emitter_common_elt (struct ucl_emitter_context *ctx,
	ucl_add_tabs (func, ctx->indent, compact);

	if (ctx->comments && ctx->id == UCL_EMIT_CONFIG) {
-
		comment = ucl_object_find_keyl (ctx->comments, (const char *)&obj,
+
		comment = ucl_object_lookup_len (ctx->comments, (const char *)&obj,
				sizeof (void *));

		if (comment) {
@@ -551,7 +551,7 @@ ucl_emit_msgpack_elt (struct ucl_emitter_context *ctx,
		ucl_emit_msgpack_start_obj (ctx, obj, print_key);
		it = NULL;

-
		while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) {
+
		while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
			LL_FOREACH (cur, celt) {
				ucl_emit_msgpack_elt (ctx, celt, false, true);
				/* XXX:
@@ -570,7 +570,7 @@ ucl_emit_msgpack_elt (struct ucl_emitter_context *ctx,
		ucl_emit_msgpack_start_array (ctx, obj, print_key);
		it = NULL;

-
		while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) {
+
		while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
			ucl_emit_msgpack_elt (ctx, cur, false, false);
		}

modified external/libucl/src/ucl_hash.c
@@ -117,7 +117,7 @@ static inline int
ucl_hash_equal (const ucl_object_t *k1, const ucl_object_t *k2)
{
	if (k1->keylen == k2->keylen) {
-
		return strncmp (k1->key, k2->key, k1->keylen) == 0;
+
		return memcmp (k1->key, k2->key, k1->keylen) == 0;
	}

	return 0;
@@ -216,7 +216,7 @@ static inline int
ucl_hash_caseless_equal (const ucl_object_t *k1, const ucl_object_t *k2)
{
	if (k1->keylen == k2->keylen) {
-
		return strncasecmp (k1->key, k2->key, k1->keylen) == 0;
+
		return memcmp (k1->key, k2->key, k1->keylen) == 0;
	}

	return 0;
modified external/libucl/src/ucl_parser.c
@@ -259,7 +259,7 @@ ucl_lex_time_multiplier (const unsigned char c) {
			{'h', 60 * 60},
			{'d', 60 * 60 * 24},
			{'w', 60 * 60 * 24 * 7},
-
			{'y', 60 * 60 * 24 * 7 * 365}
+
			{'y', 60 * 60 * 24 * 365}
	};
	int i;

@@ -1068,6 +1068,7 @@ ucl_parser_process_object_element (struct ucl_parser *parser, ucl_object_t *nobj
{
	ucl_hash_t *container;
	ucl_object_t *tobj;
+
	char errmsg[256];

	container = parser->stack->obj->value.ov;

@@ -1126,25 +1127,36 @@ ucl_parser_process_object_element (struct ucl_parser *parser, ucl_object_t *nobj
			break;

		case UCL_DUPLICATE_ERROR:
-
			ucl_create_err (&parser->err, "error while parsing %s: "
-
					"line: %d, column: %d: duplicate element for key '%s' "
-
					"has been found",
-
					parser->cur_file ? parser->cur_file : "<unknown>",
-
					parser->chunks->line, parser->chunks->column, nobj->key);
+
			snprintf(errmsg, sizeof(errmsg),
+
					"duplicate element for key '%s' found",
+
					nobj->key);
+
			ucl_set_err (parser, UCL_EMERGE, errmsg, &parser->err);
			return false;

		case UCL_DUPLICATE_MERGE:
			/*
			 * Here we do have some old object so we just push it on top of objects stack
+
			 * Check priority and then perform the merge on the remaining objects
			 */
			if (tobj->type == UCL_OBJECT || tobj->type == UCL_ARRAY) {
				ucl_object_unref (nobj);
				nobj = tobj;
			}
-
			else {
-
				/* For other types we create implicit array as usual */
+
			else if (priold == prinew) {
				ucl_parser_append_elt (parser, container, tobj, nobj);
			}
+
			else if (priold > prinew) {
+
				/*
+
				 * We add this new object to a list of trash objects just to ensure
+
				 * that it won't come to any real object
+
				 * XXX: rather inefficient approach
+
				 */
+
				DL_APPEND (parser->trash_objs, nobj);
+
			}
+
			else {
+
				ucl_hash_replace (container, tobj, nobj);
+
				ucl_object_unref (tobj);
+
			}
			break;
		}
	}
@@ -1575,6 +1587,10 @@ ucl_parse_value (struct ucl_parser *parser, struct ucl_chunk *chunk)
			}

			obj = ucl_parser_get_container (parser);
+
			if (!obj) {
+
				return false;
+
			}
+

			str_len = chunk->pos - c - 2;
			obj->type = UCL_STRING;
			if ((str_len = ucl_copy_or_store_ptr (parser, c + 1,
@@ -2294,7 +2310,7 @@ ucl_state_machine (struct ucl_parser *parser)
					ucl_chunk_skipc (chunk, p);
				}
				else {
-
					if (p - c > 0) {
+
					if (c != NULL && p - c > 0) {
						/* We got macro name */
						macro_len = (size_t) (p - c);
						HASH_FIND (hh, parser->macroes, c, macro_len, macro);
@@ -2347,7 +2363,7 @@ ucl_state_machine (struct ucl_parser *parser)
					macro_start, macro_len);
			parser->state = parser->prev_state;

-
			if (macro_escaped == NULL) {
+
			if (macro_escaped == NULL && macro != NULL) {
				if (macro->is_context) {
					ret = macro->h.context_handler (macro_start, macro_len,
							macro_args,
@@ -2359,7 +2375,7 @@ ucl_state_machine (struct ucl_parser *parser)
							macro->ud);
				}
			}
-
			else {
+
			else if (macro != NULL) {
				if (macro->is_context) {
					ret = macro->h.context_handler (macro_escaped, macro_len,
							macro_args,
@@ -2373,15 +2389,22 @@ ucl_state_machine (struct ucl_parser *parser)

				UCL_FREE (macro_len + 1, macro_escaped);
			}
+
			else {
+
				ret = false;
+
				ucl_set_err (parser, UCL_EINTERNAL,
+
						"internal error: parser has macro undefined", &parser->err);
+
			}

			/*
			 * Chunk can be modified within macro handler
			 */
			chunk = parser->chunks;
			p = chunk->pos;
+

			if (macro_args) {
				ucl_object_unref (macro_args);
			}
+

			if (!ret) {
				return false;
			}
@@ -2574,14 +2597,16 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data,
		return false;
	}

-
	if (data == NULL) {
-
		ucl_create_err (&parser->err, "invalid chunk added");
-
		return false;
-
	}
	if (len == 0) {
		parser->top_obj = ucl_object_new_full (UCL_OBJECT, priority);
		return true;
	}
+

+
	if (data == NULL) {
+
		ucl_create_err (&parser->err, "invalid chunk added");
+
		return false;
+
	}
+

	if (parser->state != UCL_STATE_ERROR) {
		chunk = UCL_ALLOC (sizeof (struct ucl_chunk));
		if (chunk == NULL) {
modified external/libucl/src/ucl_schema.c
@@ -78,7 +78,7 @@ ucl_schema_test_pattern (const ucl_object_t *obj, const char *pattern)
	ucl_object_iter_t iter = NULL;

	if (regcomp (&reg, pattern, REG_EXTENDED | REG_NOSUB) == 0) {
-
		while ((elt = ucl_iterate_object (obj, &iter, true)) != NULL) {
+
		while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) {
			if (regexec (&reg, ucl_object_key (elt), 0, NULL, 0) == 0) {
				res = elt;
				break;
@@ -103,14 +103,14 @@ ucl_schema_validate_dependencies (const ucl_object_t *deps,
	ucl_object_iter_t iter = NULL, piter;
	bool ret = true;

-
	while (ret && (cur = ucl_iterate_object (deps, &iter, true)) != NULL) {
-
		elt = ucl_object_find_key (obj, ucl_object_key (cur));
+
	while (ret && (cur = ucl_object_iterate (deps, &iter, true)) != NULL) {
+
		elt = ucl_object_lookup (obj, ucl_object_key (cur));
		if (elt != NULL) {
			/* Need to check dependencies */
			if (cur->type == UCL_ARRAY) {
				piter = NULL;
-
				while (ret && (cur_dep = ucl_iterate_object (cur, &piter, true)) != NULL) {
-
					if (ucl_object_find_key (obj, ucl_object_tostring (cur_dep)) == NULL) {
+
				while (ret && (cur_dep = ucl_object_iterate (cur, &piter, true)) != NULL) {
+
					if (ucl_object_lookup (obj, ucl_object_tostring (cur_dep)) == NULL) {
						ucl_schema_create_error (err, UCL_SCHEMA_MISSING_DEPENDENCY, elt,
								"dependency %s is missing for key %s",
								ucl_object_tostring (cur_dep), ucl_object_key (cur));
@@ -143,12 +143,12 @@ ucl_schema_validate_object (const ucl_object_t *schema,
	bool ret = true, allow_additional = true;
	int64_t minmax;

-
	while (ret && (elt = ucl_iterate_object (schema, &iter, true)) != NULL) {
+
	while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) {
		if (elt->type == UCL_OBJECT &&
				strcmp (ucl_object_key (elt), "properties") == 0) {
			piter = NULL;
-
			while (ret && (prop = ucl_iterate_object (elt, &piter, true)) != NULL) {
-
				found = ucl_object_find_key (obj, ucl_object_key (prop));
+
			while (ret && (prop = ucl_object_iterate (elt, &piter, true)) != NULL) {
+
				found = ucl_object_lookup (obj, ucl_object_key (prop));
				if (found) {
					ret = ucl_schema_validate (prop, found, true, err, root,
							ext_ref);
@@ -206,7 +206,7 @@ ucl_schema_validate_object (const ucl_object_t *schema,
		}
		else if (strcmp (ucl_object_key (elt), "patternProperties") == 0) {
			piter = NULL;
-
			while (ret && (prop = ucl_iterate_object (elt, &piter, true)) != NULL) {
+
			while (ret && (prop = ucl_object_iterate (elt, &piter, true)) != NULL) {
				found = ucl_schema_test_pattern (obj, ucl_object_key (prop));
				if (found) {
					ret = ucl_schema_validate (prop, found, true, err, root,
@@ -226,14 +226,14 @@ ucl_schema_validate_object (const ucl_object_t *schema,
		if (!allow_additional || additional_schema != NULL) {
			/* Check if we have exactly the same properties in schema and object */
			iter = NULL;
-
			prop = ucl_object_find_key (schema, "properties");
-
			while ((elt = ucl_iterate_object (obj, &iter, true)) != NULL) {
-
				found = ucl_object_find_key (prop, ucl_object_key (elt));
+
			prop = ucl_object_lookup (schema, "properties");
+
			while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) {
+
				found = ucl_object_lookup (prop, ucl_object_key (elt));
				if (found == NULL) {
					/* Try patternProperties */
					piter = NULL;
-
					pat = ucl_object_find_key (schema, "patternProperties");
-
					while ((pelt = ucl_iterate_object (pat, &piter, true)) != NULL) {
+
					pat = ucl_object_lookup (schema, "patternProperties");
+
					while ((pelt = ucl_object_iterate (pat, &piter, true)) != NULL) {
						found = ucl_schema_test_pattern (obj, ucl_object_key (pelt));
						if (found != NULL) {
							break;
@@ -261,8 +261,8 @@ ucl_schema_validate_object (const ucl_object_t *schema,
		/* Required properties */
		if (required != NULL) {
			iter = NULL;
-
			while ((elt = ucl_iterate_object (required, &iter, true)) != NULL) {
-
				if (ucl_object_find_key (obj, ucl_object_tostring (elt)) == NULL) {
+
			while ((elt = ucl_object_iterate (required, &iter, true)) != NULL) {
+
				if (ucl_object_lookup (obj, ucl_object_tostring (elt)) == NULL) {
					ucl_schema_create_error (err, UCL_SCHEMA_MISSING_PROPERTY, obj,
							"object has missing property %s",
							ucl_object_tostring (elt));
@@ -287,7 +287,7 @@ ucl_schema_validate_number (const ucl_object_t *schema,
	double constraint, val;
	const double alpha = 1e-16;

-
	while (ret && (elt = ucl_iterate_object (schema, &iter, true)) != NULL) {
+
	while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) {
		if ((elt->type == UCL_FLOAT || elt->type == UCL_INT) &&
				strcmp (ucl_object_key (elt), "multipleOf") == 0) {
			constraint = ucl_object_todouble (elt);
@@ -309,7 +309,7 @@ ucl_schema_validate_number (const ucl_object_t *schema,
		else if ((elt->type == UCL_FLOAT || elt->type == UCL_INT) &&
			strcmp (ucl_object_key (elt), "maximum") == 0) {
			constraint = ucl_object_todouble (elt);
-
			test = ucl_object_find_key (schema, "exclusiveMaximum");
+
			test = ucl_object_lookup (schema, "exclusiveMaximum");
			if (test && test->type == UCL_BOOLEAN) {
				exclusive = ucl_object_toboolean (test);
			}
@@ -325,7 +325,7 @@ ucl_schema_validate_number (const ucl_object_t *schema,
		else if ((elt->type == UCL_FLOAT || elt->type == UCL_INT) &&
				strcmp (ucl_object_key (elt), "minimum") == 0) {
			constraint = ucl_object_todouble (elt);
-
			test = ucl_object_find_key (schema, "exclusiveMinimum");
+
			test = ucl_object_lookup (schema, "exclusiveMinimum");
			if (test && test->type == UCL_BOOLEAN) {
				exclusive = ucl_object_toboolean (test);
			}
@@ -355,7 +355,7 @@ ucl_schema_validate_string (const ucl_object_t *schema,
	regex_t re;
#endif

-
	while (ret && (elt = ucl_iterate_object (schema, &iter, true)) != NULL) {
+
	while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) {
		if (elt->type == UCL_INT &&
			strcmp (ucl_object_key (elt), "maxLength") == 0) {
			constraint = ucl_object_toint (elt);
@@ -429,7 +429,7 @@ ucl_schema_array_is_unique (const ucl_object_t *obj, struct ucl_schema_error *er
	struct ucl_compare_node *node, test, *nodes = NULL, *tmp;
	bool ret = true;

-
	while ((elt = ucl_iterate_object (obj, &iter, true)) != NULL) {
+
	while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) {
		test.obj = elt;
		node = TREE_FIND (&tree, ucl_compare_node, link, &test);
		if (node != NULL) {
@@ -470,11 +470,11 @@ ucl_schema_validate_array (const ucl_object_t *schema,
	int64_t minmax;
	unsigned int idx = 0;

-
	while (ret && (elt = ucl_iterate_object (schema, &iter, true)) != NULL) {
+
	while (ret && (elt = ucl_object_iterate (schema, &iter, true)) != NULL) {
		if (strcmp (ucl_object_key (elt), "items") == 0) {
			if (elt->type == UCL_ARRAY) {
				found = ucl_array_head (obj);
-
				while (ret && (it = ucl_iterate_object (elt, &piter, true)) != NULL) {
+
				while (ret && (it = ucl_object_iterate (elt, &piter, true)) != NULL) {
					if (found) {
						ret = ucl_schema_validate (it, found, false, err,
								root, ext_ref);
@@ -488,7 +488,7 @@ ucl_schema_validate_array (const ucl_object_t *schema,
			}
			else if (elt->type == UCL_OBJECT) {
				/* Validate all items using the specified schema */
-
				while (ret && (it = ucl_iterate_object (obj, &piter, true)) != NULL) {
+
				while (ret && (it = ucl_object_iterate (obj, &piter, true)) != NULL) {
					ret = ucl_schema_validate (elt, it, false, err, root,
							ext_ref);
				}
@@ -594,7 +594,7 @@ ucl_schema_type_is_allowed (const ucl_object_t *type, const ucl_object_t *obj,

	if (type->type == UCL_ARRAY) {
		/* One of allowed types */
-
		while ((elt = ucl_iterate_object (type, &iter, true)) != NULL) {
+
		while ((elt = ucl_object_iterate (type, &iter, true)) != NULL) {
			if (ucl_schema_type_is_allowed (elt, obj, err)) {
				return true;
			}
@@ -642,7 +642,7 @@ ucl_schema_validate_enum (const ucl_object_t *en, const ucl_object_t *obj,
	const ucl_object_t *elt;
	bool ret = false;

-
	while ((elt = ucl_iterate_object (en, &iter, true)) != NULL) {
+
	while ((elt = ucl_object_iterate (en, &iter, true)) != NULL) {
		if (ucl_object_compare (elt, obj) == 0) {
			ret = true;
			break;
@@ -672,7 +672,7 @@ ucl_schema_resolve_ref_component (const ucl_object_t *cur,

	if (cur->type == UCL_OBJECT) {
		/* Find a key inside an object */
-
		res = ucl_object_find_keyl (cur, refc, len);
+
		res = ucl_object_lookup_len (cur, refc, len);
		if (res == NULL) {
			ucl_schema_create_error (err, UCL_SCHEMA_INVALID_SCHEMA, cur,
					"reference %s is invalid, missing path component", refc);
@@ -748,7 +748,7 @@ ucl_schema_resolve_ref (const ucl_object_t *root, const char *ref,
			p = ref;
		}

-
		ext_obj = ucl_object_find_key (ext_ref, p);
+
		ext_obj = ucl_object_lookup (ext_ref, p);

		if (ext_obj == NULL) {
			if (ucl_strnstr (p, "://", strlen (p)) != NULL) {
@@ -863,7 +863,7 @@ ucl_schema_validate_values (const ucl_object_t *schema, const ucl_object_t *obj,
	const ucl_object_t *elt, *cur;
	int64_t constraint, i;

-
	elt = ucl_object_find_key (schema, "maxValues");
+
	elt = ucl_object_lookup (schema, "maxValues");
	if (elt != NULL && elt->type == UCL_INT) {
		constraint = ucl_object_toint (elt);
		cur = obj;
@@ -879,7 +879,7 @@ ucl_schema_validate_values (const ucl_object_t *schema, const ucl_object_t *obj,
			cur = cur->next;
		}
	}
-
	elt = ucl_object_find_key (schema, "minValues");
+
	elt = ucl_object_lookup (schema, "minValues");
	if (elt != NULL && elt->type == UCL_INT) {
		constraint = ucl_object_toint (elt);
		cur = obj;
@@ -935,17 +935,17 @@ ucl_schema_validate (const ucl_object_t *schema,
		return true;
	}

-
	elt = ucl_object_find_key (schema, "enum");
+
	elt = ucl_object_lookup (schema, "enum");
	if (elt != NULL && elt->type == UCL_ARRAY) {
		if (!ucl_schema_validate_enum (elt, obj, err)) {
			return false;
		}
	}

-
	elt = ucl_object_find_key (schema, "allOf");
+
	elt = ucl_object_lookup (schema, "allOf");
	if (elt != NULL && elt->type == UCL_ARRAY) {
		iter = NULL;
-
		while ((cur = ucl_iterate_object (elt, &iter, true)) != NULL) {
+
		while ((cur = ucl_object_iterate (elt, &iter, true)) != NULL) {
			ret = ucl_schema_validate (cur, obj, true, err, root, external_refs);
			if (!ret) {
				return false;
@@ -953,10 +953,10 @@ ucl_schema_validate (const ucl_object_t *schema,
		}
	}

-
	elt = ucl_object_find_key (schema, "anyOf");
+
	elt = ucl_object_lookup (schema, "anyOf");
	if (elt != NULL && elt->type == UCL_ARRAY) {
		iter = NULL;
-
		while ((cur = ucl_iterate_object (elt, &iter, true)) != NULL) {
+
		while ((cur = ucl_object_iterate (elt, &iter, true)) != NULL) {
			ret = ucl_schema_validate (cur, obj, true, err, root, external_refs);
			if (ret) {
				break;
@@ -971,11 +971,11 @@ ucl_schema_validate (const ucl_object_t *schema,
		}
	}

-
	elt = ucl_object_find_key (schema, "oneOf");
+
	elt = ucl_object_lookup (schema, "oneOf");
	if (elt != NULL && elt->type == UCL_ARRAY) {
		iter = NULL;
		ret = false;
-
		while ((cur = ucl_iterate_object (elt, &iter, true)) != NULL) {
+
		while ((cur = ucl_object_iterate (elt, &iter, true)) != NULL) {
			if (!ret) {
				ret = ucl_schema_validate (cur, obj, true, err, root, external_refs);
			}
@@ -989,7 +989,7 @@ ucl_schema_validate (const ucl_object_t *schema,
		}
	}

-
	elt = ucl_object_find_key (schema, "not");
+
	elt = ucl_object_lookup (schema, "not");
	if (elt != NULL && elt->type == UCL_OBJECT) {
		if (ucl_schema_validate (elt, obj, true, err, root, external_refs)) {
			return false;
@@ -1000,7 +1000,7 @@ ucl_schema_validate (const ucl_object_t *schema,
		}
	}

-
	elt = ucl_object_find_key (schema, "$ref");
+
	elt = ucl_object_lookup (schema, "$ref");
	if (elt != NULL) {
		ref_root = root;
		cur = ucl_schema_resolve_ref (root, ucl_object_tostring (elt),
@@ -1015,7 +1015,7 @@ ucl_schema_validate (const ucl_object_t *schema,
		}
	}

-
	elt = ucl_object_find_key (schema, "type");
+
	elt = ucl_object_lookup (schema, "type");
	if (!ucl_schema_type_is_allowed (elt, obj, err)) {
		return false;
	}
modified external/libucl/src/ucl_util.c
@@ -27,7 +27,7 @@
#include "ucl_chartable.h"
#include "kvec.h"
#include <stdarg.h>
-
#include <stdio.h> /* for asprintf */
+
#include <stdio.h> /* for snprintf */

#ifndef _WIN32
#include <glob.h>
@@ -51,6 +51,8 @@ typedef kvec_t(ucl_object_t *) ucl_array_t;
#endif

#ifdef CURL_FOUND
+
/* Seems to be broken */
+
#define CURL_DISABLE_TYPECHECK 1
#include <curl/curl.h>
#endif
#ifdef HAVE_FETCH_H
@@ -771,6 +773,8 @@ ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *bufl
			close (fd);
			ucl_create_err (err, "cannot mmap file %s: %s",
					filename, strerror (errno));
+
			*buf = NULL;
+

			return false;
		}
		*buflen = st.st_size;
@@ -987,12 +991,12 @@ ucl_include_file_single (const unsigned char *data, size_t len,
			ucl_create_err (&parser->err, "cannot verify file %s: %s",
							filebuf,
							ERR_error_string (ERR_get_error (), NULL));
-
			if (siglen > 0) {
+
			if (sigbuf) {
				ucl_munmap (sigbuf, siglen);
			}
			return false;
		}
-
		if (siglen > 0) {
+
		if (sigbuf) {
			ucl_munmap (sigbuf, siglen);
		}
#endif
@@ -1059,7 +1063,7 @@ ucl_include_file_single (const unsigned char *data, size_t len,

			if (nest_obj == NULL) {
				ucl_create_err (&parser->err, "cannot allocate memory for an object");
-
				if (buflen > 0) {
+
				if (buf) {
					ucl_munmap (buf, buflen);
				}

@@ -1083,7 +1087,7 @@ ucl_include_file_single (const unsigned char *data, size_t len,
				nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
				if (nest_obj == NULL) {
					ucl_create_err (&parser->err, "cannot allocate memory for an object");
-
					if (buflen > 0) {
+
					if (buf) {
						ucl_munmap (buf, buflen);
					}

@@ -1099,7 +1103,7 @@ ucl_include_file_single (const unsigned char *data, size_t len,
				new_obj = ucl_object_typed_new (UCL_ARRAY);
				if (new_obj == NULL) {
					ucl_create_err (&parser->err, "cannot allocate memory for an object");
-
					if (buflen > 0) {
+
					if (buf) {
						ucl_munmap (buf, buflen);
					}

@@ -1114,7 +1118,7 @@ ucl_include_file_single (const unsigned char *data, size_t len,
				nest_obj = ucl_object_new_full (UCL_OBJECT, params->priority);
				if (nest_obj == NULL) {
					ucl_create_err (&parser->err, "cannot allocate memory for an object");
-
					if (buflen > 0) {
+
					if (buf) {
						ucl_munmap (buf, buflen);
					}

@@ -1138,7 +1142,7 @@ ucl_include_file_single (const unsigned char *data, size_t len,
				ucl_create_err (&parser->err,
						"Conflicting type for key: %s",
						params->prefix);
-
				if (buflen > 0) {
+
				if (buf) {
					ucl_munmap (buf, buflen);
				}

@@ -1149,22 +1153,21 @@ ucl_include_file_single (const unsigned char *data, size_t len,
		 /* Put all of the content of the include inside that object */
		parser->stack->obj->value.ov = container;

-
		if (nest_obj != NULL) {
-
			st = UCL_ALLOC (sizeof (struct ucl_stack));
-
			if (st == NULL) {
-
				ucl_create_err (&parser->err, "cannot allocate memory for an object");
-
				ucl_object_unref (nest_obj);
-
				if (buflen > 0) {
-
					ucl_munmap (buf, buflen);
-
				}
+
		st = UCL_ALLOC (sizeof (struct ucl_stack));
+
		if (st == NULL) {
+
			ucl_create_err (&parser->err, "cannot allocate memory for an object");
+
			ucl_object_unref (nest_obj);

-
				return false;
+
			if (buf) {
+
				ucl_munmap (buf, buflen);
			}
-
			st->obj = nest_obj;
-
			st->level = parser->stack->level;
-
			LL_PREPEND (parser->stack, st);
-
			parser->cur_obj = nest_obj;
+

+
			return false;
		}
+
		st->obj = nest_obj;
+
		st->level = parser->stack->level;
+
		LL_PREPEND (parser->stack, st);
+
		parser->cur_obj = nest_obj;
	}

	res = ucl_parser_add_chunk_full (parser, buf, buflen, params->priority,
@@ -1334,7 +1337,7 @@ ucl_include_common (const unsigned char *data, size_t len,

	/* Process arguments */
	if (args != NULL && args->type == UCL_OBJECT) {
-
		while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
+
		while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
			if (param->type == UCL_BOOLEAN) {
				if (strncmp (param->key, "try", param->keylen) == 0) {
					params.must_exist = !ucl_object_toboolean (param);
@@ -1509,7 +1512,7 @@ ucl_priority_handler (const unsigned char *data, size_t len,

	/* Process arguments */
	if (args != NULL && args->type == UCL_OBJECT) {
-
		while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
+
		while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
			if (param->type == UCL_INT) {
				if (strncmp (param->key, "priority", param->keylen) == 0) {
					priority = ucl_object_toint (param);
@@ -1588,7 +1591,7 @@ ucl_load_handler (const unsigned char *data, size_t len,

	/* Process arguments */
	if (args != NULL && args->type == UCL_OBJECT) {
-
		while ((param = ucl_iterate_object (args, &it, true)) != NULL) {
+
		while ((param = ucl_object_iterate (args, &it, true)) != NULL) {
			if (param->type == UCL_BOOLEAN) {
				if (strncmp (param->key, "try", param->keylen) == 0) {
					try_load = ucl_object_toboolean (param);
@@ -1631,14 +1634,15 @@ ucl_load_handler (const unsigned char *data, size_t len,
	}

	if (len > 0) {
-
		asprintf (&load_file, "%.*s", (int)len, data);
-

+
		load_file = malloc (len + 1);
		if (!load_file) {
			ucl_create_err (&parser->err, "cannot allocate memory for suffix");

			return false;
		}

+
		snprintf (load_file, len + 1, "%.*s", (int)len, data);
+

		if (!ucl_fetch_file (load_file, &buf, &buflen, &parser->err,
				!try_load)) {
			free (load_file);
@@ -1648,12 +1652,12 @@ ucl_load_handler (const unsigned char *data, size_t len,

		free (load_file);
		container = parser->stack->obj;
-
		old_obj = __DECONST (ucl_object_t *, ucl_object_find_key (container,
+
		old_obj = __DECONST (ucl_object_t *, ucl_object_lookup (container,
				prefix));

		if (old_obj != NULL) {
			ucl_create_err (&parser->err, "Key %s already exists", prefix);
-
			if (buflen > 0) {
+
			if (buf) {
				ucl_munmap (buf, buflen);
			}

@@ -1668,12 +1672,24 @@ ucl_load_handler (const unsigned char *data, size_t len,
			}
		}
		else if (strcasecmp (target, "int") == 0) {
-
			asprintf(&tmp, "%.*s", (int)buflen, buf);
-
			iv = strtoll(tmp, NULL, 10);
+
			tmp = malloc (buflen + 1);
+

+
			if (tmp == NULL) {
+
				ucl_create_err (&parser->err, "Memory allocation failed");
+
				if (buf) {
+
					ucl_munmap (buf, buflen);
+
				}
+

+
				return false;
+
			}
+

+
			snprintf (tmp, buflen + 1, "%.*s", (int)buflen, buf);
+
			iv = strtoll (tmp, NULL, 10);
			obj = ucl_object_fromint (iv);
+
			free (tmp);
		}

-
		if (buflen > 0) {
+
		if (buf) {
			ucl_munmap (buf, buflen);
		}

@@ -1704,7 +1720,7 @@ ucl_inherit_handler (const unsigned char *data, size_t len,
	bool replace = false;
	struct ucl_parser *parser = ud;

-
	parent = ucl_object_find_keyl (ctx, data, len);
+
	parent = ucl_object_lookup_len (ctx, data, len);

	/* Some sanity checks */
	if (parent == NULL || ucl_object_type (parent) != UCL_OBJECT) {
@@ -1721,13 +1737,13 @@ ucl_inherit_handler (const unsigned char *data, size_t len,

	target = parser->stack->obj;

-
	if (args && (cur = ucl_object_find_key (args, "replace")) != NULL) {
+
	if (args && (cur = ucl_object_lookup (args, "replace")) != NULL) {
		replace = ucl_object_toboolean (cur);
	}

-
	while ((cur = ucl_iterate_object (parent, &it, true))) {
+
	while ((cur = ucl_object_iterate (parent, &it, true))) {
		/* We do not replace existing keys */
-
		if (!replace && ucl_object_find_keyl (target, cur->key, cur->keylen)) {
+
		if (!replace && ucl_object_lookup_len (target, cur->key, cur->keylen)) {
			continue;
		}

@@ -2172,7 +2188,7 @@ ucl_object_insert_key_common (ucl_object_t *top, ucl_object_t *elt,
			}
			else if (found->type == UCL_OBJECT && elt->type == UCL_OBJECT) {
				/* Mix two hashes */
-
				while ((cur = ucl_iterate_object (elt, &it, true)) != NULL) {
+
				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);
@@ -2201,7 +2217,7 @@ ucl_object_delete_keyl (ucl_object_t *top, const char *key, size_t keylen)
		return false;
	}

-
	found = __DECONST (ucl_object_t *, ucl_object_find_keyl (top, key, keylen));
+
	found = __DECONST (ucl_object_t *, ucl_object_lookup_len (top, key, keylen));

	if (found == NULL) {
		return false;
@@ -2228,7 +2244,7 @@ ucl_object_pop_keyl (ucl_object_t *top, const char *key, size_t keylen)
	if (top == NULL || key == NULL) {
		return false;
	}
-
	found = ucl_object_find_keyl (top, key, keylen);
+
	found = ucl_object_lookup_len (top, key, keylen);

	if (found == NULL) {
		return NULL;
@@ -2301,7 +2317,7 @@ ucl_object_merge (ucl_object_t *top, ucl_object_t *elt, bool copy)
}

const ucl_object_t *
-
ucl_object_find_keyl (const ucl_object_t *obj, const char *key, size_t klen)
+
ucl_object_lookup_len (const ucl_object_t *obj, const char *key, size_t klen)
{
	const ucl_object_t *ret;
	ucl_object_t srch;
@@ -2318,17 +2334,17 @@ ucl_object_find_keyl (const ucl_object_t *obj, const char *key, size_t klen)
}

const ucl_object_t *
-
ucl_object_find_key (const ucl_object_t *obj, const char *key)
+
ucl_object_lookup (const ucl_object_t *obj, const char *key)
{
	if (key == NULL) {
		return NULL;
	}

-
	return ucl_object_find_keyl (obj, key, strlen (key));
+
	return ucl_object_lookup_len (obj, key, strlen (key));
}

const ucl_object_t*
-
ucl_object_find_any_key (const ucl_object_t *obj,
+
ucl_object_lookup_any (const ucl_object_t *obj,
		const char *key, ...)
{
	va_list ap;
@@ -2339,7 +2355,7 @@ ucl_object_find_any_key (const ucl_object_t *obj,
		return NULL;
	}

-
	ret = ucl_object_find_keyl (obj, key, strlen (key));
+
	ret = ucl_object_lookup_len (obj, key, strlen (key));

	if (ret == NULL) {
		va_start (ap, key);
@@ -2351,7 +2367,7 @@ ucl_object_find_any_key (const ucl_object_t *obj,
				break;
			}
			else {
-
				ret = ucl_object_find_keyl (obj, nk, strlen (nk));
+
				ret = ucl_object_lookup_len (obj, nk, strlen (nk));
			}
		}

@@ -2362,7 +2378,7 @@ ucl_object_find_any_key (const ucl_object_t *obj,
}

const ucl_object_t*
-
ucl_iterate_object (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values)
+
ucl_object_iterate (const ucl_object_t *obj, ucl_object_iter_t *iter, bool expand_values)
{
	const ucl_object_t *elt = NULL;

@@ -2469,7 +2485,7 @@ ucl_object_iterate_safe (ucl_object_iter_t it, bool expand_values)
	}

	if (rit->impl_it->type == UCL_OBJECT || rit->impl_it->type == UCL_ARRAY) {
-
		ret = ucl_iterate_object (rit->impl_it, &rit->expl_it, true);
+
		ret = ucl_object_iterate (rit->impl_it, &rit->expl_it, true);

		if (ret == NULL) {
			/* Need to switch to another implicit object in chain */
@@ -2504,13 +2520,13 @@ ucl_object_iterate_free (ucl_object_iter_t it)
}

const ucl_object_t *
-
ucl_lookup_path (const ucl_object_t *top, const char *path_in) {
-
	return ucl_lookup_path_char (top, path_in, '.');
+
ucl_object_lookup_path (const ucl_object_t *top, const char *path_in) {
+
	return ucl_object_lookup_path_char (top, path_in, '.');
}


const ucl_object_t *
-
ucl_lookup_path_char (const ucl_object_t *top, const char *path_in, const char sep) {
+
ucl_object_lookup_path_char (const ucl_object_t *top, const char *path_in, const char sep) {
	const ucl_object_t *o = NULL, *found;
	const char *p, *c;
	char *err_str;
@@ -2543,7 +2559,7 @@ ucl_lookup_path_char (const ucl_object_t *top, const char *path_in, const char s
					o = ucl_array_find_index (top, index);
					break;
				default:
-
					o = ucl_object_find_keyl (top, c, p - c);
+
					o = ucl_object_lookup_len (top, c, p - c);
					break;
				}
				if (o == NULL) {
@@ -2769,14 +2785,16 @@ ucl_array_merge (ucl_object_t *top, ucl_object_t *elt, bool copy)
	UCL_ARRAY_GET (v1, top);
	UCL_ARRAY_GET (v2, cp);

-
	kv_concat (ucl_object_t *, *v1, *v2);
+
	if (v1 && v2) {
+
		kv_concat (ucl_object_t *, *v1, *v2);

-
	for (i = v2->n; i < v1->n; i ++) {
-
		obj = &kv_A (*v1, i);
-
		if (*obj == NULL) {
-
			continue;
+
		for (i = v2->n; i < v1->n; i ++) {
+
			obj = &kv_A (*v1, i);
+
			if (*obj == NULL) {
+
				continue;
+
			}
+
			top->len ++;
		}
-
		top->len ++;
	}

	return true;
@@ -3165,7 +3183,7 @@ ucl_object_copy_internal (const ucl_object_t *other, bool allow_array)
			/* reset old value */
			memset (&new->value, 0, sizeof (new->value));

-
			while ((cur = ucl_iterate_object (other, &it, true)) != NULL) {
+
			while ((cur = ucl_object_iterate (other, &it, true)) != NULL) {
				if (other->type == UCL_ARRAY) {
					ucl_array_append (new, ucl_object_copy_internal (cur, false));
				}
@@ -3271,8 +3289,8 @@ ucl_object_compare (const ucl_object_t *o1, const ucl_object_t *o2)
		break;
	case UCL_OBJECT:
		if (o1->len == o2->len && o1->len > 0) {
-
			while ((it1 = ucl_iterate_object (o1, &iter, true)) != NULL) {
-
				it2 = ucl_object_find_key (o2, ucl_object_key (it1));
+
			while ((it1 = ucl_object_iterate (o1, &iter, true)) != NULL) {
+
				it2 = ucl_object_lookup (o2, ucl_object_key (it1));
				if (it2 == NULL) {
					ret = 1;
					break;
@@ -3426,9 +3444,45 @@ ucl_comments_find (const ucl_object_t *comments,
		const ucl_object_t *srch)
{
	if (comments && srch) {
-
		return ucl_object_find_keyl (comments, (const char *)&srch,
+
		return ucl_object_lookup_len (comments, (const char *)&srch,
				sizeof (void *));
	}

	return NULL;
}
+

+
bool
+
ucl_comments_move (ucl_object_t *comments,
+
		const ucl_object_t *from, const ucl_object_t *to)
+
{
+
	const ucl_object_t *found;
+
	ucl_object_t *obj;
+

+
	if (comments && from && to) {
+
		found = ucl_object_lookup_len (comments,
+
				(const char *)&from, sizeof (void *));
+

+
		if (found) {
+
			/* Replace key */
+
			obj = ucl_object_ref (found);
+
			ucl_object_delete_keyl (comments, (const char *)&from,
+
					sizeof (void *));
+
			ucl_object_insert_key (comments, obj, (const char *)&to,
+
					sizeof (void *), true);
+

+
			return true;
+
		}
+
	}
+

+
	return false;
+
}
+

+
void
+
ucl_comments_add (ucl_object_t *comments, const ucl_object_t *obj,
+
		const char *comment)
+
{
+
	if (comments && obj && comment) {
+
		ucl_object_insert_key (comments, ucl_object_fromstring (comment),
+
				(const char *)&obj, sizeof (void *), true);
+
	}
+
}
modified external/libucl/tests/basic/2.res
@@ -29,7 +29,7 @@ key4 = 5000000;
key4 = "s1";
key5 = 0.010000;
key5 = "\n\r123";
-
key6 = 2207520000.000000;
+
key6 = 315360000.0;
keyvar = "unknowntest";
keyvar = "unknownunknownunknown${unknown}";
keyvar = "${some}$no${}$$test$$$$$$$";
modified external/libucl/tests/generate.res
@@ -29,6 +29,7 @@ key14 [
    "абв",
]
key15 = "test userdata emit";
+
# test comment
key16 = "tes";
key17 [
    "test",
modified external/libucl/tests/test_generate.c
@@ -41,9 +41,10 @@ ud_emit (void *ptr)
int
main (int argc, char **argv)
{
-
	ucl_object_t *obj, *cur, *ar, *ar1, *ref, *test_obj;
+
	ucl_object_t *obj, *cur, *ar, *ar1, *ref, *test_obj, *comments;
	ucl_object_iter_t it;
	const ucl_object_t *found, *it_obj, *test;
+
	struct ucl_emitter_functions *fn;
	FILE *out;
	unsigned char *emitted;
	const char *fname_out = NULL;
@@ -167,15 +168,15 @@ main (int argc, char **argv)
	/* More tests for keys */
	cur = ucl_object_fromlstring ("test", 3);
	ucl_object_insert_key (obj, cur, "key16", 0, false);
-
	test = ucl_object_find_any_key (obj, "key100", "key200", "key300", "key16", NULL);
+
	test = ucl_object_lookup_any (obj, "key100", "key200", "key300", "key16", NULL);
	assert (test == cur);
-
	test = ucl_object_find_keyl (obj, "key160", 5);
+
	test = ucl_object_lookup_len (obj, "key160", 5);
	assert (test == cur);
	cur = ucl_object_pop_key (obj, "key16");
	assert (test == cur);
	test = ucl_object_pop_key (obj, "key16");
	assert (test == NULL);
-
	test = ucl_object_find_keyl (obj, "key160", 5);
+
	test = ucl_object_lookup_len (obj, "key160", 5);
	assert (test == NULL);
	/* Objects merging tests */
	test_obj = ucl_object_new_full (UCL_OBJECT, 2);
@@ -192,6 +193,24 @@ main (int argc, char **argv)
	ucl_object_insert_key (obj, cur, "key18", 0, true);
	assert (ucl_object_delete_key (obj, "key18"));
	assert (!ucl_object_delete_key (obj, "key18"));
+
	cur = ucl_object_fromlstring ("test", 4);
+
	ucl_object_insert_key (obj, cur, "key18\0\0", 7, true);
+
	assert (ucl_object_lookup_len (obj, "key18\0\0", 7) == cur);
+
	assert (ucl_object_lookup (obj, "key18") == NULL);
+
	assert (ucl_object_lookup_len (obj, "key18\0\1", 7) == NULL);
+
	assert (ucl_object_delete_keyl (obj, "key18\0\0", 7));
+

+
	/* Comments */
+

+
	comments = ucl_object_typed_new (UCL_OBJECT);
+
	found = ucl_object_lookup (obj, "key17");
+
	test = ucl_object_lookup (obj, "key16");
+
	ucl_comments_add (comments, found, "# test comment");
+
	assert (ucl_comments_find (comments, found) != NULL);
+
	assert (ucl_comments_find (comments, test) == NULL);
+
	ucl_comments_move (comments, found, test);
+
	assert (ucl_comments_find (comments, found) == NULL);
+
	assert (ucl_comments_find (comments, test) != NULL);

	/* Array replace */
	ar1 = ucl_object_typed_new (UCL_ARRAY);
@@ -203,19 +222,19 @@ main (int argc, char **argv)

	/* Try to find using path */
	/* Should exist */
-
	found = ucl_lookup_path (obj, "key4.1");
+
	found = ucl_object_lookup_path (obj, "key4.1");
	assert (found != NULL && ucl_object_toint (found) == 10);
	/* . should be ignored */
-
	found = ucl_lookup_path (obj, ".key4.1");
+
	found = ucl_object_lookup_path (obj, ".key4.1");
	assert (found != NULL && ucl_object_toint (found) == 10);
	/* moar dots... */
-
	found = ucl_lookup_path (obj, ".key4........1...");
+
	found = ucl_object_lookup_path (obj, ".key4........1...");
	assert (found != NULL && ucl_object_toint (found) == 10);
	/* No such index */
-
	found = ucl_lookup_path (obj, ".key4.3");
+
	found = ucl_object_lookup_path (obj, ".key4.3");
	assert (found == NULL);
	/* No such key */
-
	found = ucl_lookup_path (obj, "key9..key1");
+
	found = ucl_object_lookup_path (obj, "key9..key1");
	assert (found == NULL);

	/* Test iteration */
@@ -245,10 +264,12 @@ main (int argc, char **argv)
	assert (ucl_object_type (it_obj) == UCL_BOOLEAN);
	ucl_object_iterate_free (it);

-
	emitted = ucl_object_emit (obj, UCL_EMIT_CONFIG);
-

+
	fn = ucl_object_emit_memory_funcs (&emitted);
+
	assert (ucl_object_emit_full (obj, UCL_EMIT_CONFIG, fn, comments));
	fprintf (out, "%s\n", emitted);
+
	ucl_object_emit_funcs_free (fn);
	ucl_object_unref (obj);
+
	ucl_object_unref (comments);

	parser = ucl_parser_new (UCL_PARSER_NO_IMPLICIT_ARRAYS);

modified external/libucl/tests/test_schema.c
@@ -68,9 +68,9 @@ perform_test (const ucl_object_t *schema, const ucl_object_t *obj,
	const ucl_object_t *valid, *data, *description;
	bool match;

-
	data = ucl_object_find_key (obj, "data");
-
	description = ucl_object_find_key (obj, "description");
-
	valid = ucl_object_find_key (obj, "valid");
+
	data = ucl_object_lookup (obj, "data");
+
	description = ucl_object_lookup (obj, "description");
+
	valid = ucl_object_lookup (obj, "valid");

	if (data == NULL || description == NULL || valid == NULL) {
		fprintf (stdout, "Bad test case\n");
@@ -103,9 +103,9 @@ perform_tests (const ucl_object_t *obj)
		return EXIT_FAILURE;
	}

-
	schema = ucl_object_find_key (obj, "schema");
-
	tests = ucl_object_find_key (obj, "tests");
-
	description = ucl_object_find_key (obj, "description");
+
	schema = ucl_object_lookup (obj, "schema");
+
	tests = ucl_object_lookup (obj, "tests");
+
	description = ucl_object_lookup (obj, "description");

	if (schema == NULL || tests == NULL || description == NULL) {
		fprintf (stdout, "Bad test case\n");
@@ -114,7 +114,7 @@ perform_tests (const ucl_object_t *obj)

	memset (&err, 0, sizeof (err));

-
	while ((test = ucl_iterate_object (tests, &iter, true)) != NULL) {
+
	while ((test = ucl_object_iterate (tests, &iter, true)) != NULL) {
		if (!perform_test (schema, test, &err)) {
			fprintf (stdout, "Test suite '%s' failed\n",
							ucl_object_tostring (description));
@@ -151,7 +151,7 @@ main (int argc, char **argv)
	obj = ucl_parser_get_object (parser);
	ucl_parser_free (parser);

-
	while ((elt = ucl_iterate_object (obj, &iter, true)) != NULL) {
+
	while ((elt = ucl_object_iterate (obj, &iter, true)) != NULL) {
		ret = perform_tests (elt);
		if (ret != 0) {
			break;
modified external/libucl/utils/objdump.c
@@ -41,7 +41,7 @@ ucl_obj_dump (const ucl_object_t *obj, unsigned int shift)

	tmp = obj;

-
	while ((obj = ucl_iterate_object (tmp, &it, false))) {
+
	while ((obj = ucl_object_iterate (tmp, &it, false))) {
		printf ("%sucl object address: %p\n", pre + 4, obj);
		if (obj->key != NULL) {
			printf ("%skey: \"%s\"\n", pre, ucl_object_key (obj));
@@ -54,7 +54,7 @@ ucl_obj_dump (const ucl_object_t *obj, unsigned int shift)
			printf ("%stype: UCL_OBJECT\n", pre);
			printf ("%svalue: %p\n", pre, obj->value.ov);
			it_obj = NULL;
-
			while ((cur = ucl_iterate_object (obj, &it_obj, true))) {
+
			while ((cur = ucl_object_iterate (obj, &it_obj, true))) {
				ucl_obj_dump (cur, shift + 2);
			}
		}
@@ -62,7 +62,7 @@ ucl_obj_dump (const ucl_object_t *obj, unsigned int shift)
			printf ("%stype: UCL_ARRAY\n", pre);
			printf ("%svalue: %p\n", pre, obj->value.av);
			it_obj = NULL;
-
			while ((cur = ucl_iterate_object (obj, &it_obj, true))) {
+
			while ((cur = ucl_object_iterate (obj, &it_obj, true))) {
				ucl_obj_dump (cur, shift + 2);
			}
		}
@@ -161,7 +161,7 @@ main(int argc, char **argv)
	if (argc > 2) {
		for (k = 2; k < argc; k++) {
			printf ("search for \"%s\"... ", argv[k]);
-
			par = ucl_object_find_key (obj, argv[k]);
+
			par = ucl_object_lookup (obj, argv[k]);
			printf ("%sfound\n", (par == NULL )?"not ":"");
			ucl_obj_dump (par, 0);
		}