Skip to content

Commit 398b9f6

Browse files
committed
Disallow open()ing of directories. Closes SF bug 487277.
1 parent 07c57d4 commit 398b9f6

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

Objects/fileobject.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,32 @@ PyFile_Name(PyObject *f)
5656
return ((PyFileObject *)f)->f_name;
5757
}
5858

59+
/* On Unix, fopen will succeed for directories.
60+
In Python, there should be no file objects referring to
61+
directories, so we need a check. */
62+
63+
static PyFileObject*
64+
dircheck(PyFileObject* f)
65+
{
66+
#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
67+
struct stat buf;
68+
if (f->f_fp == NULL)
69+
return f;
70+
if (fstat(fileno(f->f_fp), &buf) == 0 &&
71+
S_ISDIR(buf.st_mode)) {
72+
#ifdef HAVE_STRERROR
73+
char *msg = strerror(EISDIR);
74+
#else
75+
char *msg = "Is a directory";
76+
#endif
77+
PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(is)", EISDIR, msg);
78+
PyErr_SetObject(PyExc_IOError, exc);
79+
return NULL;
80+
}
81+
#endif
82+
return f;
83+
}
84+
5985

6086
static PyObject *
6187
fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode,
@@ -77,6 +103,7 @@ fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode,
77103
if (f->f_name == NULL || f->f_mode == NULL)
78104
return NULL;
79105
f->f_fp = fp;
106+
f = dircheck(f);
80107
return (PyObject *) f;
81108
}
82109

@@ -130,6 +157,7 @@ open_the_file(PyFileObject *f, char *name, char *mode)
130157
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
131158
f = NULL;
132159
}
160+
f = dircheck(f);
133161
return (PyObject *)f;
134162
}
135163

0 commit comments

Comments
 (0)