summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2023-11-22 00:07:30 -0500
committerWilliam Wilgus <wilgus.william@gmail.com>2023-11-22 00:52:58 -0500
commit72c539d35e1853980de1d74e65acc9a22caa63f6 (patch)
tree34c70c631addcd7dac99c294a1316391ef3e22c8
parent6e90bfe029fc69ad5a3b0e34b60b8a50f9105c2c (diff)
downloadrockbox-72c539d35e.tar.gz
rockbox-72c539d35e.zip
[Bug_Fix] shortcut to directory in .link files caused crash
since the plugin browser is now closed when running plugins rb->set_current_file() had no valid browser context and used 'random' memory instead also adds a way to discard levels so we can load the desired directory instead of returning to the previous https://forums.rockbox.org/index.php/topic,54694.0.html Change-Id: I624246e56d42972bf6a1ce566a209b745de6f30b
-rw-r--r--apps/filetree.c9
-rw-r--r--apps/open_plugin.c2
-rw-r--r--apps/plugins/shortcuts/shortcuts_view.c58
-rw-r--r--apps/tree.c22
-rw-r--r--apps/tree.h5
5 files changed, 83 insertions, 13 deletions
diff --git a/apps/filetree.c b/apps/filetree.c
index 42f13f39e7..eb429c83e3 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -287,12 +287,18 @@ static int compare(const void* p1, const void* p2)
/* load and sort directory into the tree's cache. returns NULL on failure. */
int ft_load(struct tree_context* c, const char* tempdir)
{
+ if (c->out_of_tree > 0) /* something else is loaded */
+ return 0;
+
int files_in_dir = 0;
int name_buffer_used = 0;
struct dirent *entry;
bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
DIR *dir;
+ if (!c->is_browsing)
+ c->browse = NULL;
+
if (tempdir)
dir = opendir(tempdir);
else
@@ -760,6 +766,7 @@ int ft_enter(struct tree_context* c)
}
}
}
+
return rc;
}
@@ -802,5 +809,7 @@ int ft_exit(struct tree_context* c)
if (exit_func)
rc = 3;
+ c->out_of_tree = 0;
+
return rc;
}
diff --git a/apps/open_plugin.c b/apps/open_plugin.c
index 1256db79f8..afe59b38e3 100644
--- a/apps/open_plugin.c
+++ b/apps/open_plugin.c
@@ -353,7 +353,7 @@ static bool callback_show_item(char *name, int attr, struct tree_context *tc)
{
if (strstr(tc->currdir, PLUGIN_DIR) != NULL)
return true;
- tc->browse = NULL; /* exit immediately */
+ tc->is_browsing = false; /* exit immediately */
}
else if(attr & FILE_ATTR_ROCK)
{
diff --git a/apps/plugins/shortcuts/shortcuts_view.c b/apps/plugins/shortcuts/shortcuts_view.c
index 2a7970bebe..187ed740a1 100644
--- a/apps/plugins/shortcuts/shortcuts_view.c
+++ b/apps/plugins/shortcuts/shortcuts_view.c
@@ -32,7 +32,7 @@ enum sc_list_action_type
SCLA_USB,
};
-
+static size_t root_len;
static char *link_filename;
static bool user_file;
@@ -175,6 +175,42 @@ bool goto_entry(char *file_or_dir)
}
#endif
+static bool callback_show_item(char *name, int attr, struct tree_context *tc)
+{
+ (void)name;
+ if(attr & ATTR_DIRECTORY)
+ {
+ if ((tc->browse->flags & BROWSE_SELECTED) == 0 &&
+ rb->strlen(tc->currdir) < root_len)
+ {
+ tc->is_browsing = false; /* exit immediately */
+ }
+ }
+
+ return true;
+}
+
+bool open_browse(char *path, char *buf, size_t bufsz)
+{
+ struct browse_context browse = {
+ .dirfilter = rb->global_settings->dirfilter,
+ .flags = BROWSE_DIRFILTER| BROWSE_SELECTONLY | BROWSE_NO_CONTEXT_MENU,
+ .title = path,
+ .icon = Icon_Plugin,
+ .root = path,
+ .buf = buf,
+ .bufsize = bufsz,
+ .callback_show_item = callback_show_item,
+ };
+ root_len = 0;
+ char *name = rb->strrchr(path, '/');
+ if (name)
+ root_len = name - path;
+ rb->rockbox_browse(&browse);
+
+ return (browse.flags & BROWSE_SELECTED);
+}
+
int goto_entry(char *file_or_dir)
{
DEBUGF("Trying to go to '%s'...\n", file_or_dir);
@@ -202,14 +238,18 @@ int goto_entry(char *file_or_dir)
}
else
{
- /* Set the browsers dirfilter to the global setting
- * This is required in case the plugin was launched
- * from the plugins browser, in which case the
- * dirfilter is set to only display .rock files */
- rb->set_dirfilter(rb->global_settings->dirfilter);
-
- /* Change directory to the entry selected by the user */
- rb->set_current_file(file_or_dir);
+ if (!is_dir)
+ {
+ rb->set_current_file(file_or_dir);
+ return LOOP_EXIT;
+ }
+ char tmp_buf[MAX_PATH];
+ if (open_browse(file_or_dir, tmp_buf, sizeof(tmp_buf)))
+ {
+ DEBUGF("Trying to load '%s'...\n", tmp_buf);
+ rb->set_current_file(tmp_buf);
+ return LOOP_EXIT;
+ }
}
return PLUGIN_OK;
}
diff --git a/apps/tree.c b/apps/tree.c
index 8fa5f168fd..ba4da816d1 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -608,6 +608,13 @@ void set_current_file(const char *path)
{
tc.selected_item = tree_get_file_position(lastfile);
}
+
+ if (!tc.is_browsing && tc.out_of_tree == 0)
+ {
+ /* the browser is closed */
+ /* don't allow the previous items to overwrite what we just loaded */
+ tc.out_of_tree = tc.selected_item + 1;
+ }
}
@@ -652,7 +659,7 @@ static int dirbrowse(void)
return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */
}
- while(tc.browse) {
+ while(tc.browse && tc.is_browsing) {
bool restore = false;
if (tc.dirlevel < 0)
tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
@@ -973,10 +980,18 @@ static struct tree_context backups[NUM_TC_BACKUP];
static int backup_count = -1;
int rockbox_browse(struct browse_context *browse)
{
+ tc.is_browsing = (browse != NULL);
static char current[MAX_PATH];
int ret_val = 0;
int dirfilter = browse->dirfilter;
+ if (tc.out_of_tree > 0)
+ {
+ tc.selected_item = tc.out_of_tree - 1;
+ tc.out_of_tree = 0;
+ return ft_enter(&tc);
+ }
+
if (backup_count >= NUM_TC_BACKUP)
return GO_TO_PREVIOUS;
if (backup_count >= 0)
@@ -1031,6 +1046,9 @@ int rockbox_browse(struct browse_context *browse)
backup_count--;
if (backup_count >= 0)
tc = backups[backup_count];
+
+ tc.is_browsing = false;
+
return ret_val;
}
@@ -1198,7 +1216,7 @@ static int ft_play_filename(char *dir, char *file, int attr)
/* These two functions are called by the USB and shutdown handlers */
void tree_flush(void)
{
- tc.browse = NULL; /* clear browse to prevent reentry to a possibly missing file */
+ tc.is_browsing = false;/* clear browse to prevent reentry to a possibly missing file */
#ifdef HAVE_TAGCACHE
tagcache_shutdown();
#endif
diff --git a/apps/tree.h b/apps/tree.h
index d454c0f7ee..d13c75d434 100644
--- a/apps/tree.h
+++ b/apps/tree.h
@@ -90,9 +90,12 @@ struct tree_context {
int currtable; /* db use */
int currextra; /* db use */
#endif
+ int sort_dir; /* directory sort order */
+ int out_of_tree; /* shortcut from elsewhere */
struct tree_cache cache;
bool dirfull;
- int sort_dir; /* directory sort order */
+ bool is_browsing; /* valid browse context? */
+
struct browse_context *browse;
};