--- npw-config.c.orig 2008-03-09 17:24:55.000000000 +0000 +++ npw-config.c 2008-03-09 17:26:57.000000000 +0000 @@ -233,6 +233,13 @@ static const char **get_mozilla_plugin_d const int n_default_dirs = (sizeof(default_dirs) / sizeof(default_dirs[0])); const char **dirs = malloc((n_default_dirs + 2) * sizeof(dirs[0])); int i, j; + + if(!dirs) + { + printf("\nFailed to alloc dirs"); + exit(EXIT_FAILURE); + } + for (i = 0, j = 0; i < n_default_dirs; i++) { const char *dir = default_dirs[i]; if (dir && access(dir, F_OK) == 0) @@ -601,13 +608,35 @@ static bool is_wrapper_plugin_handle(voi static bool is_wrapper_plugin(const char *plugin_path, NPW_PluginInfo *out_plugin_info) { - void *handle = dlopen(plugin_path, RTLD_LAZY); - if (handle == NULL) - return false; +pid_t pid; +#define EXIT_TRUE 0 +#define EXIT_FALSE 1 + + if(0 > (pid = fork())) + return false; + + /* IN Child */ + if(!pid) + { + /* test the libary in a child process to prevent a dodgy libary crashing app */ + void *handle; + bool ret; + /* this line may throw SIGSEGV */ + if(NULL == (handle = dlopen(plugin_path, RTLD_LAZY))) + exit(EXIT_FALSE); + + ret = is_wrapper_plugin_handle(handle, out_plugin_info); + dlclose(handle); + exit( (ret) ? EXIT_TRUE : EXIT_FALSE ); + } + else + { + int status; + if(0 >(pid = waitpid(pid,&status,0))) + return false; - bool ret = is_wrapper_plugin_handle(handle, out_plugin_info); - dlclose(handle); - return ret; + return (status == EXIT_TRUE) ; + } } static bool is_wrapper_plugin_0(const char *plugin_path) @@ -643,36 +672,29 @@ static bool is_system_wide_wrapper_plugi typedef bool (*is_plugin_cb)(const char *plugin_path, NPW_PluginInfo *plugin_info); typedef int (*process_plugin_cb)(const char *plugin_path, NPW_PluginInfo *plugin_info); +static int process_entry(struct dirent *ent,const char *plugin_dir,is_plugin_cb test, process_plugin_cb process); static int process_plugin_dir(const char *plugin_dir, is_plugin_cb test, process_plugin_cb process) { - if (g_verbose) - printf("Looking for plugins in %s\n", plugin_dir); - - DIR *dir = opendir(plugin_dir); - if (dir == NULL) - return -1; - - int plugin_path_length = 256; - char *plugin_path = (char *)malloc(plugin_path_length); - int plugin_dir_length = strlen(plugin_dir); - - struct dirent *ent; - while ((ent = readdir(dir)) != NULL) { - int len = plugin_dir_length + 1 + strlen(ent->d_name) + 1; - if (len > plugin_path_length) { - plugin_path_length = len; - plugin_path = (char *)realloc(plugin_path, plugin_path_length); - } - sprintf(plugin_path, "%s/%s", plugin_dir, ent->d_name); - NPW_PluginInfo plugin_info; - if (test(plugin_path, &plugin_info)) - process(plugin_path, &plugin_info); - } - - free(plugin_path); - closedir(dir); - return 0; + DIR *dir; + struct dirent *ent; + + if( !plugin_dir || !test || !process) + return -1; + + if(g_verbose) + printf("\nLooking for plugins in %s\n", plugin_dir); + + if( ! (dir = opendir(plugin_dir))) + return 1; + + while(NULL != (ent = readdir(dir))) + if( process_entry(ent,plugin_dir,test,process) ) { + closedir(dir); + return -1; + } + closedir(dir); + return 0; } static int do_install_plugin(const char *plugin_path, const char *plugin_dir, NPW_PluginInfo *plugin_info) @@ -1089,3 +1111,26 @@ int main(int argc, char *argv[]) return 0; } + +static int process_entry(struct dirent *ent,const char *plugin_dir,is_plugin_cb test, process_plugin_cb process) +{ + NPW_PluginInfo plugin_info = {{0}} ; + int len,tot; + char *p; + + if(!ent || !plugin_dir || !test || !process ) + return -1; + + if(!(p = malloc((len = strlen(ent->d_name) + strlen(plugin_dir) + 5)))) + return -1; + + tot = snprintf(p,len-1, "%s/%s", plugin_dir, ent->d_name); + p[tot] = '\0'; + + if(test(p, &plugin_info)) + process(p, &plugin_info); + free(p); + return 0; +} + +