From 858d9d90cbf0d9e2f9e02d4a9252e21d62eaa08c Mon Sep 17 00:00:00 2001 From: Chris Allegretta Date: Thu, 30 Jan 2003 00:53:32 +0000 Subject: [PATCH] - files.c:do_browse_from() - Fix path checking to fix bad paths, escaping the operating directory, new function readable_dir() (David Benbennick) git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1408 35c25a1d-7b9e-4130-9fde-d3aeb78583b8 --- ChangeLog | 6 +++++ files.c | 67 ++++++++++++++++++++++++++++++++++++------------------- proto.h | 1 + 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d5871c5..dddd7f88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,12 @@ CVS Code - - Fix incorrect cursor location when cutting long lines (David Benbennick). - files.c: + - Set a default PATH_MAX for getcwd() etc calls (David + Benbennick). + do_browse_from() + - Fix path checking to fix bad paths, escaping + the operating directory, new function readable_dir() (David + Benbennick). do_browser() - Fix incorrect path check for check_operating_dir() (David Benbennick). diff --git a/files.c b/files.c index 88056320..7c46929e 100644 --- a/files.c +++ b/files.c @@ -38,6 +38,12 @@ #include "proto.h" #include "nano.h" +/* Set a default value for PATH_MAX, so we can use it below in lines like + path = getcwd(NULL, PATH_MAX + 1); */ +#ifndef PATH_MAX +#define PATH_MAX -1 +#endif + #ifndef NANO_SMALL static int fileformat = 0; /* 0 = *nix, 1 = DOS, 2 = Mac */ #endif @@ -2408,6 +2414,16 @@ void striponedir(char *foo) } } +int readable_dir(const char *path) +{ + DIR *dir = opendir(path); + + /* If dir is NULL, don't do closedir(), since that changes errno. */ + if (dir != NULL) + closedir(dir); + return dir != NULL; +} + /* Initialize the browser code, including the list of files in *path */ char **browser_init(const char *path, int *longest, int *numents) { @@ -2810,34 +2826,39 @@ char *do_browser(const char *inpath) char *do_browse_from(const char *inpath) { struct stat st; - char *tmp; char *bob; + /* The result of do_browser; the selected file name. */ + char *path; + /* inpath, tilde expanded. */ - /* If there's no / in the string, we may as well start from . */ - if (inpath == NULL || strchr(inpath, '/') == NULL) { -#ifdef PATH_MAX - char *from = getcwd(NULL, PATH_MAX + 1); -#else - char *from = getcwd(NULL, 0); -#endif + assert(inpath != NULL); + + path = real_dir_from_tilde(inpath); - bob = do_browser(from != NULL ? from : "./"); - free(from); - return bob; + /* + * Perhaps path is a directory. If so, we will pass that to + * do_browser. Otherwise, perhaps path is a directory / a file. So + * we try stripping off the last path element. If it still isn't a + * directory, just use the current directory. */ + + if (stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) { + striponedir(path); + if (stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) + path = getcwd(NULL, PATH_MAX + 1); } - /* If the string is a directory, pass do_browser() that */ - st = filestat(inpath); - if (S_ISDIR(st.st_mode)) - return do_browser(inpath); - - tmp = mallocstrcpy(NULL, inpath); - /* Okay, there's a dir in there, but not at the end of the string... - try stripping it off */ - striponedir(tmp); - align(&tmp); - bob = do_browser(tmp); - free(tmp); +#ifndef DISABLE_OPERATINGDIR + /* If the resulting path isn't in the operating directory, use that. */ + if (check_operating_dir(path, FALSE)) + path = mallocstrcpy(path, operating_dir); +#endif + + if (!readable_dir(path)) { + beep(); + bob = NULL; + } else + bob = do_browser(path); + free(path); return bob; } #endif /* !DISABLE_BROWSER */ diff --git a/proto.h b/proto.h index 8f202b56..530f552a 100644 --- a/proto.h +++ b/proto.h @@ -182,6 +182,7 @@ int diralphasort(const void *va, const void *vb); void free_charptrarray(char **array, int len); const char *tail(const char *foo); void striponedir(char *foo); +int readable_dir(const char *path); char **browser_init(const char *path, int *longest, int *numents); char *do_browser(const char *inpath); char *do_browse_from(const char *inpath); -- 2.39.5