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 */

5252

static 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) {

5656

i++;

5757

}

5858

return 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

*/

130130

static 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 */

135136

assert(PyList_CheckExact(consts));

@@ -142,7 +143,7 @@ fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t c_start,

142143143144

for (Py_ssize_t i = 0, pos = c_start; i < n; i++, pos++) {

144145

assert(pos < opcode_end);

145-

pos = find_op(codestr, pos);

146+

pos = find_op(codestr, codelen, pos);

146147

assert(_Py_OPCODE(codestr[pos]) == LOAD_CONST);

147148148149

unsigned int arg = get_arg(codestr, pos);

@@ -267,7 +268,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,

267268

goto exitError;

268269

assert(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) {

271272

opcode = _Py_OPCODE(codestr[i]);

272273

op_start = i;

273274

while (op_start >= 1 && _Py_OPCODE(codestr[op_start-1]) == EXTENDED_ARG) {

@@ -305,7 +306,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,

305306

if (j > 0 && lastlc >= j) {

306307

h = lastn_const_start(codestr, op_start, j);

307308

if (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);

309311

break;

310312

}

311313

}

@@ -342,7 +344,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,

342344

case JUMP_IF_FALSE_OR_POP:

343345

case JUMP_IF_TRUE_OR_POP:

344346

h = get_arg(codestr, i) / sizeof(_Py_CODEUNIT);

345-

tgt = find_op(codestr, h);

347+

tgt = find_op(codestr, codelen, h);

346348347349

j = _Py_OPCODE(codestr[tgt]);

348350

if (CONDITIONAL_JUMP(j)) {

@@ -383,7 +385,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,

383385

case SETUP_WITH:

384386

case SETUP_ASYNC_WITH:

385387

h = 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 */

388390

if (UNCONDITIONAL_JUMP(opcode) &&

389391

_Py_OPCODE(codestr[tgt]) == RETURN_VALUE) {

@@ -412,7 +414,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,

412414

}

413415

if (h > i + 1) {

414416

fill_nops(codestr, i + 1, h);

415-

nexti = find_op(codestr, h);

417+

nexti = find_op(codestr, codelen, h);

416418

}

417419

break;

418420

}