From fd48d98df9c1b0cb36b38834cd1ce5020c0a60f3 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:04:51 +0100 Subject: [PATCH] [3.13] gh-125666: Avoid PyREPL exiting when a null byte is in input (GH-125732) (#126023) gh-125666: Avoid PyREPL exiting when a null byte is in input (GH-125732) (cherry picked from commit 44becb8cba677cbfdbcf2f7652277e5e1efc4f20) Co-authored-by: devdanzin <74280297+devdanzin@users.noreply.github.com> --- Lib/code.py | 3 ++- Lib/test/test_pyrepl/test_interact.py | 9 +++++++++ Lib/test/test_pyrepl/test_pyrepl.py | 5 +++++ .../2024-10-19-16-06-52.gh-issue-125666.jGfdCP.rst | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2024-10-19-16-06-52.gh-issue-125666.jGfdCP.rst diff --git a/Lib/code.py b/Lib/code.py index a70d8ccb29ef..2777c3111877 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -137,7 +137,8 @@ class InteractiveInterpreter: # Set the line of text that the exception refers to lines = source.splitlines() if (source and typ is SyntaxError - and not value.text and len(lines) >= value.lineno): + and not value.text and value.lineno is not None + and len(lines) >= value.lineno): value.text = lines[value.lineno - 1] sys.last_exc = sys.last_value = value = value.with_traceback(tb) if sys.excepthook is sys.__excepthook__: diff --git a/Lib/test/test_pyrepl/test_interact.py b/Lib/test/test_pyrepl/test_interact.py index b746674b9ff8..8b941b93670e 100644 --- a/Lib/test/test_pyrepl/test_interact.py +++ b/Lib/test/test_pyrepl/test_interact.py @@ -117,6 +117,15 @@ SyntaxError: duplicate argument 'x' in function definition""" console.runsource(source) mock_showsyntaxerror.assert_called_once() + def test_runsource_survives_null_bytes(self): + console = InteractiveColoredConsole() + source = "\x00\n" + f = io.StringIO() + with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f): + result = console.runsource(source) + self.assertFalse(result) + self.assertIn("source code string cannot contain null bytes", f.getvalue()) + def test_no_active_future(self): console = InteractiveColoredConsole() source = dedent("""\ diff --git a/Lib/test/test_pyrepl/test_pyrepl.py b/Lib/test/test_pyrepl/test_pyrepl.py index 5538c248fdba..e5936c0984ae 100644 --- a/Lib/test/test_pyrepl/test_pyrepl.py +++ b/Lib/test/test_pyrepl/test_pyrepl.py @@ -1313,6 +1313,11 @@ class TestMain(ReplTestCase): self.assertIn("in x3", output) self.assertIn("in ", output) + def test_null_byte(self): + output, exit_code = self.run_repl("\x00\nexit()\n") + self.assertEqual(exit_code, 0) + self.assertNotIn("TypeError", output) + def test_readline_history_file(self): # skip, if readline module is not available readline = import_module('readline') diff --git a/Misc/NEWS.d/next/Library/2024-10-19-16-06-52.gh-issue-125666.jGfdCP.rst b/Misc/NEWS.d/next/Library/2024-10-19-16-06-52.gh-issue-125666.jGfdCP.rst new file mode 100644 index 000000000000..3b4488815cce --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-10-19-16-06-52.gh-issue-125666.jGfdCP.rst @@ -0,0 +1 @@ +Avoid the exiting the interpreter if a null byte is given as input in the new REPL. -- 2.47.3