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
This commit is contained in:
John Mark Bell 2006-10-12 14:00:40 +00:00
parent 50c303284b
commit 2caa96dcc9
3 changed files with 126 additions and 64 deletions

View File

@ -299,33 +299,24 @@ void gui_init(int argc, char** argv)
while (*help == 9) help++;
if (!memcmp(help, "0.55", 4))
#endif
ro_plot_patterned_lines = false;
ro_plot_patterned_lines = false;
}
atexit(ro_gui_cleanup);
prev_sigs.sigabrt = signal(SIGABRT, ro_gui_signal);
prev_sigs.sigfpe = signal(SIGFPE, ro_gui_signal);
prev_sigs.sigill = signal(SIGILL, ro_gui_signal);
prev_sigs.sigint = signal(SIGINT, ro_gui_signal);
prev_sigs.sigsegv = signal(SIGSEGV, ro_gui_signal);
prev_sigs.sigterm = signal(SIGTERM, ro_gui_signal);
if (prev_sigs.sigabrt == SIG_ERR || prev_sigs.sigfpe == SIG_ERR ||
prev_sigs.sigill == SIG_ERR ||
prev_sigs.sigint == SIG_ERR ||
prev_sigs.sigsegv == SIG_ERR ||
prev_sigs.sigterm == SIG_ERR)
die("Failed registering signal handlers");
filename_initialise();
#ifdef WITH_SAVE_COMPLETE
save_complete_init();
#endif
/* Read in the options */
options_read("NetSurf:Choices");
/* set defaults for absent strings */
/* Choose the interface language to use */
ro_gui_choose_language();
/* Load in our language-specific Messages */
if ((length = snprintf(path, sizeof(path),
"NetSurf:Resources.%s.Messages",
option_language)) < 0 || length >= (int)sizeof(path))
die("Failed to locate Messages resource.");
messages_load(path);
messages_load("NetSurf:Resources.LangNames");
/* Set defaults for absent option strings */
if (!option_theme)
option_theme = strdup("Aletheia");
if (!option_toolbar_browser)
@ -369,18 +360,31 @@ void gui_init(int argc, char** argv)
!option_theme_save)
die("Failed initialising string options");
/* create our choices directories */
/* Create our choices directories */
ro_gui_create_dirs();
/* Register exit and signal handlers */
atexit(ro_gui_cleanup);
prev_sigs.sigabrt = signal(SIGABRT, ro_gui_signal);
prev_sigs.sigfpe = signal(SIGFPE, ro_gui_signal);
prev_sigs.sigill = signal(SIGILL, ro_gui_signal);
prev_sigs.sigint = signal(SIGINT, ro_gui_signal);
prev_sigs.sigsegv = signal(SIGSEGV, ro_gui_signal);
prev_sigs.sigterm = signal(SIGTERM, ro_gui_signal);
if (prev_sigs.sigabrt == SIG_ERR || prev_sigs.sigfpe == SIG_ERR ||
prev_sigs.sigill == SIG_ERR ||
prev_sigs.sigint == SIG_ERR ||
prev_sigs.sigsegv == SIG_ERR ||
prev_sigs.sigterm == SIG_ERR)
die("Failed registering signal handlers");
/* Load in UI sprites */
gui_sprites = ro_gui_load_sprite_file("NetSurf:Resources.Sprites");
if (!gui_sprites)
die("Unable to load Sprites.");
ro_gui_choose_language();
bitmap_initialise_memory();
urldb_load(option_url_path);
urldb_load_cookies(option_cookie_file);
/* Find NetSurf directory */
nsdir_temp = getenv("NetSurf$Dir");
if (!nsdir_temp)
die("Failed to locate NetSurf directory");
@ -388,18 +392,28 @@ void gui_init(int argc, char** argv)
if (!NETSURF_DIR)
die("Failed duplicating NetSurf directory string");
if ((length = snprintf(path, sizeof(path),
"NetSurf:Resources.%s.Messages",
option_language)) < 0 || length >= (int)sizeof(path))
die("Failed to locate Messages resource.");
messages_load(path);
messages_load("NetSurf:Resources.LangNames");
/* Initialise stylesheet URLs */
default_stylesheet_url = strdup("file:///NetSurf:/Resources/CSS");
adblock_stylesheet_url = strdup("file:///NetSurf:/Resources/AdBlock");
if (!default_stylesheet_url || !adblock_stylesheet_url)
die("Failed initialising string constants.");
/* Initialise filename allocator */
filename_initialise();
/* Initialise save complete functionality */
#ifdef WITH_SAVE_COMPLETE
save_complete_init();
#endif
/* Initialise bitmap memory pool */
bitmap_initialise_memory();
/* Load in visited URLs and Cookies */
urldb_load(option_url_path);
urldb_load_cookies(option_cookie_file);
/* Initialise with the wimp */
error = xwimp_initialise(wimp_VERSION_RO38, task_name,
(const wimp_message_list *) &task_messages, 0,
&task_handle);
@ -408,7 +422,7 @@ void gui_init(int argc, char** argv)
error->errnum, error->errmess));
die(error->errmess);
}
/* register our message handlers */
/* Register message handlers */
ro_message_register_route(message_HELP_REQUEST,
ro_gui_interactive_help_request);
ro_message_register_route(message_DATA_OPEN,
@ -427,9 +441,11 @@ void gui_init(int argc, char** argv)
ro_gui_selection_drag_claim);
ro_message_register_route(message_WINDOW_INFO,
ro_msg_window_info);
/* end of handler registration */
/* Initialise the font subsystem */
nsfont_init();
/* Initialise global information */
ro_gui_get_screen_properties();
ro_gui_wimp_get_desktop_font();
@ -437,8 +453,7 @@ void gui_init(int argc, char** argv)
if (getenv("NetSurf$Start_URI_Handler"))
xwimp_start_task("Desktop", 0);
/* Open the templates
*/
/* Open the templates */
if ((length = snprintf(path, sizeof(path),
"NetSurf:Resources.%s.Templates",
option_language)) < 0 || length >= (int)sizeof(path))
@ -449,17 +464,30 @@ void gui_init(int argc, char** argv)
error->errnum, error->errmess));
die(error->errmess);
}
ro_gui_theme_initialise(); /* initialise themes before dialogs */
ro_gui_dialog_init(); /* must be done after sprite loading */
/* Initialise themes before dialogs */
ro_gui_theme_initialise();
/* Initialise dialog windows (must be after UI sprites are loaded) */
ro_gui_dialog_init();
/* Initialise download window */
ro_gui_download_init();
/* Initialise menus */
ro_gui_menu_init();
/* Initialise query windows */
ro_gui_query_init();
/* Initialise the history subsystem */
ro_gui_history_init();
/* Done with the templates file */
wimp_close_template();
ro_gui_tree_initialise(); /* must be done after sprite loading */
/* Initialise tree views (must be after UI sprites are loaded) */
ro_gui_tree_initialise();
/* Create Iconbar icon */
ro_gui_icon_bar_create();
/* Finally, check Inet$Resolvers for sanity */
ro_gui_check_resolvers();
}
@ -2196,7 +2224,7 @@ void warn_user(const char *warning, const char *detail)
* Should only be used during initialisation.
*/
void die(const char *error)
void die(const char * const error)
{
os_error warn_error;

View File

@ -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");

View File

@ -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;
}