From 9d01a645edb1f312b419f850f0d5754d715d42a9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 23 Mar 2012 04:14:01 -0400 Subject: [PATCH] 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. --- docs/TODO.txt | 1 - src/physfs.c | 5 +++-- src/physfs_internal.h | 1 + src/platform_beos.cpp | 3 ++- src/platform_macosx.c | 9 +++++++-- src/platform_unix.c | 10 +++++++--- src/platform_windows.c | 12 ++++++++++-- 7 files changed, 30 insertions(+), 11 deletions(-) diff --git a/docs/TODO.txt b/docs/TODO.txt index fabaef67..1d2f0d3c 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -75,7 +75,6 @@ Other stuff I thought of... - bzip2 support in zip archiver? - rewrite 7zip archiver. - 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. Probably other stuff. Requests and recommendations are welcome. diff --git a/src/physfs.c b/src/physfs.c index 6fe11ba1..6bbe451c 100644 --- a/src/physfs.c +++ b/src/physfs.c @@ -1147,7 +1147,7 @@ static char *calculateBaseDir(const char *argv0) ptr = strrchr(argv0, dirsep); 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); BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL); memcpy(retval, argv0, size); @@ -1203,7 +1203,8 @@ int PHYSFS_init(const char *argv0) baseDir = calculateBaseDir(argv0); 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(); if ((!userDir) || (!appendDirSep(&userDir))) diff --git a/src/physfs_internal.h b/src/physfs_internal.h index 8421e54e..ba75f0b1 100644 --- a/src/physfs_internal.h +++ b/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. * Just return NULL if the standard routines will suffice. (see * 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. */ char *__PHYSFS_platformCalcBaseDir(const char *argv0); diff --git a/src/platform_beos.cpp b/src/platform_beos.cpp index 8921de70..437b5473 100644 --- a/src/platform_beos.cpp +++ b/src/platform_beos.cpp @@ -176,9 +176,10 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0) assert(rc == B_OK); const char *str = path.Path(); 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); strcpy(retval, str); + strcat(retval, "/"); return retval; } /* __PHYSFS_platformCalcBaseDir */ diff --git a/src/platform_macosx.c b/src/platform_macosx.c index 380e7471..187916a8 100644 --- a/src/platform_macosx.c +++ b/src/platform_macosx.c @@ -268,18 +268,23 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0) return NULL; } /* 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; CFStringDelete(cfmutstr, cfrange); /* If we're an Application Bundle, chop everything but the base. */ - cfrange = CFStringFind(cfmutstr, CFSTR("/Contents/MacOS"), + cfrange = CFStringFind(cfmutstr, CFSTR("/Contents/MacOS/"), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareAnchored); if (cfrange.location != kCFNotFound) + { + cfrange.location++; /* leave the trailing '/' char ... */ + cfrange.length--; CFStringDelete(cfmutstr, cfrange); /* chop that, too. */ + } /* if */ } /* if */ retval = convertCFString(cfmutstr); diff --git a/src/platform_unix.c b/src/platform_unix.c index 93b5fde7..bb73cbef 100644 --- a/src/platform_unix.c +++ b/src/platform_unix.c @@ -167,11 +167,14 @@ static char *findBinaryInPath(const char *bin, char *envr) do { size_t size; + size_t binlen; + ptr = strchr(start, ':'); /* find next $PATH separator. */ if (ptr) *ptr = '\0'; - size = strlen(start) + strlen(bin) + 2; + binlen = strlen(bin); + size = strlen(start) + binlen + 2; if (size > alloc_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. */ { - strcpy(exe, start); /* i'm lazy. piss off. */ + exe[size - binlen] = '\0'; /* chop off filename, leave '/' */ return exe; } /* if */ @@ -269,12 +272,13 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0) { char *ptr = strrchr(retval, '/'); if (ptr != NULL) - *ptr = '\0'; + *(ptr+1) = '\0'; } /* if */ if ((retval == NULL) && (argv0 != NULL)) { /* If there's no dirsep on argv0, then look through $PATH for it. */ + /* !!! FIXME: smallAlloc? */ envr = __PHYSFS_platformCopyEnvironmentVariable("PATH"); BAIL_IF_MACRO(!envr, ERRPASS, NULL); retval = findBinaryInPath(argv0, envr); diff --git a/src/platform_windows.c b/src/platform_windows.c index 3cbd44be..f6079b6f 100644 --- a/src/platform_windows.c +++ b/src/platform_windows.c @@ -372,7 +372,7 @@ char *__PHYSFS_platformCalcBaseDir(const char *argv0) __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR); /* oh well. */ else { - *(ptr + 1) = '\0'; /* chop off filename. */ + *(ptr+1) = '\0'; /* chop off filename. */ retval = unicodeToUtf8Heap(modpath); } /* else */ } /* else */ @@ -448,11 +448,19 @@ char *__PHYSFS_platformCalcUserDir(void) (void) rc; /* 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 (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); + } /* if */ __PHYSFS_smallFree(wstr); } /* if */