Browse Source

io: With stdio, only forbid opening directories as files.

This allows opening Unix device nodes, etc.

Fixes #15188.

(cherry picked from commit 9f19cffc787a715e6bf33fe0c5b6f9644bf563e6)
Ryan C. Gordon 6 days ago
parent
commit
a63fd07812
1 changed files with 11 additions and 14 deletions
  1. 11 14
      src/io/SDL_iostream.c

+ 11 - 14
src/io/SDL_iostream.c

@@ -861,16 +861,13 @@ static bool SDLCALL mem_close(void *userdata)
 #endif
 
 #if defined(HAVE_STDIO_H) && !defined(SKIP_STDIO_DIR_TEST)
-static bool IsRegularFileOrPipe(FILE *f)
+static bool IsStdioFileADirectory(FILE *f)
 {
     struct stat st;
-    if (fstat(fileno(f), &st) < 0 || !(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) {
-        return false;
-    }
-    return true;
+    return ((fstat(fileno(f), &st) == 0) && (S_ISDIR(st.st_mode)));
 }
 #else
-#define IsRegularFileOrPipe(f) false
+#define IsStdioFileADirectory(f) false
 #endif
 
 SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode)
@@ -892,9 +889,9 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode)
     if (*file == '/') {
         FILE *fp = fopen(file, mode);
         if (fp) {
-            if (!IsRegularFileOrPipe(fp)) {
+            if (IsStdioFileADirectory(fp)) {
                 fclose(fp);
-                SDL_SetError("%s is not a regular file or pipe", file);
+                SDL_SetError("%s is a directory", file);
                 return NULL;
             }
             return SDL_IOFromFP(fp, true);
@@ -923,9 +920,9 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode)
             FILE *fp = fopen(path, mode);
             SDL_free(path);
             if (fp) {
-                if (!IsRegularFileOrPipe(fp)) {
+                if (IsStdioFileADirectory(fp)) {
                     fclose(fp);
-                    SDL_SetError("%s is not a regular file or pipe", path);
+                    SDL_SetError("%s is a directory", path);
                     return NULL;
                 }
                 return SDL_IOFromFP(fp, true);
@@ -989,9 +986,9 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode)
 
     if (!fp) {
         SDL_SetError("Couldn't open %s: %s", file, strerror(errno));
-    } else if (!IsRegularFileOrPipe(fp)) {
+    } else if (IsStdioFileADirectory(fp)) {
         fclose(fp);
-        SDL_SetError("%s is not a regular file or pipe", file);
+        SDL_SetError("%s is a directory", file);
     } else {
         iostr = SDL_IOFromFP(fp, true);
     }
@@ -1012,9 +1009,9 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode)
 
         if (!fp) {
             SDL_SetError("Couldn't open %s: %s", file, strerror(errno));
-        } else if (!IsRegularFileOrPipe(fp)) {
+        } else if (IsStdioFileADirectory(fp)) {
             fclose(fp);
-            SDL_SetError("%s is not a regular file or pipe", file);
+            SDL_SetError("%s is a directory", file);
         } else {
             iostr = SDL_IOFromFP(fp, true);
         }