فهرست منبع

Make sure base dir always has a dirsep at the end of it.

Now the higher level doesn't have to check for this and realloc the string.
Ryan C. Gordon 14 سال پیش
والد
کامیت
9d01a645ed
7فایلهای تغییر یافته به همراه30 افزوده شده و 11 حذف شده
  1. 0 1
      docs/TODO.txt
  2. 3 2
      src/physfs.c
  3. 1 0
      src/physfs_internal.h
  4. 2 1
      src/platform_beos.cpp
  5. 7 2
      src/platform_macosx.c
  6. 7 3
      src/platform_unix.c
  7. 10 2
      src/platform_windows.c

+ 0 - 1
docs/TODO.txt

@@ -75,7 +75,6 @@ Other stuff I thought of...
 - bzip2 support in zip archiver?
 - bzip2 support in zip archiver?
 - rewrite 7zip archiver.
 - rewrite 7zip archiver.
 - ryanify iso9660 code.
 - ryanify iso9660 code.
-- Cache basedir/userdir results (do we do this already?)
 - Reduce the BAIL and GOTO macro use. A lot of these don't add anything.
 - Reduce the BAIL and GOTO macro use. A lot of these don't add anything.
 
 
 Probably other stuff. Requests and recommendations are welcome.
 Probably other stuff. Requests and recommendations are welcome.

+ 3 - 2
src/physfs.c

@@ -1147,7 +1147,7 @@ static char *calculateBaseDir(const char *argv0)
     ptr = strrchr(argv0, dirsep);
     ptr = strrchr(argv0, dirsep);
     if (ptr != NULL)
     if (ptr != NULL)
     {
     {
-        const size_t size = (size_t) (ptr - argv0);
+        const size_t size = ((size_t) (ptr - argv0)) + 1;
         retval = (char *) allocator.Malloc(size + 1);
         retval = (char *) allocator.Malloc(size + 1);
         BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
         BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
         memcpy(retval, argv0, size);
         memcpy(retval, argv0, size);
@@ -1203,7 +1203,8 @@ int PHYSFS_init(const char *argv0)
     baseDir = calculateBaseDir(argv0);
     baseDir = calculateBaseDir(argv0);
     BAIL_IF_MACRO(!baseDir, ERRPASS, 0);
     BAIL_IF_MACRO(!baseDir, ERRPASS, 0);
 
 
-    BAIL_IF_MACRO(!appendDirSep(&baseDir), ERRPASS, 0);
+    /* Platform layer is required to append a dirsep. */
+    assert(baseDir[strlen(baseDir) - 1] == __PHYSFS_platformDirSeparator);
 
 
     userDir = __PHYSFS_platformCalcUserDir();
     userDir = __PHYSFS_platformCalcUserDir();
     if ((!userDir) || (!appendDirSep(&userDir)))
     if ((!userDir) || (!appendDirSep(&userDir)))

+ 1 - 0
src/physfs_internal.h

@@ -634,6 +634,7 @@ void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data);
  * Calculate the base dir, if your platform needs special consideration.
  * Calculate the base dir, if your platform needs special consideration.
  *  Just return NULL if the standard routines will suffice. (see
  *  Just return NULL if the standard routines will suffice. (see
  *  calculateBaseDir() in physfs.c ...)
  *  calculateBaseDir() in physfs.c ...)
+ * Your string must end with a dir separator if you don't return NULL.
  *  Caller will allocator.Free() the retval if it's not NULL.
  *  Caller will allocator.Free() the retval if it's not NULL.
  */
  */
 char *__PHYSFS_platformCalcBaseDir(const char *argv0);
 char *__PHYSFS_platformCalcBaseDir(const char *argv0);

+ 2 - 1
src/platform_beos.cpp

@@ -176,9 +176,10 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
     assert(rc == B_OK);
     assert(rc == B_OK);
     const char *str = path.Path();
     const char *str = path.Path();
     assert(str != NULL);
     assert(str != NULL);
-    char *retval = (char *) allocator.Malloc(strlen(str) + 1);
+    char *retval = (char *) allocator.Malloc(strlen(str) + 2);
     BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
     BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
     strcpy(retval, str);
     strcpy(retval, str);
+    strcat(retval, "/");
     return retval;
     return retval;
 } /* __PHYSFS_platformCalcBaseDir */
 } /* __PHYSFS_platformCalcBaseDir */
 
 

+ 7 - 2
src/platform_macosx.c

@@ -268,18 +268,23 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
             return NULL;
             return NULL;
         } /* if */
         } /* if */
 
 
-        /* chop the "/exename" from the end of the path string... */
+        /* chop the "exename" from the end of the path string (leave '/')... */
+        cfrange.location++;
         cfrange.length = CFStringGetLength(cfmutstr) - cfrange.location;
         cfrange.length = CFStringGetLength(cfmutstr) - cfrange.location;
         CFStringDelete(cfmutstr, cfrange);
         CFStringDelete(cfmutstr, cfrange);
 
 
         /* If we're an Application Bundle, chop everything but the base. */
         /* If we're an Application Bundle, chop everything but the base. */
