Issue #13848: open() and the FileIO constructor now check for NUL characters in the file name.
Patch by Hynek Schlawack.
This commit is contained in:
commit
7ab4af0427
|
@ -1914,6 +1914,12 @@ PyAPI_FUNC(int) PyUnicode_Contains(
|
|||
PyObject *element /* Element string */
|
||||
);
|
||||
|
||||
/* Checks whether the string contains any NUL characters. */
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_FUNC(int) _PyUnicode_HasNULChars(PyObject *);
|
||||
#endif
|
||||
|
||||
/* Checks whether argument is a valid identifier. */
|
||||
|
||||
PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s);
|
||||
|
|
|
@ -306,6 +306,11 @@ class OtherFileTests(unittest.TestCase):
|
|||
finally:
|
||||
os.unlink(TESTFN)
|
||||
|
||||
def testConstructorHandlesNULChars(self):
|
||||
fn_with_NUL = 'foo\0bar'
|
||||
self.assertRaises(TypeError, _FileIO, fn_with_NUL, 'w')
|
||||
self.assertRaises(TypeError, _FileIO, bytes(fn_with_NUL, 'ascii'), 'w')
|
||||
|
||||
def testInvalidFd(self):
|
||||
self.assertRaises(ValueError, _FileIO, -10)
|
||||
self.assertRaises(OSError, _FileIO, make_bad_fd())
|
||||
|
|
|
@ -363,6 +363,11 @@ class IOTest(unittest.TestCase):
|
|||
self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR)
|
||||
self.assertRaises(exc, fp.seek, -1, self.SEEK_END)
|
||||
|
||||
def test_open_handles_NUL_chars(self):
|
||||
fn_with_NUL = 'foo\0bar'
|
||||
self.assertRaises(TypeError, self.open, fn_with_NUL, 'w')
|
||||
self.assertRaises(TypeError, self.open, bytes(fn_with_NUL, 'ascii'), 'w')
|
||||
|
||||
def test_raw_file_io(self):
|
||||
with self.open(support.TESTFN, "wb", buffering=0) as f:
|
||||
self.assertEqual(f.readable(), False)
|
||||
|
|
|
@ -461,6 +461,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #13848: open() and the FileIO constructor now check for NUL
|
||||
characters in the file name. Patch by Hynek Schlawack.
|
||||
|
||||
- Issue #13806: The size check in audioop decompression functions was too
|
||||
strict and could reject valid compressed data. Patch by Oleg Plakhotnyuk.
|
||||
|
||||
|
|
|
@ -258,6 +258,12 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
|
|||
|
||||
#ifdef MS_WINDOWS
|
||||
if (PyUnicode_Check(nameobj)) {
|
||||
int rv = _PyUnicode_HasNULChars(nameobj);
|
||||
if (rv) {
|
||||
if (rv != -1)
|
||||
PyErr_SetString(PyExc_TypeError, "embedded NUL character");
|
||||
return -1;
|
||||
}
|
||||
widename = PyUnicode_AsUnicode(nameobj);
|
||||
if (widename == NULL)
|
||||
return -1;
|
||||
|
@ -265,28 +271,10 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
|
|||
#endif
|
||||
if (fd < 0)
|
||||
{
|
||||
if (PyBytes_Check(nameobj) || PyByteArray_Check(nameobj)) {
|
||||
Py_ssize_t namelen;
|
||||
if (PyObject_AsCharBuffer(nameobj, &name, &namelen) < 0)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
PyObject *u = PyUnicode_FromObject(nameobj);
|
||||
|
||||
if (u == NULL)
|
||||
return -1;
|
||||
|
||||
stringobj = PyUnicode_EncodeFSDefault(u);
|
||||
Py_DECREF(u);
|
||||
if (stringobj == NULL)
|
||||
return -1;
|
||||
if (!PyBytes_Check(stringobj)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"encoder failed to return bytes");
|
||||
goto error;
|
||||
}
|
||||
name = PyBytes_AS_STRING(stringobj);
|
||||
if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
|
||||
return -1;
|
||||
}
|
||||
name = PyBytes_AS_STRING(stringobj);
|
||||
}
|
||||
|
||||
s = mode;
|
||||
|
|
|
@ -3574,6 +3574,19 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
_PyUnicode_HasNULChars(PyObject* s)
|
||||
{
|
||||
static PyObject *nul = NULL;
|
||||
|
||||
if (nul == NULL)
|
||||
nul = PyUnicode_FromStringAndSize("\0", 1);
|
||||
if (nul == NULL)
|
||||
return -1;
|
||||
return PyUnicode_Contains(s, nul);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyUnicode_FSConverter(PyObject* arg, void* addr)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue