]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Backport fixes from libucl
authorVsevolod Stakhov <vsevolod@rspamd.com>
Thu, 25 Apr 2024 14:27:24 +0000 (15:27 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Thu, 25 Apr 2024 14:27:47 +0000 (15:27 +0100)
contrib/libucl/ucl_msgpack.c
contrib/libucl/ucl_util.c

index 1fcdcc8750d7d67bceb4da22d62b3d950e52751c..9190cc4c6b0135ae38ca495dbd204fec8e811013 100644 (file)
@@ -438,7 +438,7 @@ static ssize_t ucl_msgpack_parse_ignore (struct ucl_parser *parser,
 /*
  * 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                   */
@@ -1019,6 +1019,8 @@ ucl_msgpack_consume (struct ucl_parser *parser)
                        }
                        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",
@@ -1028,7 +1030,6 @@ ucl_msgpack_consume (struct ucl_parser *parser)
                                }
 
                                p ++;
-                               remain --;
 
                                switch (obj_parser->len) {
                                case 1:
@@ -1044,8 +1045,10 @@ ucl_msgpack_consume (struct ucl_parser *parser)
                                        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;
@@ -1131,7 +1134,9 @@ ucl_msgpack_consume (struct ucl_parser *parser)
                         */
                        container = parser->stack;
 
-                       if (container == NULL) {
+                       if (parser->stack == NULL) {
+                               ucl_create_err (&parser->err,
+                                               "read assoc value when no container represented");
                                return false;
                        }
 
@@ -1141,9 +1146,14 @@ ucl_msgpack_consume (struct ucl_parser *parser)
 
 
                        /* 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)) {
@@ -1191,6 +1201,8 @@ ucl_msgpack_consume (struct ucl_parser *parser)
                        container = parser->stack;
 
                        if (container == NULL) {
+                               ucl_create_err (&parser->err,
+                                               "read assoc value when no container represented");
                                return false;
                        }
 
@@ -1200,9 +1212,12 @@ ucl_msgpack_consume (struct ucl_parser *parser)
 
                        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;
@@ -1237,7 +1252,9 @@ ucl_msgpack_consume (struct ucl_parser *parser)
        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;
                }
@@ -1245,6 +1262,12 @@ ucl_msgpack_consume (struct ucl_parser *parser)
                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)) {
@@ -1271,7 +1294,9 @@ ucl_msgpack_consume (struct ucl_parser *parser)
 
                container = parser->stack;
 
-               if (container == NULL) {
+               if (parser->stack == NULL) {
+                       ucl_create_err (&parser->err,
+                                       "read assoc value when no container represented");
                        return false;
                }
 
@@ -1281,9 +1306,11 @@ ucl_msgpack_consume (struct ucl_parser *parser)
 
 
                /* 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:
@@ -1301,7 +1328,12 @@ ucl_msgpack_consume (struct ucl_parser *parser)
 
        /* 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;
 }
@@ -1611,5 +1643,7 @@ ucl_msgpack_parse_ignore (struct ucl_parser *parser,
                return -1;
        }
 
+       parser->cur_obj = NULL;
+
        return len;
 }
index 3f2483c10f65fe4a2f3bfaa88c5e5eb4ea00787d..b00f2779e52a857de939a9753344fe63a4c2e2a6 100644 (file)
@@ -67,7 +67,7 @@ typedef kvec_t(ucl_object_t *) ucl_array_t;
 #include <fetch.h>
 #endif
 
-#if defined(_MSC_VER)
+#if defined(_WIN32)
 #include <windows.h>
 #include <io.h>
 #include <direct.h>
@@ -866,6 +866,8 @@ ucl_fetch_url (const unsigned char *url, unsigned char **buf, size_t *buflen,
        *buf = cbdata.buf;
        *buflen = cbdata.buflen;
 
+       curl_easy_cleanup (curl);
+
        return true;
 #else
        ucl_create_err (err, "URL support is disabled");
@@ -1020,6 +1022,9 @@ ucl_include_url (const unsigned char *data, size_t len,
        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;
        }
 
@@ -1095,6 +1100,11 @@ ucl_include_file_single (const unsigned char *data, size_t len,
        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) {
@@ -1131,6 +1141,8 @@ ucl_include_file_single (const unsigned char *data, size_t len,
                        return false;
                }
 
+               ucl_parser_clear_error (parser);
+
                return true;
        }
 
@@ -1850,6 +1862,10 @@ ucl_load_handler (const unsigned char *data, size_t len,
                                !try_load)) {
                        free (load_file);
 
+                       if (try_load) {
+                               ucl_parser_clear_error (parser);
+                       }
+
                        return (try_load || false);
                }
 
@@ -3078,13 +3094,13 @@ ucl_object_type (const ucl_object_t *obj)
 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 *
@@ -3375,10 +3391,20 @@ ucl_elt_append (ucl_object_t *head, ucl_object_t *elt)
                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;
@@ -3588,11 +3614,15 @@ ucl_object_copy_internal (const ucl_object_t *other, bool allow_array)
        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;
@@ -3949,4 +3979,4 @@ const char *
 ucl_parser_get_cur_file (struct ucl_parser *parser)
 {
        return parser->cur_file;
-}
\ No newline at end of file
+}