summaryrefslogtreecommitdiff
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-72c539d35e1853980de1d74e65acc9a22caa63f6.tar.gz
rockbox-72c539d35e1853980de1d74e65acc9a22caa63f6.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)
287/* load and sort directory into the tree's cache. returns NULL on failure. */ 287/* load and sort directory into the tree's cache. returns NULL on failure. */
288int ft_load(struct tree_context* c, const char* tempdir) 288int ft_load(struct tree_context* c, const char* tempdir)
289{ 289{
290 if (c->out_of_tree > 0) /* something else is loaded */
291 return 0;
292
290 int files_in_dir = 0; 293 int files_in_dir = 0;
291 int name_buffer_used = 0; 294 int name_buffer_used = 0;
292 struct dirent *entry; 295 struct dirent *entry;
293 bool (*callback_show_item)(char *, int, struct tree_context *) = NULL; 296 bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
294 DIR *dir; 297 DIR *dir;
295 298
299 if (!c->is_browsing)
300 c->browse = NULL;
301
296 if (tempdir) 302 if (tempdir)
297 dir = opendir(tempdir); 303 dir = opendir(tempdir);
298 else 304 else
@@ -760,6 +766,7 @@ int ft_enter(struct tree_context* c)
760 } 766 }
761 } 767 }
762 } 768 }
769
763 return rc; 770 return rc;
764} 771}
765 772
@@ -802,5 +809,7 @@ int ft_exit(struct tree_context* c)
802 if (exit_func) 809 if (exit_func)
803 rc = 3; 810 rc = 3;
804 811
812 c->out_of_tree = 0;
813
805 return rc; 814 return rc;
806} 815}
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)
353 { 353 {
354 if (strstr(tc->currdir, PLUGIN_DIR) != NULL) 354 if (strstr(tc->currdir, PLUGIN_DIR) != NULL)
355 return true; 355 return true;
356 tc->browse = NULL; /* exit immediately */ 356 tc->is_browsing = false; /* exit immediately */
357 } 357 }
358 else if(attr & FILE_ATTR_ROCK) 358 else if(attr & FILE_ATTR_ROCK)
359 { 359 {
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
32 SCLA_USB, 32 SCLA_USB,
33}; 33};
34 34
35 35static size_t root_len;
36static char *link_filename; 36static char *link_filename;
37static bool user_file; 37static bool user_file;
38 38
@@ -175,6 +175,42 @@ bool goto_entry(char *file_or_dir)
175} 175}
176#endif 176#endif
177 177
178static bool callback_show_item(char *name, int attr, struct tree_context *tc)
179{
180 (void)name;
181 if(attr & ATTR_DIRECTORY)
182 {
183 if ((tc->browse->flags & BROWSE_SELECTED) == 0 &&
184 rb->strlen(tc->currdir) < root_len)
185 {
186 tc->is_browsing = false; /* exit immediately */
187 }
188 }
189
190 return true;
191}
192
193bool open_browse(char *path, char *buf, size_t bufsz)
194{
195 struct browse_context browse = {
196 .dirfilter = rb->global_settings->dirfilter,
197 .flags = BROWSE_DIRFILTER| BROWSE_SELECTONLY | BROWSE_NO_CONTEXT_MENU,
198 .title = path,
199 .icon = Icon_Plugin,
200 .root = path,
201 .buf = buf,
202 .bufsize = bufsz,
203 .callback_show_item = callback_show_item,
204 };
205 root_len = 0;
206 char *name = rb->strrchr(path, '/');
207 if (name)
208 root_len = name - path;
209 rb->rockbox_browse(&browse);
210
211 return (browse.flags & BROWSE_SELECTED);
212}
213
178int goto_entry(char *file_or_dir) 214int goto_entry(char *file_or_dir)
179{ 215{
180 DEBUGF("Trying to go to '%s'...\n", file_or_dir); 216 DEBUGF("Trying to go to '%s'...\n", file_or_dir);
@@ -202,14 +238,18 @@ int goto_entry(char *file_or_dir)
202 } 238 }
203 else 239 else
204 { 240 {
205 /* Set the browsers dirfilter to the global setting 241 if (!is_dir)
206 * This is required in case the plugin was launched 242 {
207 * from the plugins browser, in which case the 243 rb->set_current_file(file_or_dir);
208 * dirfilter is set to only display .rock files */ 244 return LOOP_EXIT;
209 rb->set_dirfilter(rb->global_settings->dirfilter); 245 }
210 246 char tmp_buf[MAX_PATH];
211 /* Change directory to the entry selected by the user */ 247 if (open_browse(file_or_dir, tmp_buf, sizeof(tmp_buf)))
212 rb->set_current_file(file_or_dir); 248 {
249 DEBUGF("Trying to load '%s'...\n", tmp_buf);
250 rb->set_current_file(tmp_buf);
251 return LOOP_EXIT;
252 }
213 } 253 }
214 return PLUGIN_OK; 254 return PLUGIN_OK;
215} 255}
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)
608 { 608 {
609 tc.selected_item = tree_get_file_position(lastfile); 609 tc.selected_item = tree_get_file_position(lastfile);
610 } 610 }
611
612 if (!tc.is_browsing && tc.out_of_tree == 0)
613 {
614 /* the browser is closed */
615 /* don't allow the previous items to overwrite what we just loaded */
616 tc.out_of_tree = tc.selected_item + 1;
617 }
611} 618}
612 619
613 620
@@ -652,7 +659,7 @@ static int dirbrowse(void)
652 return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */ 659 return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */
653 } 660 }
654 661
655 while(tc.browse) { 662 while(tc.browse && tc.is_browsing) {
656 bool restore = false; 663 bool restore = false;
657 if (tc.dirlevel < 0) 664 if (tc.dirlevel < 0)
658 tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */ 665 tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */
@@ -973,10 +980,18 @@ static struct tree_context backups[NUM_TC_BACKUP];
973static int backup_count = -1; 980static int backup_count = -1;
974int rockbox_browse(struct browse_context *browse) 981int rockbox_browse(struct browse_context *browse)
975{ 982{
983 tc.is_browsing = (browse != NULL);
976 static char current[MAX_PATH]; 984 static char current[MAX_PATH];
977 int ret_val = 0; 985 int ret_val = 0;
978 int dirfilter = browse->dirfilter; 986 int dirfilter = browse->dirfilter;
979 987
988 if (tc.out_of_tree > 0)
989 {
990 tc.selected_item = tc.out_of_tree - 1;
991 tc.out_of_tree = 0;
992 return ft_enter(&tc);
993 }
994
980 if (backup_count >= NUM_TC_BACKUP) 995 if (backup_count >= NUM_TC_BACKUP)
981 return GO_TO_PREVIOUS; 996 return GO_TO_PREVIOUS;
982 if (backup_count >= 0) 997 if (backup_count >= 0)
@@ -1031,6 +1046,9 @@ int rockbox_browse(struct browse_context *browse)
1031 backup_count--; 1046 backup_count--;
1032 if (backup_count >= 0) 1047 if (backup_count >= 0)
1033 tc = backups[backup_count]; 1048 tc = backups[backup_count];
1049
1050 tc.is_browsing = false;
1051
1034 return ret_val; 1052 return ret_val;
1035} 1053}
1036 1054
@@ -1198,7 +1216,7 @@ static int ft_play_filename(char *dir, char *file, int attr)
1198/* These two functions are called by the USB and shutdown handlers */ 1216/* These two functions are called by the USB and shutdown handlers */
1199void tree_flush(void) 1217void tree_flush(void)
1200{ 1218{
1201 tc.browse = NULL; /* clear browse to prevent reentry to a possibly missing file */ 1219 tc.is_browsing = false;/* clear browse to prevent reentry to a possibly missing file */
1202#ifdef HAVE_TAGCACHE 1220#ifdef HAVE_TAGCACHE
1203 tagcache_shutdown(); 1221 tagcache_shutdown();
1204#endif 1222#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 {
90 int currtable; /* db use */ 90 int currtable; /* db use */
91 int currextra; /* db use */ 91 int currextra; /* db use */
92#endif 92#endif
93 int sort_dir; /* directory sort order */
94 int out_of_tree; /* shortcut from elsewhere */
93 struct tree_cache cache; 95 struct tree_cache cache;
94 bool dirfull; 96 bool dirfull;
95 int sort_dir; /* directory sort order */ 97 bool is_browsing; /* valid browse context? */
98
96 struct browse_context *browse; 99 struct browse_context *browse;
97}; 100};
98 101