Browse Source

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

This allows opening Unix device nodes, etc.

Fixes #15188.
Ryan C. Gordon 2 days ago
parent
commit
9f19cffc78
1 changed files with 11 additions and 14 deletions
  1. 11 14
      src/io/SDL_iostream.c

+ 11 - 14
src/io/SDL_iostream.c

@@ -970,16 +970,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)
@@ -1001,9 +998,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);
@@ -1032,9 +1029,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);
@@ -1098,9 +1095,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);
     }
@@ -1121,9 +1118,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);
         }