bpo-35193: Fix an off by one error in the RETURN_VALUE case. (GH-10418) · python/cpython@f16ebcd
@@ -50,9 +50,9 @@ lastn_const_start(const _Py_CODEUNIT *codestr, Py_ssize_t i, Py_ssize_t n)
50505151/* Scans through EXTENDED ARGs, seeking the index of the effective opcode */
5252static Py_ssize_t
53-find_op(const _Py_CODEUNIT *codestr, Py_ssize_t i)
53+find_op(const _Py_CODEUNIT *codestr, Py_ssize_t codelen, Py_ssize_t i)
5454{
55-while (_Py_OPCODE(codestr[i]) == EXTENDED_ARG) {
55+while (i < codelen && _Py_OPCODE(codestr[i]) == EXTENDED_ARG) {
5656i++;
5757 }
5858return i;
@@ -128,8 +128,9 @@ copy_op_arg(_Py_CODEUNIT *codestr, Py_ssize_t i, unsigned char op,
128128 Called with codestr pointing to the first LOAD_CONST.
129129*/
130130static Py_ssize_t
131-fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t c_start,
132-Py_ssize_t opcode_end, PyObject *consts, int n)
131+fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen,
132+Py_ssize_t c_start, Py_ssize_t opcode_end,
133+PyObject *consts, int n)
133134{
134135/* Pre-conditions */
135136assert(PyList_CheckExact(consts));
@@ -142,7 +143,7 @@ fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t c_start,
142143143144for (Py_ssize_t i = 0, pos = c_start; i < n; i++, pos++) {
144145assert(pos < opcode_end);
145-pos = find_op(codestr, pos);
146+pos = find_op(codestr, codelen, pos);
146147assert(_Py_OPCODE(codestr[pos]) == LOAD_CONST);
147148148149unsigned int arg = get_arg(codestr, pos);
@@ -267,7 +268,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
267268 goto exitError;
268269assert(PyList_Check(consts));
269270270-for (i=find_op(codestr, 0) ; i<codelen ; i=nexti) {
271+for (i=find_op(codestr, codelen, 0) ; i<codelen ; i=nexti) {
271272opcode = _Py_OPCODE(codestr[i]);
272273op_start = i;
273274while (op_start >= 1 && _Py_OPCODE(codestr[op_start-1]) == EXTENDED_ARG) {
@@ -305,7 +306,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
305306if (j > 0 && lastlc >= j) {
306307h = lastn_const_start(codestr, op_start, j);
307308if (ISBASICBLOCK(blocks, h, op_start)) {
308-h = fold_tuple_on_constants(codestr, h, i+1, consts, j);
309+h = fold_tuple_on_constants(codestr, codelen,
310+h, i+1, consts, j);
309311break;
310312 }
311313 }
@@ -342,7 +344,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
342344case JUMP_IF_FALSE_OR_POP:
343345case JUMP_IF_TRUE_OR_POP:
344346h = get_arg(codestr, i) / sizeof(_Py_CODEUNIT);
345-tgt = find_op(codestr, h);
347+tgt = find_op(codestr, codelen, h);
346348347349j = _Py_OPCODE(codestr[tgt]);
348350if (CONDITIONAL_JUMP(j)) {
@@ -383,7 +385,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
383385case SETUP_WITH:
384386case SETUP_ASYNC_WITH:
385387h = GETJUMPTGT(codestr, i);
386-tgt = find_op(codestr, h);
388+tgt = find_op(codestr, codelen, h);
387389/* Replace JUMP_* to a RETURN into just a RETURN */
388390if (UNCONDITIONAL_JUMP(opcode) &&
389391_Py_OPCODE(codestr[tgt]) == RETURN_VALUE) {
@@ -412,7 +414,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
412414 }
413415if (h > i + 1) {
414416fill_nops(codestr, i + 1, h);
415-nexti = find_op(codestr, h);
417+nexti = find_op(codestr, codelen, h);
416418 }
417419break;
418420 }