Skip to content

Commit adef1a2

Browse files
authored
Merge branch 'main' into issue-64373
2 parents bc09e60 + 0d04b8d commit adef1a2

File tree

8 files changed

+69
-18
lines changed

8 files changed

+69
-18
lines changed

Lib/distutils/command/install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ def finalize_options(self):
323323
self.config_vars['userbase'] = self.install_userbase
324324
self.config_vars['usersite'] = self.install_usersite
325325

326-
if sysconfig.is_python_build(True):
326+
if sysconfig.is_python_build():
327327
self.config_vars['srcdir'] = sysconfig.get_config_var('srcdir')
328328

329329
self.expand_basedirs()

Lib/test/test_bisect.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,34 @@ def test_insort_keynotNone(self):
263263
for f in (self.module.insort_left, self.module.insort_right):
264264
self.assertRaises(TypeError, f, x, y, key = "b")
265265

266+
def test_lt_returns_non_bool(self):
267+
class A:
268+
def __init__(self, val):
269+
self.val = val
270+
def __lt__(self, other):
271+
return "nonempty" if self.val < other.val else ""
272+
273+
data = [A(i) for i in range(100)]
274+
i1 = self.module.bisect_left(data, A(33))
275+
i2 = self.module.bisect_right(data, A(33))
276+
self.assertEqual(i1, 33)
277+
self.assertEqual(i2, 34)
278+
279+
def test_lt_returns_notimplemented(self):
280+
class A:
281+
def __init__(self, val):
282+
self.val = val
283+
def __lt__(self, other):
284+
return NotImplemented
285+
def __gt__(self, other):
286+
return self.val > other.val
287+
288+
data = [A(i) for i in range(100)]
289+
i1 = self.module.bisect_left(data, A(40))
290+
i2 = self.module.bisect_right(data, A(40))
291+
self.assertEqual(i1, 40)
292+
self.assertEqual(i2, 41)
293+
266294
class TestBisectPython(TestBisect, unittest.TestCase):
267295
module = py_bisect
268296

Lib/test/test_source_encoding.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,18 @@ def test_error_from_string(self):
147147
self.assertTrue(c.exception.args[0].startswith(expected),
148148
msg=c.exception.args[0])
149149

150+
def test_file_parse_error_multiline(self):
151+
# gh96611:
152+
with open(TESTFN, "wb") as fd:
153+
fd.write(b'print("""\n\xb1""")\n')
154+
155+
try:
156+
retcode, stdout, stderr = script_helper.assert_python_failure(TESTFN)
157+
158+
self.assertGreater(retcode, 0)
159+
self.assertIn(b"Non-UTF-8 code starting with '\\xb1'", stderr)
160+
finally:
161+
os.unlink(TESTFN)
150162

151163
class AbstractSourceEncodingTest:
152164

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
When loading a file with invalid UTF-8 inside a multi-line string, a correct
2+
SyntaxError is emitted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix use after free in trace refs build mode. Patch by Kumar Aditya.

Modules/_bisectmodule.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t
120120
}
121121
else {
122122
res = PyObject_IsTrue(res_obj);
123+
Py_DECREF(res_obj);
123124
}
124125
}
125126
else {
@@ -299,6 +300,7 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h
299300
}
300301
else {
301302
res = PyObject_IsTrue(res_obj);
303+
Py_DECREF(res_obj);
302304
}
303305
}
304306
else {

Parser/tokenizer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,8 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end)
19361936
/* Get rest of string */
19371937
while (end_quote_size != quote_size) {
19381938
c = tok_nextc(tok);
1939+
if (tok->done == E_DECODE)
1940+
break;
19391941
if (c == EOF || (quote_size == 1 && c == '\n')) {
19401942
assert(tok->multi_line_start != NULL);
19411943
// shift the tok_state's location into

Python/ceval.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
# error "ceval.c must be build with Py_BUILD_CORE define for best performance"
4747
#endif
4848

49-
#ifndef Py_DEBUG
49+
#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
5050
// GH-89279: The MSVC compiler does not inline these static inline functions
5151
// in PGO build in _PyEval_EvalFrameDefault(), because this function is over
5252
// the limit of PGO, and that limit cannot be configured.
@@ -3816,10 +3816,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
38163816
}
38173817
_PyErr_Clear(tstate);
38183818
}
3819-
iterator_exhausted_no_error:
38203819
/* iterator ended normally */
3821-
assert(!_PyErr_Occurred(tstate));
3822-
Py_DECREF(POP());
3820+
STACK_SHRINK(1);
3821+
Py_DECREF(iter);
38233822
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
38243823
DISPATCH();
38253824
}
@@ -3845,19 +3844,21 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
38453844
DEOPT_IF(Py_TYPE(it) != &PyListIter_Type, FOR_ITER);
38463845
STAT_INC(FOR_ITER, hit);
38473846
PyListObject *seq = it->it_seq;
3848-
if (seq == NULL) {
3849-
goto iterator_exhausted_no_error;
3850-
}
3851-
if (it->it_index < PyList_GET_SIZE(seq)) {
3852-
PyObject *next = PyList_GET_ITEM(seq, it->it_index++);
3853-
Py_INCREF(next);
3854-
PUSH(next);
3855-
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER);
3856-
NOTRACE_DISPATCH();
3847+
if (seq) {
3848+
if (it->it_index < PyList_GET_SIZE(seq)) {
3849+
PyObject *next = PyList_GET_ITEM(seq, it->it_index++);
3850+
Py_INCREF(next);
3851+
PUSH(next);
3852+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER);
3853+
NOTRACE_DISPATCH();
3854+
}
3855+
it->it_seq = NULL;
3856+
Py_DECREF(seq);
38573857
}
3858-
it->it_seq = NULL;
3859-
Py_DECREF(seq);
3860-
goto iterator_exhausted_no_error;
3858+
STACK_SHRINK(1);
3859+
Py_DECREF(it);
3860+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
3861+
NOTRACE_DISPATCH();
38613862
}
38623863

38633864
TARGET(FOR_ITER_RANGE) {
@@ -3868,7 +3869,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
38683869
_Py_CODEUNIT next = next_instr[INLINE_CACHE_ENTRIES_FOR_ITER];
38693870
assert(_PyOpcode_Deopt[_Py_OPCODE(next)] == STORE_FAST);
38703871
if (r->index >= r->len) {
3871-
goto iterator_exhausted_no_error;
3872+
STACK_SHRINK(1);
3873+
Py_DECREF(r);
3874+
JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg);
3875+
NOTRACE_DISPATCH();
38723876
}
38733877
long value = (long)(r->start +
38743878
(unsigned long)(r->index++) * r->step);

0 commit comments

Comments
 (0)