[prev in list] [next in list] [prev in thread] [next in thread] 

List:       rockbox-cvs
Subject:    [Bug_Fix] shortcut to directory in .link files caused crash
From:       rockbox-gerrit-noreply--- via rockbox-cvs <rockbox-cvs () lists ! haxx ! se>
Date:       2023-11-22 5:59:23
Message-ID: 202311220559.3AM5xNC5349372 () archos ! rockbox ! org
[Download RAW message or body]

commit 72c539d35e1853980de1d74e65acc9a22caa63f6
Author: William Wilgus <wilgus.william@gmail.com>
Date:   Wed Nov 22 00:07:30 2023 -0500

    [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

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;
 };
 
-- 
rockbox-cvs mailing list
rockbox-cvs@lists.haxx.se
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic