/*
* Search tree packed in array
*/
-static struct ucl_msgpack_parser {
+struct ucl_msgpack_parser {
uint8_t prefix; /* Prefix byte */
uint8_t prefixlen; /* Length of prefix in bits */
uint8_t fmt; /* The desired format */
}
else {
/* Length is not embedded */
+ remain --;
+
if (remain < obj_parser->len) {
ucl_create_err (&parser->err, "not enough data remain to "
"read object's length: %u remain, %u needed",
}
p ++;
- remain --;
switch (obj_parser->len) {
case 1:
len = FROM_BE64 (*(uint64_t *)p);
break;
default:
- assert (0);
- break;
+ ucl_create_err (&parser->err, "invalid length of the length field: %u",
+ (unsigned)obj_parser->len);
+
+ return false;
}
p += obj_parser->len;
*/
container = parser->stack;
- if (container == NULL) {
+ if (parser->stack == NULL) {
+ ucl_create_err (&parser->err,
+ "read assoc value when no container represented");
return false;
}
/* Insert value to the container and check if we have finished array */
- if (!ucl_msgpack_insert_object (parser, NULL, 0,
+ if (parser->cur_obj) {
+ if (!ucl_msgpack_insert_object(parser, NULL, 0,
parser->cur_obj)) {
- return false;
+ return false;
+ }
+ }
+ else {
+ /* We have parsed ext, ignore it */
}
if (ucl_msgpack_is_container_finished (container)) {
container = parser->stack;
if (container == NULL) {
+ ucl_create_err (&parser->err,
+ "read assoc value when no container represented");
return false;
}
assert (key != NULL && keylen > 0);
- if (!ucl_msgpack_insert_object (parser, key, keylen,
+ if (parser->cur_obj) {
+ if (!ucl_msgpack_insert_object(parser, key, keylen,
parser->cur_obj)) {
- return false;
+
+ return false;
+ }
}
key = NULL;
case start_assoc:
/* Empty container at the end */
if (len != 0) {
- ucl_create_err (&parser->err, "invalid non-empty container at the end");
+ ucl_create_err (&parser->err,
+ "invalid non-empty container at the end; len=%zu",
+ (uintmax_t)len);
return false;
}
parser->cur_obj = ucl_object_new_full (
state == start_array ? UCL_ARRAY : UCL_OBJECT,
parser->chunks->priority);
+
+ if (parser->stack == NULL) {
+ ucl_create_err (&parser->err,
+ "read assoc value when no container represented");
+ return false;
+ }
/* Insert to the previous level container */
if (!ucl_msgpack_insert_object (parser,
key, keylen, parser->cur_obj)) {
container = parser->stack;
- if (container == NULL) {
+ if (parser->stack == NULL) {
+ ucl_create_err (&parser->err,
+ "read assoc value when no container represented");
return false;
}
/* Insert value to the container and check if we have finished array */
- if (!ucl_msgpack_insert_object (parser, NULL, 0,
+ if (parser->cur_obj) {
+ if (!ucl_msgpack_insert_object(parser, NULL, 0,
parser->cur_obj)) {
- return false;
+ return false;
+ }
}
break;
case finish_array_value:
/* Rewind to the top level container */
ucl_msgpack_get_next_container (parser);
- assert (parser->stack == NULL);
+
+ if (parser->stack != NULL) {
+ ucl_create_err (&parser->err, "incomplete container");
+
+ return false;
+ }
return true;
}
return -1;
}
+ parser->cur_obj = NULL;
+
return len;
}
#include <fetch.h>
#endif
-#if defined(_MSC_VER)
+#if defined(_WIN32)
#include <windows.h>
#include <io.h>
#include <direct.h>
*buf = cbdata.buf;
*buflen = cbdata.buflen;
+ curl_easy_cleanup (curl);
+
return true;
#else
ucl_create_err (err, "URL support is disabled");
snprintf (urlbuf, sizeof (urlbuf), "%.*s", (int)len, data);
if (!ucl_fetch_url (urlbuf, &buf, &buflen, &parser->err, params->must_exist)) {
+ if (!params->must_exist) {
+ ucl_parser_clear_error (parser);
+ }
return !params->must_exist;
}
ucl_hash_t *container = NULL;
struct ucl_stack *st = NULL;
+ if (parser->state == UCL_STATE_ERROR) {
+ /* Return immediately if we are in the error state... */
+ return false;
+ }
+
snprintf (filebuf, sizeof (filebuf), "%.*s", (int)len, data);
if (ucl_realpath (filebuf, realbuf) == NULL) {
if (params->soft_fail) {
return false;
}
+ ucl_parser_clear_error (parser);
+
return true;
}
!try_load)) {
free (load_file);
+ if (try_load) {
+ ucl_parser_clear_error (parser);
+ }
+
return (try_load || false);
}
ucl_object_t*
ucl_object_fromstring (const char *str)
{
- return ucl_object_fromstring_common (str, 0, UCL_STRING_ESCAPE);
+ return ucl_object_fromstring_common (str, 0, UCL_STRING_RAW);
}
ucl_object_t *
ucl_object_fromlstring (const char *str, size_t len)
{
- return ucl_object_fromstring_common (str, len, UCL_STRING_ESCAPE);
+ return ucl_object_fromstring_common (str, len, UCL_STRING_RAW);
}
ucl_object_t *
head = elt;
}
else {
- elt->prev = head->prev;
- head->prev->next = elt;
- head->prev = elt;
- elt->next = NULL;
+ if (head->type == UCL_USERDATA) {
+ /* Userdata objects are VERY special! */
+ struct ucl_object_userdata *ud = (struct ucl_object_userdata *)head;
+ elt->prev = ud->obj.prev;
+ ud->obj.prev->next = elt;
+ ud->obj.prev = elt;
+ elt->next = NULL;
+ }
+ else {
+ elt->prev = head->prev;
+ head->prev->next = elt;
+ head->prev = elt;
+ elt->next = NULL;
+ }
}
return head;
ucl_object_t *new;
ucl_object_iter_t it = NULL;
const ucl_object_t *cur;
+ size_t sz = sizeof(*new);
- new = malloc (sizeof (*new));
+ if (other->type == UCL_USERDATA) {
+ sz = sizeof (struct ucl_object_userdata);
+ }
+ new = malloc (sz);
if (new != NULL) {
- memcpy (new, other, sizeof (*new));
+ memcpy (new, other, sz);
if (other->flags & UCL_OBJECT_EPHEMERAL) {
/* Copied object is always non ephemeral */
new->flags &= ~UCL_OBJECT_EPHEMERAL;
ucl_parser_get_cur_file (struct ucl_parser *parser)
{
return parser->cur_file;
-}
\ No newline at end of file
+}