From 019dc53764d77a5cafbe95283ae2593f7bd848e7 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 28 Jan 2024 01:44:50 +0300 Subject: [PATCH] SDL_RWFromFile, stdio: reject if the file is not a regular file. Fixes https://github.com/libsdl-org/SDL/issues/8935 (cherry picked from commit 230ae797a7406358b7fcf74701d39b5f342f9807) --- src/file/SDL_rwops.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 7c3c34d868..18a389a00b 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -26,6 +26,7 @@ #ifdef HAVE_STDIO_H #include +#include #endif #ifdef HAVE_LIMITS_H #include @@ -459,6 +460,24 @@ static size_t SDLCALL mem_write(SDL_RWops *context, const void *ptr, size_t size /* Functions to create SDL_RWops structures from various data sources */ +#if defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINDOWS) +static SDL_bool SDL_IsRegularFile(FILE *f) +{ + #ifdef SDL_PLATFORM_WINRT + struct __stat64 st; + if (_fstat64(_fileno(f), &st) < 0 || !S_ISREG(st.st_mode)) { + return SDL_FALSE; + } + #else + struct stat st; + if (fstat(fileno(f), &st) < 0 || !S_ISREG(st.st_mode)) { + return SDL_FALSE; + } + #endif + return SDL_TRUE; +} +#endif + SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) { SDL_RWops *rwops = NULL; @@ -472,6 +491,11 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) if (*file == '/') { FILE *fp = fopen(file, mode); if (fp) { + if (!SDL_IsRegularFile(fp)) { + fclose(fp); + SDL_SetError("%s is not a regular file", file); + return NULL; + } return SDL_RWFromFP(fp, 1); } } else { @@ -487,6 +511,11 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) fp = fopen(path, mode); SDL_stack_free(path); if (fp) { + if (!SDL_IsRegularFile(fp)) { + fclose(fp); + SDL_SetError("%s is not a regular file", path); + return NULL; + } return SDL_RWFromFP(fp, 1); } } @@ -540,6 +569,10 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) #endif if (!fp) { SDL_SetError("Couldn't open %s", file); + } else if (!SDL_IsRegularFile(fp)) { + fclose(fp); + fp = NULL; + SDL_SetError("%s is not a regular file", file); } else { rwops = SDL_RWFromFP(fp, SDL_TRUE); }