From 85bcb1b26683f3f3def8858dd216539cadb1c308 Mon Sep 17 00:00:00 2001 From: devdanzin <74280297+devdanzin@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:13:50 -0300 Subject: [PATCH 1/5] Check that suggestion candidates in calculate_suggestions are strings. --- Python/suggestions.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Python/suggestions.c b/Python/suggestions.c index 2ce0bcfd54e23f..bb553ef9b3c909 100644 --- a/Python/suggestions.c +++ b/Python/suggestions.c @@ -148,6 +148,10 @@ _Py_CalculateSuggestions(PyObject *dir, } for (Py_ssize_t i = 0; i < dir_size; ++i) { PyObject *item = PyList_GET_ITEM(dir, i); + if (!PyUnicode_Check(item)) { + PyMem_Free(buffer); + return NULL; + } if (_PyUnicode_Equal(name, item)) { continue; } From 4586bbaef43b7dc8086a7e5648d40c355faad314 Mon Sep 17 00:00:00 2001 From: devdanzin <74280297+devdanzin@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:32:44 -0300 Subject: [PATCH 2/5] Add a test for the abort with non-string candidates in calculate_suggestions. --- Lib/test/test_traceback.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 68c4fa117a90f5..c33d9b27ae052b 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4072,6 +4072,17 @@ class A: actual = self.get_suggestion(A(), 'bluch') self.assertNotIn("blech", actual) + def test_suggestions_do_not_trigger_with_non_string_candidates(self): + class Parent: + def __dir__(self): + return [0, 'blech'] + + class WithNonStringAttrs(Parent): + blech = None + + result = self.get_suggestion(WithNonStringAttrs(), "bluch") + self.assertNotIn("blech", result) + def test_getattr_suggestions_no_args(self): class A: blech = None From 22ac8be88459cc5c0c4f6afc3101ceb80c78a199 Mon Sep 17 00:00:00 2001 From: devdanzin <74280297+devdanzin@users.noreply.github.com> Date: Sat, 8 Mar 2025 23:15:54 -0300 Subject: [PATCH 3/5] Use a test that actually aborts on 3.12, still not testing the code change in 3.14. --- Lib/test/test_traceback.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index c33d9b27ae052b..aae04a21443f1c 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4073,15 +4073,12 @@ class A: self.assertNotIn("blech", actual) def test_suggestions_do_not_trigger_with_non_string_candidates(self): - class Parent: - def __dir__(self): - return [0, 'blech'] - - class WithNonStringAttrs(Parent): - blech = None + def run_module_code(): + import runpy + runpy._run_module_code("blech", {0: "", "bluch": ""}, "") - result = self.get_suggestion(WithNonStringAttrs(), "bluch") - self.assertNotIn("blech", result) + actual = self.get_exception(run_module_code, slice_start=-1, slice_end=None) + self.assertNotIn("bluch", actual[0]) def test_getattr_suggestions_no_args(self): class A: From b7022154626e94de839ea2073ec7d50135e78602 Mon Sep 17 00:00:00 2001 From: devdanzin <74280297+devdanzin@users.noreply.github.com> Date: Mon, 2 Jun 2025 09:31:50 -0300 Subject: [PATCH 4/5] Remove test added in baccfdb, add a new one. --- Lib/test/test_traceback.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 9a39db1b7cb19e..e0e904c1231ac3 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4130,14 +4130,6 @@ class A: actual = self.get_suggestion(A(), 'bluch') self.assertNotIn("blech", actual) - def test_suggestions_do_not_trigger_with_non_string_candidates(self): - def run_module_code(): - import runpy - runpy._run_module_code("blech", {0: "", "bluch": ""}, "") - - actual = self.get_exception(run_module_code, slice_start=-1, slice_end=None) - self.assertNotIn("bluch", actual[0]) - def test_getattr_suggestions_no_args(self): class A: blech = None @@ -4748,6 +4740,13 @@ def test_suggestions_extension(self): None ) + self.assertRaises( + TypeError, + _suggestions._generate_suggestions, + ["hello", "world", 0, 1.1], + "hell", + ) + # gh-131936: _generate_suggestions() doesn't accept list subclasses class MyList(list): pass From 87b57945346e639e55e7e905fdd75c0325837744 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:37:00 +0000 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-06-02-12-36-52.gh-issue-129573.zY2VO9.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-06-02-12-36-52.gh-issue-129573.zY2VO9.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-02-12-36-52.gh-issue-129573.zY2VO9.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-02-12-36-52.gh-issue-129573.zY2VO9.rst new file mode 100644 index 00000000000000..9290236ca32370 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-02-12-36-52.gh-issue-129573.zY2VO9.rst @@ -0,0 +1 @@ +Avoid possible abort when getting suggestions and there are non-string candidates.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: