From: Serhiy Storchaka Date: Mon, 20 Apr 2015 07:12:28 +0000 (+0300) Subject: Issue #23908: os functions now reject paths with embedded null character X-Git-Tag: v3.5.0b1~320^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7e9d1d1a1b8ec4db9b9b6789b448c4202ab84b48;p=python Issue #23908: os functions now reject paths with embedded null character on Windows instead of silently truncate them. Removed no longer used _PyUnicode_HasNULChars(). --- 7e9d1d1a1b8ec4db9b9b6789b448c4202ab84b48 diff --cc Include/unicodeobject.h index 814d7c0cf6,d7b2acebde..4ba632803c --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@@ -2060,12 -2060,12 +2060,6 @@@ 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); diff --cc Lib/test/test_posix.py index d49cd92c77,aeb8924107..77e5b0c4fd --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@@ -1168,6 -1169,42 +1168,42 @@@ class PosixTester(unittest.TestCase) else: self.fail("No valid path_error2() test for os." + name) + def test_path_with_null_character(self): + fn = support.TESTFN + fn_with_NUL = fn + '\0' + self.addCleanup(support.unlink, fn) + support.unlink(fn) + fd = None + try: - with self.assertRaises(TypeError): ++ with self.assertRaises(ValueError): + fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises + finally: + if fd is not None: + os.close(fd) + self.assertFalse(os.path.exists(fn)) - self.assertRaises(TypeError, os.mkdir, fn_with_NUL) ++ self.assertRaises(ValueError, os.mkdir, fn_with_NUL) + self.assertFalse(os.path.exists(fn)) + open(fn, 'wb').close() - self.assertRaises(TypeError, os.stat, fn_with_NUL) ++ self.assertRaises(ValueError, os.stat, fn_with_NUL) + + def test_path_with_null_byte(self): + fn = os.fsencode(support.TESTFN) + fn_with_NUL = fn + b'\0' + self.addCleanup(support.unlink, fn) + support.unlink(fn) + fd = None + try: + with self.assertRaises(ValueError): + fd = os.open(fn_with_NUL, os.O_WRONLY | os.O_CREAT) # raises + finally: + if fd is not None: + os.close(fd) + self.assertFalse(os.path.exists(fn)) + self.assertRaises(ValueError, os.mkdir, fn_with_NUL) + self.assertFalse(os.path.exists(fn)) + open(fn, 'wb').close() + self.assertRaises(ValueError, os.stat, fn_with_NUL) + class PosixGroupsTester(unittest.TestCase): def setUp(self): diff --cc Modules/_io/fileio.c index 145d93adeb,74508a7f42..0894ca45c8 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@@ -281,15 -275,14 +281,14 @@@ _io_FileIO___init___impl(fileio *self, #ifdef MS_WINDOWS if (PyUnicode_Check(nameobj)) { - int rv = _PyUnicode_HasNULChars(nameobj); - if (rv) { - if (rv != -1) - PyErr_SetString(PyExc_ValueError, "embedded null character"); - return -1; - } - widename = PyUnicode_AsUnicode(nameobj); + Py_ssize_t length; + widename = PyUnicode_AsUnicodeAndSize(nameobj, &length); if (widename == NULL) return -1; + if (wcslen(widename) != length) { - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); ++ PyErr_SetString(PyExc_ValueError, "embedded null character"); + return -1; + } } else #endif if (fd < 0) diff --cc Modules/posixmodule.c index 89fb08b674,e538437941..90d820fa81 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@@ -866,6 -858,11 +866,11 @@@ path_converter(PyObject *o, void *p) Py_DECREF(unicode); return 0; } + if (wcslen(wide) != length) { - FORMAT_EXCEPTION(PyExc_TypeError, "embedded null character"); ++ FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character"); + Py_DECREF(unicode); + return 0; + } path->wide = wide; path->narrow = NULL; diff --cc Objects/unicodeobject.c index 9611ed41f7,b425e43289..3225fb3be9 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@@ -3606,21 -3642,21 +3606,6 @@@ PyUnicode_DecodeFSDefaultAndSize(const } --int --_PyUnicode_HasNULChars(PyObject* str) --{ -- Py_ssize_t pos; -- -- if (PyUnicode_READY(str) == -1) -- return -1; -- pos = findchar(PyUnicode_DATA(str), PyUnicode_KIND(str), -- PyUnicode_GET_LENGTH(str), '\0', 1); -- if (pos == -1) -- return 0; -- else -- return 1; --} -- int PyUnicode_FSConverter(PyObject* arg, void* addr) {