From c7fe9ab439a015bd234fa972057b29f8ce43f4cb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 16 Jul 2001 17:36:28 +0000 Subject: [PATCH] Architecture adjustment for enumerating files with regards to whether symlinks are permitted. --- archivers/dir.c | 6 ++++-- archivers/grp.c | 4 +++- archivers/zip.c | 4 +++- physfs.c | 3 ++- physfs_internal.h | 13 +++++++++---- platform/unix.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/archivers/dir.c b/archivers/dir.c index a2ff55dd..06e4117f 100644 --- a/archivers/dir.c +++ b/archivers/dir.c @@ -140,13 +140,15 @@ static DirHandle *DIR_openArchive(const char *name, int forWriting) } /* DIR_openArchive */ -static LinkedStringList *DIR_enumerateFiles(DirHandle *h, const char *dname) +static LinkedStringList *DIR_enumerateFiles(DirHandle *h, + const char *dname, + int omitSymLinks) { char *d = __PHYSFS_platformCvtToDependent((char *)(h->opaque),dname,NULL); LinkedStringList *retval; BAIL_IF_MACRO(d == NULL, NULL, NULL); - retval = __PHYSFS_platformEnumerateFiles(d); + retval = __PHYSFS_platformEnumerateFiles(d, omitSymLinks); free(d); return(retval); } /* DIR_enumerateFiles */ diff --git a/archivers/grp.c b/archivers/grp.c index dc96de55..a579bbe7 100644 --- a/archivers/grp.c +++ b/archivers/grp.c @@ -197,7 +197,9 @@ static DirHandle *GRP_openArchive(const char *name, int forWriting) } /* GRP_openArchive */ -static LinkedStringList *GRP_enumerateFiles(DirHandle *h, const char *dirname) +static LinkedStringList *GRP_enumerateFiles(DirHandle *h, + const char *dirname, + int omitSymLinks) { char buf[16]; GRPinfo *g = (GRPinfo *) (h->opaque); diff --git a/archivers/zip.c b/archivers/zip.c index 09b252e1..2b7e3560 100644 --- a/archivers/zip.c +++ b/archivers/zip.c @@ -123,7 +123,9 @@ static DirHandle *ZIP_openArchive(const char *name, int forWriting) } /* ZIP_openArchive */ -static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, const char *dirname) +static LinkedStringList *ZIP_enumerateFiles(DirHandle *h, + const char *dirname, + int omitSymLinks) { ZIPinfo *zi = (ZIPinfo *) (h->opaque); unzFile fh = zi->handle; diff --git a/physfs.c b/physfs.c index 8c70ce53..cc6377c0 100644 --- a/physfs.c +++ b/physfs.c @@ -1022,6 +1022,7 @@ char **PHYSFS_enumerateFiles(const char *path) char **retval = NULL; LinkedStringList *rc; LinkedStringList *finalList = NULL; + int omitSymLinks = !allowSymLinks; while (*path == '/') path++; @@ -1031,7 +1032,7 @@ char **PHYSFS_enumerateFiles(const char *path) DirHandle *h = i->dirHandle; if (__PHYSFS_verifySecurity(h, path)) { - rc = h->funcs->enumerateFiles(h, path); + rc = h->funcs->enumerateFiles(h, path, omitSymLinks); interpolateStringLists(&finalList, rc); } /* if */ } /* for */ diff --git a/physfs_internal.h b/physfs_internal.h index 38e86289..c25c5b54 100644 --- a/physfs_internal.h +++ b/physfs_internal.h @@ -142,11 +142,14 @@ typedef struct __PHYSFS_DIRFUNCTIONS__ * Returns a list of all files in dirname. Each element of this list * (and its "str" field) will be deallocated with the system's free() * function by the caller, so be sure to explicitly malloc() each - * chunk. + * chunk. Omit symlinks if (omitSymLinks) is non-zero. * If you have a memory failure, return as much as you can. * This dirname is in platform-independent notation. */ - LinkedStringList *(*enumerateFiles)(DirHandle *r, const char *dirname); + LinkedStringList *(*enumerateFiles)(DirHandle *r, + const char *dirname, + int omitSymLinks); + /* * Returns non-zero if filename can be opened for reading. @@ -407,9 +410,11 @@ void __PHYSFS_platformTimeslice(void); * DirFunctions->enumerateFiles() method (see above), except that the * (dirName) that is passed to this function is converted to * platform-DEPENDENT notation by the caller. The DirFunctions version - * uses platform-independent notation. + * uses platform-independent notation. Note that ".", "..", and other + * metaentries should always be ignored. */ -LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname); +LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, + int omitSymLinks); /* diff --git a/platform/unix.c b/platform/unix.c index 549db270..6229ebd1 100644 --- a/platform/unix.c +++ b/platform/unix.c @@ -286,17 +286,40 @@ void __PHYSFS_platformTimeslice(void) } /* __PHYSFS_platformTimeslice */ -LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname) +LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, + int omitSymLinks) { LinkedStringList *retval = NULL; LinkedStringList *l = NULL; LinkedStringList *prev = NULL; DIR *dir; struct dirent *ent; + int bufsize = 0; + char *buf = NULL; + int dlen = 0; + + if (omitSymLinks) + { + dlen = strlen(dirname); + bufsize = dlen + 256; + buf = malloc(bufsize); + BAIL_IF_MACRO(buf == NULL, ERR_OUT_OF_MEMORY, NULL); + strcpy(buf, dirname); + if (buf[dlen - 1] != '/') + { + buf[dlen++] = '/'; + buf[dlen] = '\0'; + } /* if */ + } /* if */ errno = 0; dir = opendir(dirname); - BAIL_IF_MACRO(dir == NULL, strerror(errno), NULL); + if (dir == NULL) + { + if (buf != NULL) + free(buf); + BAIL_IF_MACRO(1, strerror(errno), NULL); + } /* if */ while (1) { @@ -310,6 +333,24 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname) if (strcmp(ent->d_name, "..") == 0) continue; + if (omitSymLinks) + { + char *p; + int len = strlen(ent->d_name) + dlen + 1; + if (len > bufsize) + { + p = realloc(buf, len); + if (p == NULL) + continue; + buf = p; + bufsize = len; + } /* if */ + + strcpy(buf + dlen, ent->d_name); + if (__PHYSFS_platformIsSymLink(buf)) + continue; + } /* if */ + l = (LinkedStringList *) malloc(sizeof (LinkedStringList)); if (l == NULL) break; @@ -333,6 +374,7 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname) } /* while */ closedir(dir); + free(buf); return(retval); } /* __PHYSFS_platformEnumerateFiles */