Просмотр исходного кода

Architecture adjustment for enumerating files with regards to whether
symlinks are permitted.

Ryan C. Gordon 24 лет назад
Родитель
Сommit
c7fe9ab439
6 измененных файлов с 65 добавлено и 11 удалено
  1. 4 2
      archivers/dir.c
  2. 3 1
      archivers/grp.c
  3. 3 1
      archivers/zip.c
  4. 2 1
      physfs.c
  5. 9 4
      physfs_internal.h
  6. 44 2
      platform/unix.c

+ 4 - 2
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 */

+ 3 - 1
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);

+ 3 - 1
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;

+ 2 - 1
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 */

+ 9 - 4
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);
 
 
 /*

+ 44 - 2
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 */