summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2006-10-12 14:00:40 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2006-10-12 14:00:40 +0000
commit2caa96dcc97b7d34c5186214a247874b3355071b (patch)
treef8544dc5f2f4c48c344673f6aa6721b72da65b7b /utils
parent50c303284b670449e67b4c2bce36050eac8cc229 (diff)
downloadnetsurf-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.c41
-rw-r--r--utils/messages.c33
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;
}