From b9582dab762e7257cd61664cdf456fe8880fd708 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Wed, 8 Jan 2025 22:28:10 +0100 Subject: [PATCH 1/3] Fix PyREPL failure when os.environ is overwritten --- Lib/_pyrepl/unix_console.py | 4 ++-- Lib/test/test_pyrepl/test_unix_console.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Lib/_pyrepl/unix_console.py b/Lib/_pyrepl/unix_console.py index 63e8fc24dd7625..085f7cfc531dfe 100644 --- a/Lib/_pyrepl/unix_console.py +++ b/Lib/_pyrepl/unix_console.py @@ -449,7 +449,7 @@ def getheightwidth(self): """ try: return int(os.environ["LINES"]), int(os.environ["COLUMNS"]) - except KeyError: + except (KeyError, TypeError, ValueError): height, width = struct.unpack( "hhhh", ioctl(self.input_fd, TIOCGWINSZ, b"\000" * 8) )[0:2] @@ -468,7 +468,7 @@ def getheightwidth(self): """ try: return int(os.environ["LINES"]), int(os.environ["COLUMNS"]) - except KeyError: + except (KeyError, TypeError, ValueError): return 25, 80 def forgetinput(self): diff --git a/Lib/test/test_pyrepl/test_unix_console.py b/Lib/test/test_pyrepl/test_unix_console.py index e3bbabcb0089fb..15dbf48bcf0f1c 100644 --- a/Lib/test/test_pyrepl/test_unix_console.py +++ b/Lib/test/test_pyrepl/test_unix_console.py @@ -1,7 +1,9 @@ import itertools +import os import sys import unittest from functools import partial +from test.support import os_helper from unittest import TestCase from unittest.mock import MagicMock, call, patch, ANY @@ -312,3 +314,14 @@ def same_console(events): ) console.restore() con.restore() + + def test_getheightwidth_with_invalid_environ(self, _os_write): + # gh-128636 + console = UnixConsole() + with os_helper.EnvironmentVarGuard() as env: + env["LINES"] = "" + self.assertIsInstance(console.getheightwidth(), tuple) + env["COLUMNS"] = "" + self.assertIsInstance(console.getheightwidth(), tuple) + os.environ = [] + self.assertIsInstance(console.getheightwidth(), tuple) From 48ae6c2aa0e9f27ba192bb592c42983011a861da Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Wed, 8 Jan 2025 22:30:44 +0100 Subject: [PATCH 2/3] Add news entry --- .../next/Library/2025-01-08-22-30-38.gh-issue-128636.jQfWXj.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-01-08-22-30-38.gh-issue-128636.jQfWXj.rst diff --git a/Misc/NEWS.d/next/Library/2025-01-08-22-30-38.gh-issue-128636.jQfWXj.rst b/Misc/NEWS.d/next/Library/2025-01-08-22-30-38.gh-issue-128636.jQfWXj.rst new file mode 100644 index 00000000000000..80c9840b585530 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-01-08-22-30-38.gh-issue-128636.jQfWXj.rst @@ -0,0 +1,2 @@ +Fix PyREPL failure when :data:`os.environ` is overwritten with an invalid +value. From df63da0c7ecc6be979ceb743f22d8470c808e3f4 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Thu, 9 Jan 2025 22:23:46 +0100 Subject: [PATCH 3/3] ioctl can raise OSError --- Lib/_pyrepl/unix_console.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/_pyrepl/unix_console.py b/Lib/_pyrepl/unix_console.py index 085f7cfc531dfe..74299a8fc85797 100644 --- a/Lib/_pyrepl/unix_console.py +++ b/Lib/_pyrepl/unix_console.py @@ -450,9 +450,11 @@ def getheightwidth(self): try: return int(os.environ["LINES"]), int(os.environ["COLUMNS"]) except (KeyError, TypeError, ValueError): - height, width = struct.unpack( - "hhhh", ioctl(self.input_fd, TIOCGWINSZ, b"\000" * 8) - )[0:2] + try: + size = ioctl(self.input_fd, TIOCGWINSZ, b"\000" * 8) + except OSError: + return 25, 80 + height, width = struct.unpack("hhhh", size)[0:2] if not height: return 25, 80 return height, width