From 54b8c9aaadb204e3a1765465e8605e7e141192f9 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 14 Nov 2003 08:25:50 +0000 Subject: [PATCH] * vfs.c (vfs_split): Deconstify. * direntry.c (vfs_s_get_path_mangle): Likewise. "mangle" is in the name for a reason. Use vfs_s_get_path() instead where the path should be preserved. * extfs.c (extfs_get_path_mangle): Likewise. * sfs.c (sfs_vfmake): Protect against changes in vfs_split(). --- vfs/ChangeLog | 9 +++++++++ vfs/direntry.c | 36 ++++++++++++++++++++++++++---------- vfs/extfs.c | 35 +++++++++++++++++++++++------------ vfs/sfs.c | 48 +++++++++++++++++++++++++++++++++++++----------- vfs/vfs.c | 2 +- vfs/vfs.h | 2 +- vfs/xdirentry.h | 2 +- 7 files changed, 98 insertions(+), 36 deletions(-) diff --git a/vfs/ChangeLog b/vfs/ChangeLog index b38d99f59..e6286c552 100644 --- a/vfs/ChangeLog +++ b/vfs/ChangeLog @@ -1,3 +1,12 @@ +2003-11-14 Pavel Roskin + + * vfs.c (vfs_split): Deconstify. + * direntry.c (vfs_s_get_path_mangle): Likewise. "mangle" is in + the name for a reason. Use vfs_s_get_path() instead where the + path should be preserved. + * extfs.c (extfs_get_path_mangle): Likewise. + * sfs.c (sfs_vfmake): Protect against changes in vfs_split(). + 2003-11-13 Pavel Roskin * vfs.h: Constify chdir() and opendir() methods. Adjust all diff --git a/vfs/direntry.c b/vfs/direntry.c index e1323e599..306236bbe 100644 --- a/vfs/direntry.c +++ b/vfs/direntry.c @@ -424,10 +424,13 @@ vfs_s_free_super (struct vfs_class *me, struct vfs_s_super *super) g_free(super); } -/* ------------------------------------------------------------------------= */ +/* + * Dissect the path and create corresponding superblock. Note that inname + * can be changed and the result may point inside the original string. + */ char * -vfs_s_get_path_mangle (struct vfs_class *me, const char *inname, +vfs_s_get_path_mangle (struct vfs_class *me, char *inname, struct vfs_s_super **archive, int flags) { char *local, *op; @@ -479,14 +482,20 @@ vfs_s_get_path_mangle (struct vfs_class *me, const char *inname, return local; } + +/* + * Dissect the path and create corresponding superblock. + * The result should be freed. + */ static char * -vfs_s_get_path (struct vfs_class *me, const char *inname, struct vfs_s_super **archive, int flags) +vfs_s_get_path (struct vfs_class *me, const char *inname, + struct vfs_s_super **archive, int flags) { - char *buf = g_strdup( inname ); + char *buf = g_strdup (inname); char *res = vfs_s_get_path_mangle (me, buf, archive, flags); if (res) - res = g_strdup(res); - g_free(buf); + res = g_strdup (res); + g_free (buf); return res; } @@ -538,7 +547,7 @@ vfs_s_inode_from_path (struct vfs_class *me, const char *name, int flags) struct vfs_s_inode *ino; char *q; - if (!(q = vfs_s_get_path_mangle (me, name, &super, 0))) + if (!(q = vfs_s_get_path (me, name, &super, 0))) return NULL; ino = @@ -552,6 +561,7 @@ vfs_s_inode_from_path (struct vfs_class *me, const char *name, int flags) flags & FL_FOLLOW ? LINK_FOLLOW : LINK_NO_FOLLOW, FL_DIR | (flags & ~FL_FOLLOW)); + g_free (q); return ino; } @@ -688,7 +698,7 @@ vfs_s_open (struct vfs_class *me, const char *file, int flags, int mode) char *q; struct vfs_s_inode *ino; - if ((q = vfs_s_get_path_mangle (me, file, &super, 0)) == NULL) + if ((q = vfs_s_get_path (me, file, &super, 0)) == NULL) return NULL; ino = vfs_s_find_inode (me, super, q, LINK_FOLLOW, FL_NONE); if (ino && ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) @@ -700,8 +710,10 @@ vfs_s_open (struct vfs_class *me, const char *file, int flags, int mode) int tmp_handle; /* If the filesystem is read-only, disable file creation */ - if (!(flags & O_CREAT) || !(me->write)) + if (!(flags & O_CREAT) || !(me->write)) { + g_free (q); return NULL; + } split_dir_name (me, q, &dirname, &name, &save); /* FIXME: check if vfs_s_find_inode returns NULL */ @@ -712,12 +724,16 @@ vfs_s_open (struct vfs_class *me, const char *file, int flags, int mode) ino = ent->ino; vfs_s_insert_entry (me, dir, ent); tmp_handle = vfs_mkstemps (&ino->localname, me->name, name); - if (tmp_handle == -1) + if (tmp_handle == -1) { + g_free (q); return NULL; + } close (tmp_handle); was_changed = 1; } + g_free (q); + if (S_ISDIR (ino->st.st_mode)) ERRNOR (EISDIR, NULL); diff --git a/vfs/extfs.c b/vfs/extfs.c index 2879622bc..873dd997c 100644 --- a/vfs/extfs.c +++ b/vfs/extfs.c @@ -423,12 +423,12 @@ extfs_read_archive (int fstype, const char *name, struct archive **pparc) } /* - * Returns path inside argument. Returned char* is inside inname, which is - * mangled by this operation (so you must not free its return value). + * Dissect the path and create corresponding superblock. Note that inname + * can be changed and the result may point inside the original string. */ static char * -extfs_get_path_mangle (const char *inname, struct archive **archive, - int is_dir, int do_not_open) +extfs_get_path_mangle (char *inname, struct archive **archive, int is_dir, + int do_not_open) { char *local, *op; const char *archive_name; @@ -476,9 +476,14 @@ extfs_get_path_mangle (const char *inname, struct archive **archive, return local; } + +/* + * Dissect the path and create corresponding superblock. + * The result should be freed. + */ static char * extfs_get_path (const char *inname, struct archive **archive, int is_dir, - int do_not_open) + int do_not_open) { char *buf = g_strdup (inname); char *res = extfs_get_path_mangle (buf, archive, is_dir, do_not_open); @@ -489,7 +494,8 @@ extfs_get_path (const char *inname, struct archive **archive, int is_dir, return res2; } -/* Returns allocated path (without leading slash) inside the archive */ + +/* Return allocated path (without leading slash) inside the archive */ static char *extfs_get_path_from_entry (struct entry *entry) { struct list { @@ -658,7 +664,7 @@ extfs_open (struct vfs_class *me, const char *file, int flags, int mode) int local_handle; int created = 0; - if ((q = extfs_get_path_mangle (file, &archive, 0, 0)) == NULL) + if ((q = extfs_get_path (file, &archive, 0, 0)) == NULL) return NULL; entry = extfs_find_entry (archive->root_entry, q, 0, 0); if (entry == NULL && (flags & O_CREAT)) { @@ -666,6 +672,8 @@ extfs_open (struct vfs_class *me, const char *file, int flags, int mode) entry = extfs_find_entry (archive->root_entry, q, 0, 1); created = (entry != NULL); } + + g_free (q); if (entry == NULL) return NULL; if ((entry = extfs_resolve_symlinks (entry)) == NULL) @@ -861,9 +869,10 @@ static void * extfs_opendir (struct vfs_class *me, const char *dirname) struct entry *entry; struct entry **info; - if ((q = extfs_get_path_mangle (dirname, &archive, 1, 0)) == NULL) + if ((q = extfs_get_path (dirname, &archive, 1, 0)) == NULL) return NULL; entry = extfs_find_entry (archive->root_entry, q, 0, 0); + g_free (q); if (entry == NULL) return NULL; if ((entry = extfs_resolve_symlinks (entry)) == NULL) @@ -1071,21 +1080,23 @@ static int extfs_rmdir (struct vfs_class *me, char *path) return 0; } -static int extfs_chdir (struct vfs_class *me, const char *path) +static int +extfs_chdir (struct vfs_class *me, const char *path) { struct archive *archive; char *q; struct entry *entry; my_errno = ENOTDIR; - if ((q = extfs_get_path_mangle (path, &archive, 1, 0)) == NULL) + if ((q = extfs_get_path (path, &archive, 1, 0)) == NULL) return -1; entry = extfs_find_entry (archive->root_entry, q, 0, 0); + g_free (q); if (!entry) - return -1; + return -1; entry = extfs_resolve_symlinks (entry); if ((!entry) || (!S_ISDIR (entry->inode->mode))) - return -1; + return -1; my_errno = 0; return 0; } diff --git a/vfs/sfs.c b/vfs/sfs.c index 694898820..78fb7a025 100644 --- a/vfs/sfs.c +++ b/vfs/sfs.c @@ -58,25 +58,50 @@ sfs_vfmake (struct vfs_class *me, const char *name, char *cache) char pad[10240]; char *s, *t = pad; int was_percent = 0; + char *pname; /* name of parent archive */ + char *pqname; /* name of parent archive, quoted */ - vfs_split (name, &inpath, &op); + pname = g_strdup (name); + vfs_split (pname, &inpath, &op); if ((w = (*me->which) (me, op)) == -1) vfs_die ("This cannot happen... Hopefully.\n"); - if ((sfs_flags[w] & F_1) || (!strcmp (name, "/"))); - else + if (!(sfs_flags[w] & F_1) && strcmp (pname, "/")) { + g_free (pname); return -1; + } + /* if ((sfs_flags[w] & F_2) || (!inpath) || (!*inpath)); else return -1; */ if (!(sfs_flags[w] & F_NOLOCALCOPY)) { - s = mc_getlocalcopy (name); - if (!s) + s = mc_getlocalcopy (pname); + if (!s) { + g_free (pname); return -1; - name = name_quote (s, 0); + } + pqname = name_quote (s, 0); g_free (s); - } else - name = name_quote (name, 0); -#define COPY_CHAR if (t-pad>sizeof(pad)) { return -1; } else *t++ = *s; -#define COPY_STRING(a) if ((t-pad)+strlen(a)>sizeof(pad)) { return -1; } else { strcpy (t, a); t+= strlen(a); } + } else { + pqname = name_quote (pname, 0); + } + g_free (pname); + +#define COPY_CHAR \ + if (t-pad>sizeof(pad)) { \ + g_free (pqname); \ + return -1; \ + } \ + else \ + *t++ = *s; + +#define COPY_STRING(a) \ + if ((t-pad)+strlen(a)>sizeof(pad)) { \ + g_free (pqname); \ + return -1; \ + } else { \ + strcpy (t, a); \ + t+= strlen(a); \ + } + for (s = sfs_command[w]; *s; s++) { if (was_percent) { @@ -85,7 +110,7 @@ sfs_vfmake (struct vfs_class *me, const char *name, char *cache) switch (*s) { case '1': - ptr = name; + ptr = pqname; break; case '2': ptr = op + strlen (sfs_prefix[w]); @@ -106,6 +131,7 @@ sfs_vfmake (struct vfs_class *me, const char *name, char *cache) } } + g_free (pqname); open_error_pipe (); if (my_system (EXECUTE_AS_SHELL, "/bin/sh", pad)) { close_error_pipe (1, NULL); diff --git a/vfs/vfs.c b/vfs/vfs.c index e39eb64e0..1f9cdbc9e 100644 --- a/vfs/vfs.c +++ b/vfs/vfs.c @@ -214,7 +214,7 @@ path_magic (const char *path) * want to free neither *inpath nor *op */ struct vfs_class * -vfs_split (const char *path, char **inpath, char **op) +vfs_split (char *path, char **inpath, char **op) { char *semi; char *slash; diff --git a/vfs/vfs.h b/vfs/vfs.h index 6be317e1c..47cec74f3 100644 --- a/vfs/vfs.h +++ b/vfs/vfs.h @@ -109,7 +109,7 @@ void vfs_init (void); void vfs_shut (void); struct vfs_class *vfs_get_class (const char *path); -struct vfs_class *vfs_split (const char *path, char **inpath, char **op); +struct vfs_class *vfs_split (char *path, char **inpath, char **op); char *vfs_path (const char *path); char *vfs_strip_suffix_from_filename (const char *filename); char *vfs_canon (const char *path); diff --git a/vfs/xdirentry.h b/vfs/xdirentry.h index 29fab64e9..152c76c06 100644 --- a/vfs/xdirentry.h +++ b/vfs/xdirentry.h @@ -178,7 +178,7 @@ struct vfs_s_inode *vfs_s_find_root (struct vfs_class *me, /* outside interface */ void vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub); -char *vfs_s_get_path_mangle (struct vfs_class *me, const char *inname, +char *vfs_s_get_path_mangle (struct vfs_class *me, char *inname, struct vfs_s_super **archive, int flags); void vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super); char *vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino);