From 18dfd835f7321256b1ea497b7e3a7e86d9c2c6f4 Mon Sep 17 00:00:00 2001 From: Kanishk Pachauri Date: Thu, 27 Feb 2025 23:46:44 +0530 Subject: [PATCH 1/6] gh-130637: Add validation for numeric response data in `stat()` method --- Lib/poplib.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Lib/poplib.py b/Lib/poplib.py index beb93a0d57cf93..a123f7b45cf60c 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -226,8 +226,16 @@ def stat(self): retval = self._shortcmd('STAT') rets = retval.split() if self._debugging: print('*stat*', repr(rets)) - numMessages = int(rets[1]) - sizeMessages = int(rets[2]) + + 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) From f23be8991e93b4491f4581012cfe0573b8a33f26 Mon Sep 17 00:00:00 2001 From: Kanishk Pachauri Date: Fri, 28 Feb 2025 15:21:16 +0530 Subject: [PATCH 2/6] tests: Add tests for numeric response data in `stat()` method --- Lib/test/test_poplib.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 869f9431b928bb..43cc7b2eea13b1 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -289,6 +289,27 @@ def test_pass_(self): 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() + + 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'], From 46bc8bd061c9e95428cd3c7136c34b83d0f67ff9 Mon Sep 17 00:00:00 2001 From: Kanishk Pachauri Date: Sat, 1 Mar 2025 02:16:26 +0530 Subject: [PATCH 3/6] fix: add doc comment to ensures compliance with RFC 1939 --- Lib/poplib.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/poplib.py b/Lib/poplib.py index a123f7b45cf60c..4469bff44b4c45 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -227,6 +227,9 @@ def stat(self): rets = retval.split() if self._debugging: print('*stat*', repr(rets)) + # 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") From a43b2aebadede90361e84eaac520140f03152aba Mon Sep 17 00:00:00 2001 From: Kanishk Pachauri Date: Sat, 1 Mar 2025 02:22:55 +0530 Subject: [PATCH 4/6] tests: Add tests to ensure it follows RFC 1939 --- Lib/test/test_poplib.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 43cc7b2eea13b1..f1ebbeafe0cfb4 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -308,6 +308,16 @@ def mock_shortcmd_invalid_data(cmd): 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): From 513af113a7aa58bbce0f579aec559da2e3ce9fca Mon Sep 17 00:00:00 2001 From: Kanishk Pachauri Date: Sat, 1 Mar 2025 02:23:31 +0530 Subject: [PATCH 5/6] chore: add NEWS entry for the change --- .../Library/2025-03-01-02-19-28.gh-issue-130637.swet54w4rs.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-03-01-02-19-28.gh-issue-130637.swet54w4rs.rst 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 00000000000000..03d996791cb7ef --- /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 From dadeef1d7fb412eb4fd593e5c52ccbd3b5359456 Mon Sep 17 00:00:00 2001 From: Kanishk Pachauri Date: Sat, 1 Mar 2025 02:27:03 +0530 Subject: [PATCH 6/6] fix: linting errors --- .../Library/2025-03-01-02-19-28.gh-issue-130637.swet54w4rs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 03d996791cb7ef..83cd6c63c35215 100644 --- 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 @@ -1 +1 @@ -- Add validation for numeric response data in poplib.POP3.stat() method +Add validation for numeric response data in poplib.POP3.stat() method