Commit 1317e144 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #20368: The null character now correctly passed from Tcl to Python.

Improved error handling in variables-related commands.
parent fc055252
...@@ -55,6 +55,10 @@ class TclTest(unittest.TestCase): ...@@ -55,6 +55,10 @@ class TclTest(unittest.TestCase):
tcl.eval('set a 1') tcl.eval('set a 1')
self.assertEqual(tcl.eval('set a'),'1') self.assertEqual(tcl.eval('set a'),'1')
def test_eval_null_in_result(self):
tcl = self.interp
self.assertEqual(tcl.eval('set a "a\\0b"'), 'a\x00b')
def testEvalException(self): def testEvalException(self):
tcl = self.interp tcl = self.interp
self.assertRaises(TclError,tcl.eval,'set a') self.assertRaises(TclError,tcl.eval,'set a')
...@@ -127,20 +131,29 @@ class TclTest(unittest.TestCase): ...@@ -127,20 +131,29 @@ class TclTest(unittest.TestCase):
def testEvalFile(self): def testEvalFile(self):
tcl = self.interp tcl = self.interp
filename = "testEvalFile.tcl" with open(support.TESTFN, 'w') as f:
fd = open(filename,'w') self.addCleanup(support.unlink, support.TESTFN)
script = """set a 1 f.write("""set a 1
set b 2 set b 2
set c [ expr $a + $b ] set c [ expr $a + $b ]
""" """)
fd.write(script) tcl.evalfile(support.TESTFN)
fd.close()
tcl.evalfile(filename)
os.remove(filename)
self.assertEqual(tcl.eval('set a'),'1') self.assertEqual(tcl.eval('set a'),'1')
self.assertEqual(tcl.eval('set b'),'2') self.assertEqual(tcl.eval('set b'),'2')
self.assertEqual(tcl.eval('set c'),'3') self.assertEqual(tcl.eval('set c'),'3')
def test_evalfile_null_in_result(self):
tcl = self.interp
with open(support.TESTFN, 'w') as f:
self.addCleanup(support.unlink, support.TESTFN)
f.write("""
set a "a\0b"
set b "a\\0b"
""")
tcl.evalfile(support.TESTFN)
self.assertEqual(tcl.eval('set a'), 'a\x00b')
self.assertEqual(tcl.eval('set b'), 'a\x00b')
def testEvalFileException(self): def testEvalFileException(self):
tcl = self.interp tcl = self.interp
filename = "doesnotexists" filename = "doesnotexists"
...@@ -209,6 +222,7 @@ class TclTest(unittest.TestCase): ...@@ -209,6 +222,7 @@ class TclTest(unittest.TestCase):
check('"abc"', 'abc') check('"abc"', 'abc')
check('"a\xbd\u20ac"', 'a\xbd\u20ac') check('"a\xbd\u20ac"', 'a\xbd\u20ac')
check(r'"a\xbd\u20ac"', 'a\xbd\u20ac') check(r'"a\xbd\u20ac"', 'a\xbd\u20ac')
check(r'"a\0b"', 'a\x00b')
def test_exprdouble(self): def test_exprdouble(self):
tcl = self.interp tcl = self.interp
...@@ -320,6 +334,11 @@ class TclTest(unittest.TestCase): ...@@ -320,6 +334,11 @@ class TclTest(unittest.TestCase):
self.assertEqual(passValue(False), False if self.wantobjects else '0') self.assertEqual(passValue(False), False if self.wantobjects else '0')
self.assertEqual(passValue('string'), 'string') self.assertEqual(passValue('string'), 'string')
self.assertEqual(passValue('string\u20ac'), 'string\u20ac') self.assertEqual(passValue('string\u20ac'), 'string\u20ac')
self.assertEqual(passValue('str\x00ing'), 'str\x00ing')
self.assertEqual(passValue('str\x00ing\xbd'), 'str\x00ing\xbd')
self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac')
self.assertEqual(passValue(b'str\x00ing'), 'str\x00ing')
self.assertEqual(passValue(b'str\xc0\x80ing'), 'str\x00ing')
for i in (0, 1, -1, 2**31-1, -2**31): for i in (0, 1, -1, 2**31-1, -2**31):
self.assertEqual(passValue(i), i if self.wantobjects else str(i)) self.assertEqual(passValue(i), i if self.wantobjects else str(i))
for f in (0.0, 1.0, -1.0, 1/3, for f in (0.0, 1.0, -1.0, 1/3,
...@@ -368,6 +387,13 @@ class TclTest(unittest.TestCase): ...@@ -368,6 +387,13 @@ class TclTest(unittest.TestCase):
check('string', 'string') check('string', 'string')
check('string\xbd', 'string\xbd') check('string\xbd', 'string\xbd')
check('string\u20ac', 'string\u20ac') check('string\u20ac', 'string\u20ac')
check(b'string', 'string')
check(b'string\xe2\x82\xac', 'string\u20ac')
check('str\x00ing', 'str\x00ing')
check('str\x00ing\xbd', 'str\x00ing\xbd')
check('str\x00ing\u20ac', 'str\x00ing\u20ac')
check(b'str\xc0\x80ing', 'str\x00ing')
check(b'str\xc0\x80ing\xe2\x82\xac', 'str\x00ing\u20ac')
for i in (0, 1, -1, 2**31-1, -2**31): for i in (0, 1, -1, 2**31-1, -2**31):
check(i, str(i)) check(i, str(i))
for f in (0.0, 1.0, -1.0): for f in (0.0, 1.0, -1.0):
...@@ -396,6 +422,7 @@ class TclTest(unittest.TestCase): ...@@ -396,6 +422,7 @@ class TclTest(unittest.TestCase):
(b'a\n b\t\r c\n ', ('a', 'b', 'c')), (b'a\n b\t\r c\n ', ('a', 'b', 'c')),
('a \u20ac', ('a', '\u20ac')), ('a \u20ac', ('a', '\u20ac')),
(b'a \xe2\x82\xac', ('a', '\u20ac')), (b'a \xe2\x82\xac', ('a', '\u20ac')),
(b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')),
('a {b c}', ('a', 'b c')), ('a {b c}', ('a', 'b c')),
(r'a b\ c', ('a', 'b c')), (r'a b\ c', ('a', 'b c')),
(('a', 'b c'), ('a', 'b c')), (('a', 'b c'), ('a', 'b c')),
...@@ -438,6 +465,9 @@ class TclTest(unittest.TestCase): ...@@ -438,6 +465,9 @@ class TclTest(unittest.TestCase):
(b'a\n b\t\r c\n ', ('a', 'b', 'c')), (b'a\n b\t\r c\n ', ('a', 'b', 'c')),
('a \u20ac', ('a', '\u20ac')), ('a \u20ac', ('a', '\u20ac')),
(b'a \xe2\x82\xac', ('a', '\u20ac')), (b'a \xe2\x82\xac', ('a', '\u20ac')),
(b'a\xc0\x80b', 'a\x00b'),
(b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')),
(b'{a\xc0\x80b c\xc0\x80d', '{a\x00b c\x00d'),
('a {b c}', ('a', ('b', 'c'))), ('a {b c}', ('a', ('b', 'c'))),
(r'a b\ c', ('a', ('b', 'c'))), (r'a b\ c', ('a', ('b', 'c'))),
(('a', b'b c'), ('a', ('b', 'c'))), (('a', b'b c'), ('a', ('b', 'c'))),
......
...@@ -68,6 +68,18 @@ class TestVariable(TestBase): ...@@ -68,6 +68,18 @@ class TestVariable(TestBase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
Variable(self.root, name=123) Variable(self.root, name=123)
def test_null_in_name(self):
with self.assertRaises(ValueError):
Variable(self.root, name='var\x00name')
with self.assertRaises(ValueError):
self.root.globalsetvar('var\x00name', "value")
with self.assertRaises(ValueError):
self.root.globalsetvar(b'var\x00name', "value")
with self.assertRaises(ValueError):
self.root.setvar('var\x00name', "value")
with self.assertRaises(ValueError):
self.root.setvar(b'var\x00name', "value")
def test_initialize(self): def test_initialize(self):
v = Var() v = Var()
self.assertFalse(v.side_effect) self.assertFalse(v.side_effect)
...@@ -87,6 +99,12 @@ class TestStringVar(TestBase): ...@@ -87,6 +99,12 @@ class TestStringVar(TestBase):
self.root.globalsetvar("name", "value") self.root.globalsetvar("name", "value")
self.assertEqual("value", v.get()) self.assertEqual("value", v.get())
def test_get_null(self):
v = StringVar(self.root, "abc\x00def", "name")
self.assertEqual("abc\x00def", v.get())
self.root.globalsetvar("name", "val\x00ue")
self.assertEqual("val\x00ue", v.get())
class TestIntVar(TestBase): class TestIntVar(TestBase):
......
...@@ -45,6 +45,9 @@ Core and Builtins ...@@ -45,6 +45,9 @@ Core and Builtins
Library Library
------- -------
- Issue #20368: The null character now correctly passed from Tcl to Python.
Improved error handling in variables-related commands.
- Issue #20435: Fix _pyio.StringIO.getvalue() to take into account newline - Issue #20435: Fix _pyio.StringIO.getvalue() to take into account newline
translation settings. translation settings.
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment