Skip to content

Commit

Permalink
Fixed bug 3639 - SDL_GetPrefPath returns a path with two consecutive …
Browse files Browse the repository at this point in the history
…slashes on Unix if org is omitted

Fabian Greffrath

we use SDL_GetPrefPath() in Chocolate Doom to get a reasonable directory to save and restore config files and savegames:

https://github.com/chocolate-doom/chocolate-doom/blob/sdl2-branch/src/m_config.c#L2162

However, since there is no "organization" behind Chocolate Doom and there is really only one "product" called Chocolate Doom, we pass an empty string for the org parameter and the package string for app.

This leads to two consecutive slashes in the path returned by SDL_GetPrefPath() like this:

/home/user/.local/share//chocolate-doom/

While this is harmless, it sure looks bad.

I believe that it should be possible to either pass a NULL pointer for the org parameter or at least have the function detect an empty string as a means to express "there is no origanization, just a single product". The generation of the path string to be returned by the function will have to get adapted accordingly.
  • Loading branch information
slouken committed Aug 11, 2017
1 parent 3c85236 commit 658975f
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 10 deletions.
15 changes: 13 additions & 2 deletions src/filesystem/cocoa/SDL_sysfilesystem.m
Expand Up @@ -71,8 +71,15 @@
SDL_GetPrefPath(const char *org, const char *app)
{ @autoreleasepool
{
char *retval = NULL;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}

char *retval = NULL;
NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);

if ([array count] > 0) { /* we only want the first item in the list. */
Expand All @@ -85,7 +92,11 @@
SDL_OutOfMemory();
} else {
char *ptr;
SDL_snprintf(retval, len, "%s/%s/%s/", base, org, app);
if (*org) {
SDL_snprintf(retval, len, "%s/%s/%s/", base, org, app);
} else {
SDL_snprintf(retval, len, "%s/%s/", base, app);
}
for (ptr = retval+1; *ptr; ptr++) {
if (*ptr == '/') {
*ptr = '\0';
Expand Down
14 changes: 13 additions & 1 deletion src/filesystem/emscripten/SDL_sysfilesystem.c
Expand Up @@ -46,14 +46,26 @@ SDL_GetPrefPath(const char *org, const char *app)
char *retval;
size_t len = 0;

if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}

len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
retval = (char *) SDL_malloc(len);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}

SDL_snprintf(retval, len, "%s%s/%s/", append, org, app);
if (*org) {
SDL_snprintf(retval, len, "%s%s/%s/", append, org, app);
} else {
SDL_snprintf(retval, len, "%s%s/", append, app);
}

if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
SDL_SetError("Couldn't create directory '%s': '%s'", retval, strerror(errno));
Expand Down
15 changes: 14 additions & 1 deletion src/filesystem/haiku/SDL_sysfilesystem.cc
Expand Up @@ -77,6 +77,15 @@ SDL_GetPrefPath(const char *org, const char *app)
const char *home = SDL_getenv("HOME");
const char *append = "/config/settings/";
size_t len = SDL_strlen(home);

if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}

if (!len || (home[len - 1] == '/')) {
++append; // home empty or ends with separator, skip the one from append
}
Expand All @@ -85,7 +94,11 @@ SDL_GetPrefPath(const char *org, const char *app)
if (!retval) {
SDL_OutOfMemory();
} else {
SDL_snprintf(retval, len, "%s%s%s/%s/", home, append, org, app);
if (*org) {
SDL_snprintf(retval, len, "%s%s%s/%s/", home, append, org, app);
} else {
SDL_snprintf(retval, len, "%s%s%s/", home, append, app);
}
create_directory(retval, 0700); // Haiku api: creates missing dirs
}

Expand Down
1 change: 1 addition & 0 deletions src/filesystem/nacl/SDL_sysfilesystem.c
Expand Up @@ -40,3 +40,4 @@ SDL_GetPrefPath(const char *org, const char *app)

#endif /* SDL_FILESYSTEM_NACL */

/* vi: set ts=4 sw=4 expandtab: */
14 changes: 13 additions & 1 deletion src/filesystem/unix/SDL_sysfilesystem.c
Expand Up @@ -180,6 +180,14 @@ SDL_GetPrefPath(const char *org, const char *app)
char *ptr = NULL;
size_t len = 0;

if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}

if (!envr) {
/* You end up with "$HOME/.local/share/Game Name 2" */
envr = SDL_getenv("HOME");
Expand All @@ -204,7 +212,11 @@ SDL_GetPrefPath(const char *org, const char *app)
return NULL;
}

SDL_snprintf(retval, len, "%s%s%s/%s/", envr, append, org, app);
if (*org) {
SDL_snprintf(retval, len, "%s%s%s/%s/", envr, append, org, app);
} else {
SDL_snprintf(retval, len, "%s%s%s/", envr, append, app);
}

for (ptr = retval+1; *ptr; ptr++) {
if (*ptr == '/') {
Expand Down
14 changes: 12 additions & 2 deletions src/filesystem/windows/SDL_sysfilesystem.c
Expand Up @@ -118,6 +118,14 @@ SDL_GetPrefPath(const char *org, const char *app)
size_t new_wpath_len = 0;
BOOL api_result = FALSE;

if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}

if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) {
WIN_SetError("Couldn't locate our prefpath");
return NULL;
Expand Down Expand Up @@ -145,8 +153,10 @@ SDL_GetPrefPath(const char *org, const char *app)
return NULL;
}

lstrcatW(path, L"\\");
lstrcatW(path, worg);
if (*worg) {
lstrcatW(path, L"\\");
lstrcatW(path, worg);
}
SDL_free(worg);

api_result = CreateDirectoryW(path, NULL);
Expand Down
18 changes: 15 additions & 3 deletions src/filesystem/winrt/SDL_sysfilesystem.cpp
Expand Up @@ -152,6 +152,14 @@ SDL_GetPrefPath(const char *org, const char *app)
size_t new_wpath_len = 0;
BOOL api_result = FALSE;

if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}

srcPath = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_LOCAL_FOLDER);
if ( ! srcPath) {
SDL_SetError("Unable to find a source path");
Expand Down Expand Up @@ -186,9 +194,11 @@ SDL_GetPrefPath(const char *org, const char *app)
return NULL;
}

SDL_wcslcat(path, L"\\", new_wpath_len + 1);
SDL_wcslcat(path, worg, new_wpath_len + 1);
SDL_free(worg);
if (*worg) {
SDL_wcslcat(path, L"\\", new_wpath_len + 1);
SDL_wcslcat(path, worg, new_wpath_len + 1);
SDL_free(worg);
}

api_result = CreateDirectoryW(path, NULL);
if (api_result == FALSE) {
Expand Down Expand Up @@ -219,3 +229,5 @@ SDL_GetPrefPath(const char *org, const char *app)
}

#endif /* __WINRT__ */

/* vi: set ts=4 sw=4 expandtab: */
9 changes: 9 additions & 0 deletions test/testfilesystem.c
Expand Up @@ -46,6 +46,15 @@ main(int argc, char *argv[])
SDL_Log("pref path: '%s'\n", pref_path);
SDL_free(pref_path);

pref_path = SDL_GetPrefPath(NULL, "testfilesystem");
if(pref_path == NULL){
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find pref path without organization: %s\n",
SDL_GetError());
return 1;
}
SDL_Log("pref path: '%s'\n", pref_path);
SDL_free(pref_path);

SDL_Quit();
return 0;
}

0 comments on commit 658975f

Please sign in to comment.