From 91248f05bda1516746abbb6f1683c0af2c14d9bd Mon Sep 17 00:00:00 2001 From: Slava Zanko <slavazanko@gmail.com> Date: Mon, 12 Oct 2009 16:06:22 +0300 Subject: [PATCH] Ticket #1712: VFS fix for mc. Fix segfaults in various cases while browsing various VFSs. Signed-off-by: Slava Zanko <slavazanko@gmail.com> --- vfs/vfs.c | 58 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/vfs/vfs.c b/vfs/vfs.c index 713f24246..28633abff 100644 --- a/vfs/vfs.c +++ b/vfs/vfs.c @@ -676,6 +676,9 @@ mc_ctl (int handle, int ctlop, void *arg) { struct vfs_class *vfs = vfs_op (handle); + if (vfs == NULL) + return 0; + return vfs->ctl ? (*vfs->ctl)(vfs_info (handle), ctlop, arg) : 0; } @@ -708,6 +711,9 @@ mc_close (int handle) return -1; vfs = vfs_op (handle); + if (vfs == NULL) + return -1; + if (handle < 3) return close (handle); @@ -797,7 +803,11 @@ mc_readdir (DIR *dirp) return NULL; } handle = *(int *) dirp; + vfs = vfs_op (handle); + if (vfs == NULL) + return NULL; + dirinfo = vfs_info (handle); if (vfs->readdir) { entry = (*vfs->readdir) (dirinfo->info); @@ -820,6 +830,9 @@ mc_closedir (DIR *dirp) int result; struct vfs_dirinfo *dirinfo; + if (vfs == NULL) + return -1; + dirinfo = vfs_info (handle); if (dirinfo->converter != str_cnv_from_term) str_close_conv (dirinfo->converter); @@ -834,37 +847,49 @@ int mc_stat (const char *filename, struct stat *buf) { struct vfs_class *vfs; int result; char *path; - + path = vfs_canon_and_translate (filename); - - if (path != NULL) { - vfs = vfs_get_class (path); - + + if (path == NULL) + return -1; + + vfs = vfs_get_class (path); + + if (vfs == NULL) { + g_free (path); + return -1; + } + result = vfs->stat ? (*vfs->stat) (vfs, path, buf) : -1; - + g_free (path); - + if (result == -1) errno = vfs->name ? ferrno (vfs) : E_NOTSUPP; return result; - } else return -1; } int mc_lstat (const char *filename, struct stat *buf) { struct vfs_class *vfs; int result; char *path; - + path = vfs_canon_and_translate (filename); - - if (path != NULL) { - vfs = vfs_get_class (path); + + if (path == NULL) + return -1; + + vfs = vfs_get_class (path); + if (vfs == NULL) { + g_free (path); + return -1; + } + result = vfs->lstat ? (*vfs->lstat) (vfs, path, buf) : -1; g_free (path); if (result == -1) errno = vfs->name ? ferrno (vfs) : E_NOTSUPP; return result; - } else return -1; } int mc_fstat (int handle, struct stat *buf) { @@ -873,7 +898,11 @@ int mc_fstat (int handle, struct stat *buf) { if (handle == -1) return -1; + vfs = vfs_op (handle); + if (vfs == NULL) + return -1; + result = vfs->fstat ? (*vfs->fstat) (vfs_info (handle), buf) : -1; if (result == -1) errno = vfs->name ? ferrno (vfs) : E_NOTSUPP; @@ -967,6 +996,9 @@ off_t mc_lseek (int fd, off_t offset, int whence) return -1; vfs = vfs_op (fd); + if (vfs == NULL) + return -1; + result = vfs->lseek ? (*vfs->lseek)(vfs_info (fd), offset, whence) : -1; if (result == -1) errno = vfs->lseek ? ferrno (vfs) : E_NOTSUPP;