diff options
author | William Wilgus <wilgus.william@gmail.com> | 2023-11-22 00:07:30 -0500 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2023-11-22 00:52:58 -0500 |
commit | 72c539d35e1853980de1d74e65acc9a22caa63f6 (patch) | |
tree | 34c70c631addcd7dac99c294a1316391ef3e22c8 /apps | |
parent | 6e90bfe029fc69ad5a3b0e34b60b8a50f9105c2c (diff) | |
download | rockbox-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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/filetree.c | 9 | ||||
-rw-r--r-- | apps/open_plugin.c | 2 | ||||
-rw-r--r-- | apps/plugins/shortcuts/shortcuts_view.c | 58 | ||||
-rw-r--r-- | apps/tree.c | 22 | ||||
-rw-r--r-- | apps/tree.h | 5 |
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. */ |
288 | int ft_load(struct tree_context* c, const char* tempdir) | 288 | int 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 | 35 | static size_t root_len; | |
36 | static char *link_filename; | 36 | static char *link_filename; |
37 | static bool user_file; | 37 | static bool user_file; |
38 | 38 | ||
@@ -175,6 +175,42 @@ bool goto_entry(char *file_or_dir) | |||
175 | } | 175 | } |
176 | #endif | 176 | #endif |
177 | 177 | ||
178 | static 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 | |||
193 | bool 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 | |||
178 | int goto_entry(char *file_or_dir) | 214 | int 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]; | |||
973 | static int backup_count = -1; | 980 | static int backup_count = -1; |
974 | int rockbox_browse(struct browse_context *browse) | 981 | int 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 */ |
1199 | void tree_flush(void) | 1217 | void 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 | ||