filesystem: Check SDL_GetPrefPath parameters at the higher level.

...so the backends don't have to do it.

Also added a stern warning about `org` being omitted, but leaving it as
allowed so as not to break existing apps (more than they are already broken,
at least).

Fixes #13322.
This commit is contained in:
Ryan C. Gordon
2025-07-22 12:28:01 -04:00
parent 279a50cc26
commit af1c05fd58
13 changed files with 22 additions and 102 deletions

View File

@@ -134,6 +134,12 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetBasePath(void);
* - ...only use letters, numbers, and spaces. Avoid punctuation like "Game * - ...only use letters, numbers, and spaces. Avoid punctuation like "Game
* Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. * Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient.
* *
* Due to historical mistakes, `org` is allowed to be NULL or "". In such
* cases, SDL will omit the org subdirectory, including on platforms where it
* shouldn't, and including on platforms where this would make your app fail
* certification for an app store. New apps should definitely specify a real
* string for `org`.
*
* The returned path is guaranteed to end with a path separator ('\\' on * The returned path is guaranteed to end with a path separator ('\\' on
* Windows, '/' on most other platforms). * Windows, '/' on most other platforms).
* *

View File

@@ -502,6 +502,16 @@ const char *SDL_GetUserFolder(SDL_Folder folder)
char *SDL_GetPrefPath(const char *org, const char *app) char *SDL_GetPrefPath(const char *org, const char *app)
{ {
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
// if org is NULL, just make it "" so backends don't have to check both.
if (!org) {
org = "";
}
return SDL_SYS_GetPrefPath(org, app); return SDL_SYS_GetPrefPath(org, app);
} }

View File

