|
 |
0e0432 |
diff --git a/imap/http_dav.c b/imap/http_dav.c
|
|
 |
0e0432 |
index 91bbc28b6b..a6fa5c8345 100644
|
|
 |
0e0432 |
--- a/imap/http_dav.c
|
|
 |
0e0432 |
+++ b/imap/http_dav.c
|
|
 |
0e0432 |
@@ -5494,7 +5494,7 @@ EXPORTED int meth_propfind(struct transaction_t *txn, void *params)
|
|
 |
0e0432 |
xmlDocPtr indoc = NULL, outdoc = NULL;
|
|
 |
0e0432 |
xmlNodePtr root, cur = NULL, props = NULL;
|
|
 |
0e0432 |
xmlNsPtr ns[NUM_NAMESPACE];
|
|
 |
0e0432 |
- struct hash_table ns_table = { 0, NULL, NULL };
|
|
 |
0e0432 |
+ struct hash_table ns_table = HASH_TABLE_INITIALIZER;
|
|
 |
0e0432 |
struct propfind_ctx fctx;
|
|
 |
0e0432 |
struct propfind_entry_list *elist = NULL;
|
|
 |
0e0432 |
|
|
 |
0e0432 |
@@ -7900,7 +7900,7 @@ int meth_report(struct transaction_t *txn, void *params)
|
|
 |
0e0432 |
xmlNodePtr inroot = NULL, outroot = NULL, cur, prop = NULL, props = NULL;
|
|
 |
0e0432 |
const struct report_type_t *report = NULL;
|
|
 |
0e0432 |
xmlNsPtr ns[NUM_NAMESPACE];
|
|
 |
0e0432 |
- struct hash_table ns_table = { 0, NULL, NULL };
|
|
 |
0e0432 |
+ struct hash_table ns_table = HASH_TABLE_INITIALIZER;
|
|
 |
0e0432 |
struct propfind_ctx fctx;
|
|
 |
0e0432 |
struct propfind_entry_list *elist = NULL;
|
|
 |
0e0432 |
|
|
 |
0e0432 |
diff --git a/lib/hash.c b/lib/hash.c
|
|
 |
0e0432 |
index 9703142c3b..84f2e80d28 100644
|
|
 |
0e0432 |
--- a/lib/hash.c
|
|
 |
0e0432 |
+++ b/lib/hash.c
|
|
 |
0e0432 |
@@ -43,10 +43,11 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us
|
|
 |
0e0432 |
assert(table);
|
|
 |
0e0432 |
assert(size);
|
|
 |
0e0432 |
|
|
 |
0e0432 |
- table->size = size;
|
|
 |
0e0432 |
+ table->size = size;
|
|
 |
0e0432 |
+ table->seed = rand(); /* might be zero, that's okay */
|
|
 |
0e0432 |
|
|
 |
0e0432 |
/* Allocate the table -- different for using memory pools and not */
|
|
 |
0e0432 |
- if(use_mpool) {
|
|
 |
0e0432 |
+ if (use_mpool) {
|
|
 |
0e0432 |
/* Allocate an initial memory pool for 32 byte keys + the hash table
|
|
 |
0e0432 |
* + the buckets themselves */
|
|
 |
0e0432 |
table->pool =
|
|
 |
0e0432 |
@@ -72,7 +73,7 @@ EXPORTED hash_table *construct_hash_table(hash_table *table, size_t size, int us
|
|
 |
0e0432 |
|
|
 |
0e0432 |
EXPORTED void *hash_insert(const char *key, void *data, hash_table *table)
|
|
 |
0e0432 |
{
|
|
 |
0e0432 |
- unsigned val = strhash(key) % table->size;
|
|
 |
0e0432 |
+ unsigned val = strhash_seeded(table->seed, key) % table->size;
|
|
 |
0e0432 |
bucket *ptr, *newptr;
|
|
 |
0e0432 |
bucket **prev;
|
|
 |
0e0432 |
|
|
 |
0e0432 |
@@ -153,9 +154,14 @@ EXPORTED void *hash_insert(const char *key, void *data, hash_table *table)
|
|
 |
0e0432 |
|
|
 |
0e0432 |
EXPORTED void *hash_lookup(const char *key, hash_table *table)
|
|
 |
0e0432 |
{
|
|
 |
0e0432 |
- unsigned val = strhash(key) % table->size;
|
|
 |
0e0432 |
+ unsigned val;
|
|
 |
0e0432 |
bucket *ptr;
|
|
 |
0e0432 |
|
|
 |
0e0432 |
+ if (!table->size)
|
|
 |
0e0432 |
+ return NULL;
|
|
 |
0e0432 |
+
|
|
 |
0e0432 |
+ val = strhash_seeded(table->seed, key) % table->size;
|
|
 |
0e0432 |
+
|
|
 |
0e0432 |
if (!(table->table)[val])
|
|
 |
0e0432 |
return NULL;
|
|
 |
0e0432 |
|
|
 |
0e0432 |
@@ -178,8 +184,7 @@ EXPORTED void *hash_lookup(const char *key, hash_table *table)
|
|
 |
0e0432 |
* since it will leak memory until you get rid of the entire hash table */
|
|
 |
0e0432 |
EXPORTED void *hash_del(const char *key, hash_table *table)
|
|
 |
0e0432 |
{
|
|
 |
0e0432 |
- unsigned val = strhash(key) % table->size;
|
|
 |
0e0432 |
- void *data;
|
|
 |
0e0432 |
+ unsigned val = strhash_seeded(table->seed, key) % table->size;
|
|
 |
0e0432 |
bucket *ptr, *last = NULL;
|
|
 |
0e0432 |
|
|
 |
0e0432 |
if (!(table->table)[val])
|
|
 |
0e0432 |
@@ -200,15 +205,10 @@ EXPORTED void *hash_del(const char *key, hash_table *table)
|
|
 |
0e0432 |
int cmpresult = strcmp(key, ptr->key);
|
|
 |
0e0432 |
if (!cmpresult)
|
|
 |
0e0432 |
{
|
|
 |
0e0432 |
+ void *data = ptr->data;
|
|
 |
0e0432 |
if (last != NULL )
|
|
 |
0e0432 |
{
|
|
 |
0e0432 |
- data = ptr -> data;
|
|
 |
0e0432 |
last -> next = ptr -> next;
|
|
 |
0e0432 |
- if(!table->pool) {
|
|
 |
0e0432 |
- free(ptr->key);
|
|
 |
0e0432 |
- free(ptr);
|
|
 |
0e0432 |
- }
|
|
 |
0e0432 |
- return data;
|
|
 |
0e0432 |
}
|
|
 |
0e0432 |
|
|
 |
0e0432 |
/*
|
|
 |
0e0432 |
@@ -221,15 +221,15 @@ EXPORTED void *hash_del(const char *key, hash_table *table)
|
|
 |
0e0432 |
|
|
 |
0e0432 |
else
|
|
 |
0e0432 |
{
|
|
 |
0e0432 |
- data = ptr->data;
|
|
 |
0e0432 |
(table->table)[val] = ptr->next;
|
|
 |
0e0432 |
- if(!table->pool) {
|
|
 |
0e0432 |
- free(ptr->key);
|
|
 |
0e0432 |
- free(ptr);
|
|
 |
0e0432 |
- }
|
|
 |
0e0432 |
- return data;
|
|
 |
0e0432 |
}
|
|
 |
0e0432 |
- } else if (cmpresult < 0) {
|
|
 |
0e0432 |
+ if(!table->pool) {
|
|
 |
0e0432 |
+ free(ptr->key);
|
|
 |
0e0432 |
+ free(ptr);
|
|
 |
0e0432 |
+ }
|
|
 |
0e0432 |
+ return data;
|
|
 |
0e0432 |
+ }
|
|
 |
0e0432 |
+ if (cmpresult < 0) {
|
|
 |
0e0432 |
/* its not here! */
|
|
 |
0e0432 |
return NULL;
|
|
 |
0e0432 |
}
|
|
 |
0e0432 |
diff --git a/lib/hash.h b/lib/hash.h
|
|
 |
0e0432 |
index 8051ac1760..cfa7da1ffa 100644
|
|
 |
0e0432 |
--- a/lib/hash.h
|
|
 |
0e0432 |
+++ b/lib/hash.h
|
|
 |
0e0432 |
@@ -3,10 +3,11 @@
|
|
 |
0e0432 |
#define HASH__H
|
|
 |
0e0432 |
|
|
 |
0e0432 |
#include <stddef.h> /* For size_t */
|
|
 |
0e0432 |
+#include <stdint.h>
|
|
 |
0e0432 |
#include "mpool.h"
|
|
 |
0e0432 |
#include "strarray.h"
|
|
 |
0e0432 |
|
|
 |
0e0432 |
-#define HASH_TABLE_INITIALIZER {0, NULL, NULL}
|
|
 |
0e0432 |
+#define HASH_TABLE_INITIALIZER {0, 0, NULL, NULL}
|
|
 |
0e0432 |
|
|
 |
0e0432 |
/*
|
|
 |
0e0432 |
** A hash table consists of an array of these buckets. Each bucket
|
|
 |
0e0432 |
@@ -32,6 +33,7 @@ typedef struct bucket {
|
|
 |
0e0432 |
|
|
 |
0e0432 |
typedef struct hash_table {
|
|
 |
0e0432 |
size_t size;
|
|
 |
0e0432 |
+ uint32_t seed;
|
|
 |
0e0432 |
bucket **table;
|
|
 |
0e0432 |
struct mpool *pool;
|
|
 |
0e0432 |
} hash_table;
|
|
 |
0e0432 |
diff --git a/lib/strhash.c b/lib/strhash.c
|
|
 |
0e0432 |
index d7c1741d2a..1b3251db73 100644
|
|
 |
0e0432 |
--- a/lib/strhash.c
|
|
 |
0e0432 |
+++ b/lib/strhash.c
|
|
 |
0e0432 |
@@ -42,17 +42,32 @@
|
|
 |
0e0432 |
|
|
 |
0e0432 |
#include "config.h"
|
|
 |
0e0432 |
|
|
 |
0e0432 |
-EXPORTED unsigned strhash(const char *string)
|
|
 |
0e0432 |
+#include "lib/strhash.h"
|
|
 |
0e0432 |
+
|
|
 |
0e0432 |
+/* The well-known djb2 algorithm (e.g. http://www.cse.yorku.ca/~oz/hash.html),
|
|
 |
0e0432 |
+ * with the addition of an optional seed to limit predictability.
|
|
 |
0e0432 |
+ *
|
|
 |
0e0432 |
+ * XXX return type 'unsigned' for back-compat to previous version, but
|
|
 |
0e0432 |
+ * XXX ought to be 'uint32_t'
|
|
 |
0e0432 |
+ */
|
|
 |
0e0432 |
+EXPORTED unsigned strhash_seeded_djb2(uint32_t seed, const char *string)
|
|
 |
0e0432 |
{
|
|
 |
0e0432 |
- unsigned ret_val = 0;
|
|
 |
0e0432 |
- int i;
|
|
 |
0e0432 |
+ const unsigned char *ustr = (const unsigned char *) string;
|
|
 |
0e0432 |
+ unsigned hash = 5381;
|
|
 |
0e0432 |
+ int c;
|
|
 |
0e0432 |
|
|
 |
0e0432 |
- while (*string)
|
|
 |
0e0432 |
- {
|
|
 |
0e0432 |
- i = (int) *string;
|
|
 |
0e0432 |
- ret_val ^= i;
|
|
 |
0e0432 |
- ret_val <<= 1;
|
|
 |
0e0432 |
- string ++;
|
|
 |
0e0432 |
- }
|
|
 |
0e0432 |
- return ret_val;
|
|
 |
0e0432 |
+ if (seed) {
|
|
 |
0e0432 |
+ /* treat the bytes of the seed as a prefix to the string */
|
|
 |
0e0432 |
+ unsigned i;
|
|
 |
0e0432 |
+ for (i = 0; i < sizeof seed; i++) {
|
|
 |
0e0432 |
+ c = seed & 0xff;
|
|
 |
0e0432 |
+ hash = ((hash << 5) + hash) ^ c;
|
|
 |
0e0432 |
+ seed >>= 8;
|
|
 |
0e0432 |
+ }
|
|
 |
0e0432 |
+ }
|
|
 |
0e0432 |
+
|
|
 |
0e0432 |
+ while ((c = *ustr++))
|
|
 |
0e0432 |
+ hash = ((hash << 5) + hash) ^ c;
|
|
 |
0e0432 |
+
|
|
 |
0e0432 |
+ return hash;
|
|
 |
0e0432 |
}
|
|
 |
0e0432 |
diff --git a/lib/strhash.h b/lib/strhash.h
|
|
 |
0e0432 |
index 34533fdffa..27339bb288 100644
|
|
 |
0e0432 |
--- a/lib/strhash.h
|
|
 |
0e0432 |
+++ b/lib/strhash.h
|
|
 |
0e0432 |
@@ -41,7 +41,11 @@
|
|
 |
0e0432 |
*/
|
|
 |
0e0432 |
|
|
 |
0e0432 |
#ifndef _STRHASH_H_
|
|
 |
0e0432 |
+#include <stdint.h>
|
|
 |
0e0432 |
|
|
 |
0e0432 |
-unsigned strhash(const char *string);
|
|
 |
0e0432 |
+unsigned strhash_seeded_djb2(uint32_t seed, const char *string);
|
|
 |
0e0432 |
+
|
|
 |
0e0432 |
+#define strhash(in) strhash_seeded_djb2((0), (in))
|
|
 |
0e0432 |
+#define strhash_seeded(sd, in) strhash_seeded_djb2((sd), (in))
|
|
 |
0e0432 |
|
|
 |
0e0432 |
#endif /* _STRHASH_H_ */
|