[#17212] Define loading order for lua plugins

Instead of loading lua plugins in the random-seeming order that is
returned by the filesystem, sort the list of plugin filenames in
ASCIIbetical order. This makes the load order of plugins predictable.

This particular order was chosen to be consistent with the precedent set
by various *nix tools.
This commit is contained in:
David Perry 2021-03-17 07:19:14 -04:00 committed by Wireshark GitLab Utility
parent 9f72d4ce60
commit 26c5635973
1 changed files with 41 additions and 12 deletions

View File

@ -618,6 +618,10 @@ static int wslua_panic(lua_State* LS) {
return 0; /* keep gcc happy */
}
static gint string_compare(gconstpointer a, gconstpointer b) {
return strcmp((const char*)a, (const char*)b);
}
static int lua_load_plugins(const char *dirname, register_cb cb, gpointer client_data,
gboolean count_only, const gboolean is_user, GHashTable *loaded_files)
{
@ -626,6 +630,9 @@ static int lua_load_plugins(const char *dirname, register_cb cb, gpointer client
gchar *filename, *dot;
const gchar *name;
int plugins_counter = 0;
GList *sorted_dirnames = NULL;
GList *sorted_filenames = NULL;
GList *l = NULL;
if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL) {
while ((file = ws_dir_read_name(dir)) != NULL) {
@ -636,8 +643,7 @@ static int lua_load_plugins(const char *dirname, register_cb cb, gpointer client
filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", dirname, name);
if (test_for_directory(filename) == EISDIR) {
plugins_counter += lua_load_plugins(filename, cb, client_data, count_only, is_user, loaded_files);
g_free(filename);
sorted_dirnames = g_list_prepend(sorted_dirnames, (gpointer)filename);
continue;
}
@ -654,26 +660,49 @@ static int lua_load_plugins(const char *dirname, register_cb cb, gpointer client
continue;
}
if (file_exists(filename)) {
sorted_filenames = g_list_prepend(sorted_filenames, (gpointer)filename);
}
else {
g_free(filename);
}
}
ws_dir_close(dir);
}
/* Depth first; ie, process subdirectories (in ASCIIbetical order) before files */
if (sorted_dirnames != NULL) {
sorted_dirnames = g_list_sort(sorted_dirnames, string_compare);
for (l = sorted_dirnames; l != NULL; l = l->next) {
plugins_counter += lua_load_plugins((const char *)l->data, cb, client_data, count_only, is_user, loaded_files);
}
g_list_free_full(sorted_dirnames, g_free);
}
/* Process files in ASCIIbetical order */
if (sorted_filenames != NULL) {
sorted_filenames = g_list_sort(sorted_filenames, string_compare);
for (l = sorted_filenames; l != NULL; l = l->next) {
filename = (gchar *)l->data;
name = strrchr(filename, G_DIR_SEPARATOR) + 1;
/* Check if we have already loaded this file name, if provided with a set */
if (loaded_files && g_hash_table_lookup_extended(loaded_files, name, NULL, NULL)) {
g_free(filename);
continue;
}
if (file_exists(filename)) {
if (!count_only) {
if (cb)
(*cb)(RA_LUA_PLUGINS, name, client_data);
lua_load_plugin_script(name, filename, is_user ? dirname : NULL, 0);
}
if (!count_only) {
if (cb)
(*cb)(RA_LUA_PLUGINS, name, client_data);
lua_load_plugin_script(name, filename, is_user ? dirname : NULL, 0);
if (loaded_files) {
g_hash_table_insert(loaded_files, g_strdup(name), NULL);
}
plugins_counter++;
}
g_free(filename);
plugins_counter++;
}
ws_dir_close(dir);
g_list_free_full(sorted_filenames, g_free);
}
return plugins_counter;