@@ -69,14 +69,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
char *result = NULL; char *result = NULL;
NSArray *array; NSArray *array;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
#ifndef SDL_PLATFORM_TVOS #ifndef SDL_PLATFORM_TVOS
array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
#else #else
@@ -106,13 +98,12 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
result = (char *)SDL_malloc(len); result = (char *)SDL_malloc(len);
if (result != NULL) { if (result != NULL) {
char *ptr;
if (*org) { if (*org) {
SDL_snprintf(result, len, "%s/%s/%s/", base, org, app); SDL_snprintf(result, len, "%s/%s/%s/", base, org, app);
} else { } else {
SDL_snprintf(result, len, "%s/%s/", base, app); SDL_snprintf(result, len, "%s/%s/", base, app);
} }
for (ptr = result + 1; *ptr; ptr++) { for (char *ptr = result + 1; *ptr; ptr++) {
if (*ptr == '/') { if (*ptr == '/') {
*ptr = '\0'; *ptr = '\0';
mkdir(result, 0700); mkdir(result, 0700);

View File

@@ -42,17 +42,7 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
const char *append = "/libsdl/"; const char *append = "/libsdl/";
char *result; char *result;
char *ptr = NULL; char *ptr = NULL;
size_t len = 0; const size_t len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
result = (char *)SDL_malloc(len); result = (char *)SDL_malloc(len);
if (!result) { if (!result) {
return NULL; return NULL;

View File

@@ -90,11 +90,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
HRESULT result; HRESULT result;
const char *csid = SDL_GetHint("SDL_GDK_SERVICE_CONFIGURATION_ID"); const char *csid = SDL_GetHint("SDL_GDK_SERVICE_CONFIGURATION_ID");
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
// This should be set before calling SDL_GetPrefPath! // This should be set before calling SDL_GetPrefPath!
if (!csid) { if (!csid) {
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "Set SDL_GDK_SERVICE_CONFIGURATION_ID before calling SDL_GetPrefPath!"); SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "Set SDL_GDK_SERVICE_CONFIGURATION_ID before calling SDL_GetPrefPath!");

View File

@@ -72,14 +72,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
const char *append = "/config/settings/"; const char *append = "/config/settings/";
size_t len = SDL_strlen(home); size_t len = SDL_strlen(home);
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
if (!len || (home[len - 1] == '/')) { if (!len || (home[len - 1] == '/')) {
++append; // home empty or ends with separator, skip the one from append ++append; // home empty or ends with separator, skip the one from append
} }

View File

@@ -43,11 +43,6 @@ char *SDL_SYS_GetBasePath(void)
char *SDL_SYS_GetPrefPath(const char *org, const char *app) char *SDL_SYS_GetPrefPath(const char *org, const char *app)
{ {
char *pref_path = NULL; char *pref_path = NULL;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
pref_path = MakePrefPath(app); pref_path = MakePrefPath(app);
if (!pref_path) { if (!pref_path) {
return NULL; return NULL;

View File

@@ -80,15 +80,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
char *result = NULL; char *result = NULL;
size_t len; size_t len;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
const char *base = SDL_GetBasePath(); const char *base = SDL_GetBasePath();
if (!base) { if (!base) {
return NULL; return NULL;
@@ -102,7 +93,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
} else { } else {
SDL_snprintf(result, len, "%s%s/", base, app); SDL_snprintf(result, len, "%s%s/", base, app);
} }
recursive_mkdir(result); recursive_mkdir(result);
} }

View File

@@ -49,22 +49,12 @@ char *SDL_SYS_GetBasePath(void)
char *SDL_SYS_GetPrefPath(const char *org, const char *app) char *SDL_SYS_GetPrefPath(const char *org, const char *app)
{ {
char *result = NULL; char *result = NULL;
size_t len;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
const char *base = SDL_GetBasePath(); const char *base = SDL_GetBasePath();
if (!base) { if (!base) {
return NULL; return NULL;
} }
if (!org) { const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
org = "";
}
len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4;
result = (char *)SDL_malloc(len); result = (char *)SDL_malloc(len);
if (result) { if (result) {
if (*org) { if (*org) {
@@ -72,7 +62,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
} else { } else {
SDL_snprintf(result, len, "%s%s/", base, app); SDL_snprintf(result, len, "%s%s/", base, app);
} }
mkdir(result, 0755); mkdir(result, 0755);
} }

View File

@@ -155,23 +155,14 @@ char *SDL_SYS_GetBasePath(void)
char *SDL_SYS_GetPrefPath(const char *org, const char *app) char *SDL_SYS_GetPrefPath(const char *org, const char *app)
{ {
char *canon, *dir, *result; char *canon, *dir, *result;
size_t len;
_kernel_oserror *error; _kernel_oserror *error;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
canon = canonicalisePath("<Choices$Write>", "Run$Path"); canon = canonicalisePath("<Choices$Write>", "Run$Path");
if (!canon) { if (!canon) {
return NULL; return NULL;
} }
len = SDL_strlen(canon) + SDL_strlen(org) + SDL_strlen(app) + 4; const size_t len = SDL_strlen(canon) + SDL_strlen(org) + SDL_strlen(app) + 4;
dir = (char *)SDL_malloc(len); dir = (char *)SDL_malloc(len);
if (!dir) { if (!dir) {
SDL_free(canon); SDL_free(canon);

View File

@@ -269,15 +269,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
const char *append; const char *append;
char *result = NULL; char *result = NULL;
char *ptr = NULL; char *ptr = NULL;
size_t len = 0;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
if (!envr) { if (!envr) {
// You end up with "$HOME/.local/share/Game Name 2" // You end up with "$HOME/.local/share/Game Name 2"
@@ -292,7 +283,7 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
append = "/"; append = "/";
} }
len = SDL_strlen(envr); size_t len = SDL_strlen(envr);
if (envr[len - 1] == '/') { if (envr[len - 1] == '/') {
append += 1; append += 1;
} }

View File

@@ -46,19 +46,7 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
const char *envr = "ux0:/data/"; const char *envr = "ux0:/data/";
char *result = NULL; char *result = NULL;
char *ptr = NULL; char *ptr = NULL;
size_t len = 0; size_t len = SDL_strlen(envr) + SDL_strlen(org) + SDL_strlen(app) + 3;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
len = SDL_strlen(envr);
len += SDL_strlen(org) + SDL_strlen(app) + 3;
result = (char *)SDL_malloc(len); result = (char *)SDL_malloc(len);
if (!result) { if (!result) {
return NULL; return NULL;

View File

@@ -110,14 +110,6 @@ char *SDL_SYS_GetPrefPath(const char *org, const char *app)
size_t new_wpath_len = 0; size_t new_wpath_len = 0;
BOOL api_result = FALSE; BOOL api_result = FALSE;
if (!app) {
SDL_InvalidParamError("app");
return NULL;
}
if (!org) {
org = "";
}
hr = SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path); hr = SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path);
if (!SUCCEEDED(hr)) { if (!SUCCEEDED(hr)) {
WIN_SetErrorFromHRESULT("Couldn't locate our prefpath", hr); WIN_SetErrorFromHRESULT("Couldn't locate our prefpath", hr);