summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-05-17 16:10:29 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-05-17 16:10:29 +0100
commit253aee289e1a6b6c3cefd11b3f719655226dc34d (patch)
treec04b48b5de3f9ea649651873871f0bbb8c065804 /contrib
parente334f5a9115c6eec839c71858d0e9f6e5f774eee (diff)
downloadrspamd-253aee289e1a6b6c3cefd11b3f719655226dc34d.tar.gz
rspamd-253aee289e1a6b6c3cefd11b3f719655226dc34d.zip
Backport fixes from libucl.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/libucl/ucl.h18
-rw-r--r--contrib/libucl/ucl_hash.c53
-rw-r--r--contrib/libucl/ucl_internal.h1
-rw-r--r--contrib/libucl/ucl_parser.c26
-rw-r--r--contrib/libucl/ucl_util.c35
5 files changed, 127 insertions, 6 deletions
diff --git a/contrib/libucl/ucl.h b/contrib/libucl/ucl.h
index 7262c8e11..0fbd5b822 100644
--- a/contrib/libucl/ucl.h
+++ b/contrib/libucl/ucl.h
@@ -498,6 +498,15 @@ 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
* returned object when it is no longer needed.
@@ -792,6 +801,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
* @param macro macro name (without leading dot)
diff --git a/contrib/libucl/ucl_hash.c b/contrib/libucl/ucl_hash.c
index ddddf1dd0..4730b82b8 100644
--- a/contrib/libucl/ucl_hash.c
+++ b/contrib/libucl/ucl_hash.c
@@ -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)
diff --git a/contrib/libucl/ucl_internal.h b/contrib/libucl/ucl_internal.h
index 0bb225148..836fcad80 100644
--- a/contrib/libucl/ucl_internal.h
+++ b/contrib/libucl/ucl_internal.h
@@ -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;
diff --git a/contrib/libucl/ucl_parser.c b/contrib/libucl/ucl_parser.c
index 4b5005be6..804744972 100644
--- a/contrib/libucl/ucl_parser.c
+++ b/contrib/libucl/ucl_parser.c
@@ -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
diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c
index d976b0d71..c8ea06c26 100644
--- a/contrib/libucl/ucl_util.c
+++ b/contrib/libucl/ucl_util.c
@@ -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)