From 52e22b253d7b7d2419a9fb22e2f40c5aeeaa821d Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Tue, 26 Mar 2024 19:02:09 -0400 Subject: [Bugfix] ft_assemble_path extra slashes, Volume unmound double free Change-Id: Ie2e7702d8e252ce29af0b9dbd2e8d9e892b9ca18 --- apps/filetree.c | 58 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'apps/filetree.c') diff --git a/apps/filetree.c b/apps/filetree.c index 4f59804686..66b5c843ca 100644 --- a/apps/filetree.c +++ b/apps/filetree.c @@ -477,41 +477,46 @@ static void ft_apply_skin_file(char *buf, char *file, const int maxlen) int ft_assemble_path(char *buf, size_t bufsz, const char* currdir, const char* filename) { - int len; + size_t len; if (!filename) filename = ""; + #ifdef HAVE_MULTIVOLUME if (currdir && currdir[0] && currdir[1]) /* Not in / */ { if (currdir[1] != VOL_START_TOK) { - len = snprintf(buf, bufsz, "%s%s/%s", root_realpath(), currdir, filename); + len = path_append(buf, root_realpath(), currdir, bufsz); + if (len < bufsz) + len = path_append(buf, buf + len, filename, bufsz - len); } - else - len = snprintf(buf, bufsz, "%s/%s", currdir, filename); + len = path_append(buf, currdir, filename, bufsz); } else /* In / */ { if (filename[0] != VOL_START_TOK) { - len = snprintf(buf, bufsz, "%s/%s",root_realpath(), filename); + len = path_append(buf, root_realpath(), filename, bufsz); } else - len = snprintf(buf, bufsz, "/%s", filename); + len = path_append(buf, PATH_SEPSTR, filename, bufsz); } #else if (currdir && currdir[0] && currdir[1]) /* Not in / */ { - len = snprintf(buf, bufsz, "%s%s/%s", root_realpath(), currdir, filename); + len = path_append(buf, root_realpath(), currdir, bufsz); + if(len < bufsz) + len = path_append(buf, buf + len, filename, bufsz - len); } else /* In / */ { - len = snprintf(buf, bufsz, "%s/%s",root_realpath(), filename); + len = path_append(buf, root_realpath(), filename, bufsz); } #endif - if ((unsigned) len > bufsz) + + if (len > bufsz) splash(HZ, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); - return len; + return (int)len; } int ft_enter(struct tree_context* c) @@ -528,7 +533,6 @@ int ft_enter(struct tree_context* c) int file_attr = file->attr; ft_assemble_path(buf, sizeof(buf), c->currdir, file->name); - if (file_attr & ATTR_DIRECTORY) { memcpy(c->currdir, buf, sizeof(c->currdir)); if ( c->dirlevel < MAX_DIR_LEVELS ) @@ -814,17 +818,39 @@ int ft_exit(struct tree_context* c) extern char lastfile[]; /* from tree.c */ char buf[MAX_PATH]; int rc = 0; - bool exit_func = false; - + bool exit_func = false; int i = strlen(c->currdir); if (i>1) { - while (c->currdir[i-1]!='/') + while (c->currdir[i-1]!=PATH_SEPCH) i--; strcpy(buf,&c->currdir[i]); if (i==1) - c->currdir[i]=0; + c->currdir[i]='\0'; else - c->currdir[i-1]=0; + c->currdir[i-1]='\0'; + +#ifdef HAVE_MULTIVOLUME /* un-redirect the realpath */ + if ((unsigned)c->dirlevel<=2) /* only expect redirect two levels max */ + { + char *currdir = c->currdir; + const char *root = root_realpath(); + int len = i-1; + /* compare to the root path bail if they don't match except single '/' */ + for (; len > 0 && *root != '\0' && *root == *currdir; len--) + { + root++; + currdir++; + } + if (*root == PATH_SEPCH) /* root may have trailing slash */ + root++; + if (*root == '\0' && + (len == 0 || (len == 1 && *currdir == PATH_SEPCH))) + { + strcpy(c->currdir, PATH_ROOTSTR); + c->dirlevel=1; + } + } +#endif if (*c->dirfilter > NUM_FILTER_MODES && c->dirlevel < 1) exit_func = true; -- cgit v1.2.3