diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2006-10-12 14:00:40 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2006-10-12 14:00:40 +0000 |
commit | 2caa96dcc97b7d34c5186214a247874b3355071b (patch) | |
tree | f8544dc5f2f4c48c344673f6aa6721b72da65b7b /utils | |
parent | 50c303284b670449e67b4c2bce36050eac8cc229 (diff) | |
download | netsurf-2caa96dcc97b7d34c5186214a247874b3355071b.tar.gz netsurf-2caa96dcc97b7d34c5186214a247874b3355071b.tar.bz2 |
Fix attempts to call die() before messages_hash exists:
1) Make hash_* more robust in the face of bad parameters
2) Make messages_* more robust in the face of bad parameters
3) Tidy up gui_init such that localised messages are loaded at the
earliest opportunity
svn path=/trunk/netsurf/; revision=2998
Diffstat (limited to 'utils')
-rw-r--r-- | utils/hashtable.c | 41 | ||||
-rw-r--r-- | utils/messages.c | 33 |
2 files changed, 54 insertions, 20 deletions
diff --git a/utils/hashtable.c b/utils/hashtable.c index f26c9f0e1..62eb415e2 100644 --- a/utils/hashtable.c +++ b/utils/hashtable.c @@ -28,7 +28,7 @@ * \return struct hash_table containing the context of this hash table or NULL * if there is insufficent memory to create it and its chains. */ - + struct hash_table *hash_create(unsigned int chains) { struct hash_table *r = malloc(sizeof(struct hash_table)); @@ -61,11 +61,14 @@ void hash_destroy(struct hash_table *ht) { unsigned int i; + if (ht == NULL) + return; + for (i = 0; i < ht->nchains; i++) { if (ht->chain[i] != NULL) { struct hash_entry *e = ht->chain[i]; while (e) { - struct hash_entry *n = e->next; + struct hash_entry *n = e->next; free(e->key); free(e->value); free(e); @@ -93,22 +96,28 @@ void hash_destroy(struct hash_table *ht) bool hash_add(struct hash_table *ht, const char *key, const char *value) { - unsigned int h = hash_string_fnv(key); - unsigned int c = h % ht->nchains; + unsigned int h; + unsigned int c; struct hash_entry *e = malloc(sizeof(struct hash_entry)); - + + if (ht == NULL || key == NULL || value == NULL) + return false; + if (e == NULL) { LOG(("Not enough memory for hash entry.")); return false; } + h = hash_string_fnv(key); + c = h % ht->nchains; + e->key = strdup(key); if (e->key == NULL) { LOG(("Unable to strdup() key for hash table.")); free(e); return false; } - + e->value = strdup(value); if (e->value == NULL) { LOG(("Unable to strdup() value for hash table.")); @@ -133,10 +142,17 @@ bool hash_add(struct hash_table *ht, const char *key, const char *value) const char *hash_get(struct hash_table *ht, const char *key) { - unsigned int h = hash_string_fnv(key); - unsigned int c = h % ht->nchains; - struct hash_entry *e = ht->chain[c]; - + unsigned int h; + unsigned int c; + struct hash_entry *e; + + if (ht == NULL || key == NULL) + return NULL; + + h = hash_string_fnv(key); + c = h % ht->nchains; + e = ht->chain[c]; + while (e) { if (!strcmp(key, e->key)) return e->value; @@ -160,6 +176,9 @@ unsigned int hash_string_fnv(const char *datum) { unsigned int z = 0x01000193, i = 0; + if (datum == NULL) + return 0; + while (datum[i]) { z *= 0x01000193; z ^= datum[i]; @@ -228,7 +247,7 @@ int main(int argc, char *argv[]) a = hash_create(1031); b = hash_create(7919); - + dict = fopen("/usr/share/dict/words", "r"); if (dict == NULL) { fprintf(stderr, "Unable to open /usr/share/dict/words - extensive testing skipped.\n"); diff --git a/utils/messages.c b/utils/messages.c index a40c2b3bf..e3a8d5c90 100644 --- a/utils/messages.c +++ b/utils/messages.c @@ -41,9 +41,11 @@ struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) { char s[400]; FILE *fp; - + + assert(path != NULL); + ctx = (ctx != NULL) ? ctx : hash_create(HASH_SIZE); - + if (ctx == NULL) { LOG(("Unable to create hash table for messages file %s", path)); return NULL; @@ -70,7 +72,7 @@ struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) continue; *colon = 0; /* terminate key */ value = colon + 1; - + if (hash_add(ctx, s, value) == false) { LOG(("Unable to add %s:%s to hash table of %s", s, value, path)); @@ -80,7 +82,7 @@ struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) } fclose(fp); - + return ctx; } @@ -99,15 +101,18 @@ void messages_load(const char *path) { struct hash_table *m; char s[400]; - + + assert(path != NULL); + m = messages_load_ctx(path, messages_hash); if (m == NULL) { LOG(("Unable to open Messages file '%s'. Possible reason: %s", path, strerror(errno))); - snprintf(s, 400, "Unable to open Messages file '%s'.", path); + snprintf(s, sizeof s, + "Unable to open Messages file '%s'.", path); die(s); } - + messages_hash = m; } @@ -121,8 +126,18 @@ void messages_load(const char *path) const char *messages_get_ctx(const char *key, struct hash_table *ctx) { - const char *r = hash_get(ctx, key); - + const char *r; + + assert(key != NULL); + + /* If we're called with no context, it's nicer to return the + * key rather than explode - this allows attempts to get messages + * before messages_hash is set up to fail gracefully, for example */ + if (ctx == NULL) + return key; + + r = hash_get(ctx, key); + return r ? r : key; } |