summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-06-28 05:30:06 (GMT)
committerGitHub <noreply@github.com>2017-06-28 05:30:06 (GMT)
commitf7eae0adfcd4c50034281b2c69f461b43b68db84 (patch)
tree02d6a582fd81f615e71c55365f1b37a774fc0a4e /Lib
parent592eda123329bb5ce2bffcbe3701be6b909f1b2a (diff)
downloadcpython-f7eae0adfcd4c50034281b2c69f461b43b68db84.zip
cpython-f7eae0adfcd4c50034281b2c69f461b43b68db84.tar.gz
cpython-f7eae0adfcd4c50034281b2c69f461b43b68db84.tar.bz2
[security] bpo-13617: Reject embedded null characters in wchar* strings. (#2302)
Based on patch by Victor Stinner. Add private C API function _PyUnicode_AsUnicode() which is similar to PyUnicode_AsUnicode(), but checks for null characters.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ctypes/test/test_loading.py2
-rw-r--r--Lib/test/test_builtin.py6
-rw-r--r--Lib/test/test_curses.py11
-rw-r--r--Lib/test/test_grp.py2
-rw-r--r--Lib/test/test_imp.py4
-rw-r--r--Lib/test/test_locale.py5
-rw-r--r--Lib/test/test_time.py4
-rw-r--r--Lib/test/test_winsound.py2
8 files changed, 35 insertions, 1 deletions
diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py
index 45571f3..f3b65b9 100644
--- a/Lib/ctypes/test/test_loading.py
+++ b/Lib/ctypes/test/test_loading.py
@@ -62,6 +62,8 @@ class LoaderTest(unittest.TestCase):
windll["kernel32"].GetModuleHandleW
windll.LoadLibrary("kernel32").GetModuleHandleW
WinDLL("kernel32").GetModuleHandleW
+ # embedded null character
+ self.assertRaises(ValueError, windll.LoadLibrary, "kernel32\0")
@unittest.skipUnless(os.name == "nt",
'test specific to Windows')
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 6613ca3..a83d20f 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -151,6 +151,8 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(TypeError, __import__, 1, 2, 3, 4)
self.assertRaises(ValueError, __import__, '')
self.assertRaises(TypeError, __import__, 'sys', name='sys')
+ # embedded null character
+ self.assertRaises(ModuleNotFoundError, __import__, 'string\x00')
def test_abs(self):
# int
@@ -1010,6 +1012,10 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(fp.read(300), 'XXX'*100)
self.assertEqual(fp.read(1000), 'YYY'*100)
+ # embedded null bytes and characters
+ self.assertRaises(ValueError, open, 'a\x00b')
+ self.assertRaises(ValueError, open, b'a\x00b')
+
def test_open_default_encoding(self):
old_environ = dict(os.environ)
try:
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index 3d8c50b..0d0b160 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -81,7 +81,7 @@ class TestCurses(unittest.TestCase):
win2 = curses.newwin(15,15, 5,5)
for meth in [stdscr.addch, stdscr.addstr]:
- for args in [('a'), ('a', curses.A_BOLD),
+ for args in [('a',), ('a', curses.A_BOLD),
(4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
with self.subTest(meth=meth.__qualname__, args=args):
meth(*args)
@@ -194,6 +194,15 @@ class TestCurses(unittest.TestCase):
self.assertRaises(ValueError, stdscr.instr, -2)
self.assertRaises(ValueError, stdscr.instr, 2, 3, -2)
+ def test_embedded_null_chars(self):
+ # reject embedded null bytes and characters
+ stdscr = self.stdscr
+ for arg in ['a', b'a']:
+ with self.subTest(arg=arg):
+ self.assertRaises(ValueError, stdscr.addstr, 'a\0')
+ self.assertRaises(ValueError, stdscr.addnstr, 'a\0', 1)
+ self.assertRaises(ValueError, stdscr.insstr, 'a\0')
+ self.assertRaises(ValueError, stdscr.insnstr, 'a\0', 1)
def test_module_funcs(self):
"Test module-level functions"
diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py
index 69095a3..e511947 100644
--- a/Lib/test/test_grp.py
+++ b/Lib/test/test_grp.py
@@ -50,6 +50,8 @@ class GroupDatabaseTestCase(unittest.TestCase):
self.assertRaises(TypeError, grp.getgrgid)
self.assertRaises(TypeError, grp.getgrnam)
self.assertRaises(TypeError, grp.getgrall, 42)
+ # embedded null character
+ self.assertRaises(ValueError, grp.getgrnam, 'a\x00b')
# try to get some errors
bynames = {}
diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py
index 4ece365..6f35f49 100644
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -314,6 +314,10 @@ class ImportTests(unittest.TestCase):
loader.get_data(imp.__file__) # File should be closed
loader.get_data(imp.__file__) # Will need to create a newly opened file
+ def test_load_source(self):
+ with self.assertRaisesRegex(ValueError, 'embedded null'):
+ imp.load_source(__name__, __file__ + "\0")
+
class ReloadTests(unittest.TestCase):
diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py
index 668f3cb..d93b3ad 100644
--- a/Lib/test/test_locale.py
+++ b/Lib/test/test_locale.py
@@ -346,9 +346,14 @@ class TestCollation(unittest.TestCase):
self.assertLess(locale.strcoll('a', 'b'), 0)
self.assertEqual(locale.strcoll('a', 'a'), 0)
self.assertGreater(locale.strcoll('b', 'a'), 0)
+ # embedded null character
+ self.assertRaises(ValueError, locale.strcoll, 'a\0', 'a')
+ self.assertRaises(ValueError, locale.strcoll, 'a', 'a\0')
def test_strxfrm(self):
self.assertLess(locale.strxfrm('a'), locale.strxfrm('b'))
+ # embedded null character
+ self.assertRaises(ValueError, locale.strxfrm, 'a\0')
class TestEnUSCollation(BaseLocalizedTest, TestCollation):
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index f224212..810ec37 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -126,6 +126,10 @@ class TimeTestCase(unittest.TestCase):
except ValueError:
self.fail('conversion specifier: %r failed.' % format)
+ self.assertRaises(TypeError, time.strftime, b'%S', tt)
+ # embedded null character
+ self.assertRaises(ValueError, time.strftime, '%S\0', tt)
+
def _bounds_checking(self, func):
# Make sure that strftime() checks the bounds of the various parts
# of the time tuple (0 is valid for *all* values).
diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py
index c86bf55..dca77cb 100644
--- a/Lib/test/test_winsound.py
+++ b/Lib/test/test_winsound.py
@@ -96,6 +96,8 @@ class PlaySoundTest(unittest.TestCase):
self.assertRaises(TypeError, winsound.PlaySound, "bad",
winsound.SND_MEMORY)
self.assertRaises(TypeError, winsound.PlaySound, 1, 0)
+ # embedded null character
+ self.assertRaises(ValueError, winsound.PlaySound, 'bad\0', 0)
def test_keyword_args(self):
safe_PlaySound(flags=winsound.SND_ALIAS, sound="SystemExit")