]> source.dussan.org Git - rspamd.git/commitdiff
Backport fixes from libucl.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 17 May 2015 15:10:29 +0000 (16:10 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 17 May 2015 15:10:29 +0000 (16:10 +0100)
contrib/libucl/ucl.h
contrib/libucl/ucl_hash.c
contrib/libucl/ucl_internal.h
contrib/libucl/ucl_parser.c
contrib/libucl/ucl_util.c

index 7262c8e11bd327f39f3ea23b69bcf5822cceada5..0fbd5b822660143e5644ce8fcba3832e37a1b863 100644 (file)
@@ -497,6 +497,15 @@ UCL_EXTERN ucl_object_t* ucl_array_pop_first (ucl_object_t *top);
 UCL_EXTERN const ucl_object_t* ucl_array_find_index (const ucl_object_t *top,
                unsigned int index);
 
+/**
+ * Return the index of `elt` in the array `top`
+ * @param top object to get a key from (must be of type UCL_ARRAY)
+ * @param elt element to find index of (must NOT be NULL)
+ * @return index of `elt` in the array `top or (unsigned int)-1 if `elt` is not found
+ */
+UCL_EXTERN unsigned int ucl_array_index_of (ucl_object_t *top,
+               ucl_object_t *elt);
+
 /**
  * Replace an element in an array with a different element, returning the object
  * that was replaced. This object is not released, caller must unref the
@@ -791,6 +800,15 @@ struct ucl_parser;
  */
 UCL_EXTERN struct ucl_parser* ucl_parser_new (int flags);
 
+/**
+ * Sets the default priority for the parser applied to chunks that does not
+ * specify priority explicitly
+ * @param parser parser object
+ * @param prio default priority (0 .. 16)
+ * @return true if parser's default priority was set
+ */
+UCL_EXTERN bool ucl_parser_set_default_priority (struct ucl_parser *parser,
+               unsigned prio);
 /**
  * Register new handler for a macro
  * @param parser parser object
index ddddf1dd081203776a103857ae6e6bdebba05a4d..4730b82b8fae3560e949660a45883094ae4ddc06 100644 (file)
@@ -27,6 +27,7 @@
 #include "kvec.h"
 
 #include <time.h>
+#include <limits.h>
 
 struct ucl_hash_elt {
        const ucl_object_t *obj;
@@ -87,11 +88,19 @@ static const unsigned char lc_map[256] = {
                0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
 };
 
+#if (defined(WORD_BIT) && WORD_BIT == 64) || (defined(__WORDSIZE) && __WORDSIZE == 64)
 static inline uint32_t
 ucl_hash_func (const ucl_object_t *o)
 {
        return XXH64 (o->key, o->keylen, ucl_hash_seed ());
 }
+#else
+static inline uint32_t
+ucl_hash_func (const ucl_object_t *o)
+{
+       return XXH32 (o->key, o->keylen, ucl_hash_seed ());
+}
+#endif
 
 static inline int
 ucl_hash_equal (const ucl_object_t *k1, const ucl_object_t *k2)
@@ -106,6 +115,7 @@ ucl_hash_equal (const ucl_object_t *k1, const ucl_object_t *k2)
 KHASH_INIT (ucl_hash_node, const ucl_object_t *, struct ucl_hash_elt, 1,
                ucl_hash_func, ucl_hash_equal)
 
+#if (defined(WORD_BIT) && WORD_BIT == 64) || (defined(__WORDSIZE) && __WORDSIZE == 64)
 static inline uint32_t
 ucl_hash_caseless_func (const ucl_object_t *o)
 {
@@ -147,6 +157,49 @@ ucl_hash_caseless_func (const ucl_object_t *o)
 
        return XXH64_digest (&st);
 }
+#else
+static inline uint32_t
+ucl_hash_caseless_func (const ucl_object_t *o)
+{
+       unsigned len = o->keylen;
+       unsigned leftover = o->keylen % 4;
+       unsigned fp, i;
+       const uint8_t* s = (const uint8_t*)o->key;
+       union {
+               struct {
+                       unsigned char c1, c2, c3, c4;
+               } c;
+               uint32_t pp;
+       } u;
+       XXH32_state_t st;
+
+       fp = len - leftover;
+       XXH32_reset (&st, ucl_hash_seed ());
+
+       for (i = 0; i != fp; i += 4) {
+               u.c.c1 = s[i], u.c.c2 = s[i + 1], u.c.c3 = s[i + 2], u.c.c4 = s[i + 3];
+               u.c.c1 = lc_map[u.c.c1];
+               u.c.c2 = lc_map[u.c.c2];
+               u.c.c3 = lc_map[u.c.c3];
+               u.c.c4 = lc_map[u.c.c4];
+               XXH32_update (&st, &u.pp, sizeof (u));
+       }
+
+       u.pp = 0;
+       switch (leftover) {
+       case 3:
+               u.c.c3 = lc_map[(unsigned char)s[i++]];
+       case 2:
+               u.c.c2 = lc_map[(unsigned char)s[i++]];
+       case 1:
+               u.c.c1 = lc_map[(unsigned char)s[i]];
+               XXH32_update (&st, &u.pp, leftover);
+               break;
+       }
+
+       return XXH32_digest (&st);
+}
+#endif
 
 static inline int
 ucl_hash_caseless_equal (const ucl_object_t *k1, const ucl_object_t *k2)
index 0bb225148b68d0644c5da7c931e405b9166167cf..836fcad80c333a2085d0327aa33c951e55da11d4 100644 (file)
@@ -191,6 +191,7 @@ struct ucl_parser {
        enum ucl_parser_state prev_state;
        unsigned int recursion;
        int flags;
+       unsigned default_priority;
        ucl_object_t *top_obj;
        ucl_object_t *cur_obj;
        ucl_object_t *trash_objs;
index 4b5005be6ebabe34384ccc27700c99236a296163..804744972fe2422871662d234573a548f72555eb 100644 (file)
@@ -981,14 +981,13 @@ ucl_parser_append_elt (struct ucl_parser *parser, ucl_hash_t *cont,
                }
                else {
                        /* Convert to an array */
-                       ucl_hash_delete (cont, top);
                        nobj = ucl_object_typed_new (UCL_ARRAY);
                        nobj->key = top->key;
                        nobj->keylen = top->keylen;
                        nobj->flags |= UCL_OBJECT_MULTIVALUE;
                        ucl_array_append (nobj, top);
                        ucl_array_append (nobj, elt);
-                       ucl_hash_insert (cont, nobj, nobj->key, nobj->keylen);
+                       ucl_hash_replace (cont, top, nobj);
                }
        }
 }
@@ -2091,6 +2090,7 @@ ucl_parser_new (int flags)
        if (new == NULL) {
                return NULL;
        }
+
        memset (new, 0, sizeof (struct ucl_parser));
 
        ucl_parser_register_macro (new, "include", ucl_include_handler, new);
@@ -2105,6 +2105,17 @@ ucl_parser_new (int flags)
        return new;
 }
 
+bool
+ucl_parser_set_default_priority (struct ucl_parser *parser, unsigned prio)
+{
+       if (parser == NULL) {
+               return false;
+       }
+
+       parser->default_priority = prio;
+
+       return true;
+}
 
 void
 ucl_parser_register_macro (struct ucl_parser *parser, const char *macro,
@@ -2194,6 +2205,10 @@ ucl_parser_add_chunk_priority (struct ucl_parser *parser, const unsigned char *d
 {
        struct ucl_chunk *chunk;
 
+       if (parser == NULL) {
+               return false;
+       }
+
        if (data == NULL) {
                ucl_create_err (&parser->err, "invalid chunk added");
                return false;
@@ -2234,7 +2249,12 @@ bool
 ucl_parser_add_chunk (struct ucl_parser *parser, const unsigned char *data,
                size_t len)
 {
-       return ucl_parser_add_chunk_priority (parser, data, len, 0);
+       if (parser == NULL) {
+               return false;
+       }
+
+       return ucl_parser_add_chunk_priority (parser, data, len,
+                       parser->default_priority);
 }
 
 bool
index d976b0d7144925c62d6ea73ea1986f773c33247e..c8ea06c2687f50c981db86b37df3612a520408c7 100644 (file)
@@ -268,6 +268,17 @@ ucl_unescape_json_string (char *str, size_t len)
        while (len) {
                if (*h == '\\') {
                        h ++;
+
+                       if (len == 1) {
+                               /*
+                                * If \ is last, then do not try to go further
+                                * Issue: #74
+                                */
+                               len --;
+                               *t++ = '\\';
+                               continue;
+                       }
+
                        switch (*h) {
                        case 'n':
                                *t++ = '\n';
@@ -352,7 +363,10 @@ ucl_unescape_json_string (char *str, size_t len)
                else {
                        *t++ = *h++;
                }
-               len --;
+
+               if (len > 0) {
+                       len --;
+               }
        }
        *t = '\0';
 
@@ -459,7 +473,7 @@ ucl_parser_free (struct ucl_parser *parser)
                UCL_FREE (sizeof (struct ucl_variable), var);
        }
        LL_FOREACH_SAFE (parser->trash_objs, tr, trtmp) {
-               ucl_object_unref (tr);
+               ucl_object_free_internal (tr, false, ucl_object_dtor_free);
        }
 
        if (parser->err != NULL) {
@@ -483,7 +497,7 @@ ucl_parser_get_error(struct ucl_parser *parser)
        if (parser->err == NULL)
                return NULL;
 
-       return utstring_body(parser->err);
+       return utstring_body (parser->err);
 }
 
 UCL_EXTERN void
@@ -2153,6 +2167,21 @@ ucl_array_find_index (const ucl_object_t *top, unsigned int index)
        return NULL;
 }
 
+unsigned int
+ucl_array_index_of (ucl_object_t *top, ucl_object_t *elt)
+{
+       UCL_ARRAY_GET (vec, top);
+       unsigned i;
+
+       for (i = 0; i < vec->n; i ++) {
+               if (kv_A (*vec, i) == elt) {
+                       return i;
+               }
+       }
+
+       return (unsigned int)(-1);
+}
+
 ucl_object_t *
 ucl_array_replace_index (ucl_object_t *top, ucl_object_t *elt,
        unsigned int index)