-        cfrange = CFStringFind(cfmutstr, CFSTR("/Contents/MacOS"),
+        cfrange = CFStringFind(cfmutstr, CFSTR("/Contents/MacOS/"),
                                kCFCompareCaseInsensitive |
                                kCFCompareCaseInsensitive |
                                kCFCompareBackwards |
                                kCFCompareBackwards |
                                kCFCompareAnchored);
                                kCFCompareAnchored);
 
 
         if (cfrange.location != kCFNotFound)
         if (cfrange.location != kCFNotFound)
+        {
+            cfrange.location++;  /* leave the trailing '/' char ... */
+            cfrange.length--;
             CFStringDelete(cfmutstr, cfrange);  /* chop that, too. */
             CFStringDelete(cfmutstr, cfrange);  /* chop that, too. */
+        } /* if */
     } /* if */
     } /* if */
 
 
     retval = convertCFString(cfmutstr);
     retval = convertCFString(cfmutstr);

+ 7 - 3
src/platform_unix.c

@@ -167,11 +167,14 @@ static char *findBinaryInPath(const char *bin, char *envr)
     do
     do
     {
     {
         size_t size;
         size_t size;
+        size_t binlen;
+
         ptr = strchr(start, ':');  /* find next $PATH separator. */
         ptr = strchr(start, ':');  /* find next $PATH separator. */
         if (ptr)
         if (ptr)
             *ptr = '\0';
             *ptr = '\0';
 
 
-        size = strlen(start) + strlen(bin) + 2;
+        binlen = strlen(bin);
+        size = strlen(start) + binlen + 2;
         if (size > alloc_size)
         if (size > alloc_size)
         {
         {
             char *x = (char *) allocator.Realloc(exe, size);
             char *x = (char *) allocator.Realloc(exe, size);
@@ -194,7 +197,7 @@ static char *findBinaryInPath(const char *bin, char *envr)
 
 
         if (access(exe, X_OK) == 0)  /* Exists as executable? We're done. */
         if (access(exe, X_OK) == 0)  /* Exists as executable? We're done. */
         {
         {
-            strcpy(exe, start);  /* i'm lazy. piss off. */
+            exe[size - binlen] = '\0'; /* chop off filename, leave '/' */
             return exe;
             return exe;
         } /* if */
         } /* if */
 
 
@@ -269,12 +272,13 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
     {
     {
         char *ptr = strrchr(retval, '/');
         char *ptr = strrchr(retval, '/');
         if (ptr != NULL)
         if (ptr != NULL)
-            *ptr = '\0';
+            *(ptr+1) = '\0';
     } /* if */
     } /* if */
 
 
     if ((retval == NULL) && (argv0 != NULL))
     if ((retval == NULL) && (argv0 != NULL))
     {
     {
         /* If there's no dirsep on argv0, then look through $PATH for it. */
         /* If there's no dirsep on argv0, then look through $PATH for it. */
+        /* !!! FIXME: smallAlloc? */
         envr = __PHYSFS_platformCopyEnvironmentVariable("PATH");
         envr = __PHYSFS_platformCopyEnvironmentVariable("PATH");
         BAIL_IF_MACRO(!envr, ERRPASS, NULL);
         BAIL_IF_MACRO(!envr, ERRPASS, NULL);
         retval = findBinaryInPath(argv0, envr);
         retval = findBinaryInPath(argv0, envr);

+ 10 - 2
src/platform_windows.c

@@ -372,7 +372,7 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
             __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR);  /* oh well. */
             __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR);  /* oh well. */
         else
         else
         {
         {
-            *(ptr + 1) = '\0';  /* chop off filename. */
+            *(ptr+1) = '\0';  /* chop off filename. */
             retval = unicodeToUtf8Heap(modpath);
             retval = unicodeToUtf8Heap(modpath);
         } /* else */
         } /* else */
     } /* else */
     } /* else */
@@ -448,11 +448,19 @@ char *__PHYSFS_platformCalcUserDir(void)
         (void) rc;
         (void) rc;
 
 
         /* Allocate memory for the profile directory */
         /* Allocate memory for the profile directory */
-        wstr = (LPWSTR) __PHYSFS_smallAlloc(psize * sizeof (WCHAR));
+        wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR));
         if (wstr != NULL)
         if (wstr != NULL)
         {
         {
             if (pGetDir(accessToken, wstr, &psize))
             if (pGetDir(accessToken, wstr, &psize))
+            {
+                /* Make sure it ends in a dirsep. We allocated +1 for this. */
+                if (wstr[psize - 2] != '\\')
+                {
+                    wstr[psize - 1] = '\\';
+                    wstr[psize - 0] = '\0';
+                } /* if */
                 retval = unicodeToUtf8Heap(wstr);
                 retval = unicodeToUtf8Heap(wstr);
+            } /* if */
             __PHYSFS_smallFree(wstr);
             __PHYSFS_smallFree(wstr);
         } /* if */
         } /* if */