From d9ca98a92d8fbd671d818c2cc0b481182370f1fc Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 2 Mar 2025 21:05:46 +0100 Subject: [PATCH] [3.12] gh-130637: Add validation for numeric response data in `stat()` method (GH-130646) (#130764) gh-130637: Add validation for numeric response data in `stat()` method (GH-130646) (cherry picked from commit a42168d316f0c9a4fc5658dab87682dc19054efb) Co-authored-by: Kanishk Pachauri Co-authored-by: Eric V. Smith --- Lib/poplib.py | 15 +++++++-- Lib/test/test_poplib.py | 31 +++++++++++++++++++ ...01-02-19-28.gh-issue-130637.swet54w4rs.rst | 1 + 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-03-01-02-19-28.gh-issue-130637.swet54w4rs.rst diff --git a/Lib/poplib.py b/Lib/poplib.py index 81b01385987c..9eb662d0000c 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -226,8 +226,19 @@ class POP3: retval = self._shortcmd('STAT') rets = retval.split() if self._debugging: print('*stat*', repr(rets)) - numMessages = int(rets[1]) - sizeMessages = int(rets[2]) + + # Check if the response has enough elements + # RFC 1939 requires at least 3 elements (+OK, message count, mailbox size) + # but allows additional data after the required fields + if len(rets) < 3: + raise error_proto("Invalid STAT response format") + + try: + numMessages = int(rets[1]) + sizeMessages = int(rets[2]) + except ValueError: + raise error_proto("Invalid STAT response data: non-numeric values") + return (numMessages, sizeMessages) diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 869f9431b928..f1ebbeafe0cf 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -289,6 +289,37 @@ class TestPOP3Class(TestCase): def test_stat(self): self.assertEqual(self.client.stat(), (10, 100)) + original_shortcmd = self.client._shortcmd + def mock_shortcmd_invalid_format(cmd): + if cmd == 'STAT': + return b'+OK' + return original_shortcmd(cmd) + + self.client._shortcmd = mock_shortcmd_invalid_format + with self.assertRaises(poplib.error_proto): + self.client.stat() + + def mock_shortcmd_invalid_data(cmd): + if cmd == 'STAT': + return b'+OK abc def' + return original_shortcmd(cmd) + + self.client._shortcmd = mock_shortcmd_invalid_data + with self.assertRaises(poplib.error_proto): + self.client.stat() + + def mock_shortcmd_extra_fields(cmd): + if cmd == 'STAT': + return b'+OK 1 2 3 4 5' + return original_shortcmd(cmd) + + self.client._shortcmd = mock_shortcmd_extra_fields + + result = self.client.stat() + self.assertEqual(result, (1, 2)) + + self.client._shortcmd = original_shortcmd + def test_list(self): self.assertEqual(self.client.list()[1:], ([b'1 1', b'2 2', b'3 3', b'4 4', b'5 5'], diff --git a/Misc/NEWS.d/next/Library/2025-03-01-02-19-28.gh-issue-130637.swet54w4rs.rst b/Misc/NEWS.d/next/Library/2025-03-01-02-19-28.gh-issue-130637.swet54w4rs.rst new file mode 100644 index 000000000000..83cd6c63c352 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-03-01-02-19-28.gh-issue-130637.swet54w4rs.rst @@ -0,0 +1 @@ +Add validation for numeric response data in poplib.POP3.stat() method -- 2.47.3