bpo-29816: Shift operation now has less opportunity to raise Overflow… · python/cpython@918403c (original) (raw)

`@@ -4277,15 +4277,54 @@ long_bool(PyLongObject *v)

`

4277

4277

`return Py_SIZE(v) != 0;

`

4278

4278

`}

`

4279

4279

``

``

4280

`+

/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */

`

``

4281

`+

static int

`

``

4282

`+

divmod_shift(PyLongObject *shiftby, Py_ssize_t *wordshift, digit *remshift)

`

``

4283

`+

{

`

``

4284

`+

assert(PyLong_Check((PyObject *)shiftby));

`

``

4285

`+

assert(Py_SIZE(shiftby) >= 0);

`

``

4286

`+

Py_ssize_t lshiftby = PyLong_AsSsize_t((PyObject *)shiftby);

`

``

4287

`+

if (lshiftby >= 0) {

`

``

4288

`+

*wordshift = lshiftby / PyLong_SHIFT;

`

``

4289

`+

*remshift = lshiftby % PyLong_SHIFT;

`

``

4290

`+

return 0;

`

``

4291

`+

}

`

``

4292

`+

/* PyLong_Check(shiftby) is true and Py_SIZE(shiftby) >= 0, so it must

`

``

4293

`+

be that PyLong_AsSsize_t raised an OverflowError. */

`

``

4294

`+

assert(PyErr_ExceptionMatches(PyExc_OverflowError));

`

``

4295

`+

PyErr_Clear();

`

``

4296

`+

PyLongObject *wordshift_obj = divrem1(shiftby, PyLong_SHIFT, remshift);

`

``

4297

`+

if (wordshift_obj == NULL) {

`

``

4298

`+

return -1;

`

``

4299

`+

}

`

``

4300

`+

*wordshift = PyLong_AsSsize_t((PyObject *)wordshift_obj);

`

``

4301

`+

Py_DECREF(wordshift_obj);

`

``

4302

`+

if (*wordshift >= 0 && *wordshift < PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(digit)) {

`

``

4303

`+

return 0;

`

``

4304

`+

}

`

``

4305

`+

PyErr_Clear();

`

``

4306

`+

/* Clip the value. With such large wordshift the right shift

`

``

4307

`+

returns 0 and the left shift raises an error in _PyLong_New(). */

`

``

4308

`+

*wordshift = PY_SSIZE_T_MAX / sizeof(digit);

`

``

4309

`+

*remshift = 0;

`

``

4310

`+

return 0;

`

``

4311

`+

}

`

``

4312

+

4280

4313

`static PyObject *

`

4281

4314

`long_rshift(PyLongObject *a, PyLongObject *b)

`

4282

4315

`{

`

4283

4316

`PyLongObject *z = NULL;

`

4284

``

`-

Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j;

`

4285

``

`-

digit lomask, himask;

`

``

4317

`+

Py_ssize_t newsize, wordshift, hishift, i, j;

`

``

4318

`+

digit loshift, lomask, himask;

`

4286

4319

``

4287

4320

`CHECK_BINOP(a, b);

`

4288

4321

``

``

4322

`+

if (Py_SIZE(b) < 0) {

`

``

4323

`+

PyErr_SetString(PyExc_ValueError,

`

``

4324

`+

"negative shift count");

`

``

4325

`+

return NULL;

`

``

4326

`+

}

`

``

4327

+

4289

4328

`if (Py_SIZE(a) < 0) {

`

4290

4329

`/* Right shifting negative numbers is harder */

`

4291

4330

`PyLongObject *a1, *a2;

`

`@@ -4300,19 +4339,11 @@ long_rshift(PyLongObject *a, PyLongObject *b)

`

4300

4339

`Py_DECREF(a2);

`

4301

4340

` }

`

4302

4341

`else {

`

4303

``

`-

shiftby = PyLong_AsSsize_t((PyObject *)b);

`

4304

``

`-

if (shiftby == -1L && PyErr_Occurred())

`

4305

``

`-

return NULL;

`

4306

``

`-

if (shiftby < 0) {

`

4307

``

`-

PyErr_SetString(PyExc_ValueError,

`

4308

``

`-

"negative shift count");

`

``

4342

`+

if (divmod_shift(b, &wordshift, &loshift) < 0)

`

4309

4343

`return NULL;

`

4310

``

`-

}

`

4311

``

`-

wordshift = shiftby / PyLong_SHIFT;

`

4312

``

`-

newsize = Py_ABS(Py_SIZE(a)) - wordshift;

`

``

4344

`+

newsize = Py_SIZE(a) - wordshift;

`

4313

4345

`if (newsize <= 0)

`

4314

4346

`return PyLong_FromLong(0);

`

4315

``

`-

loshift = shiftby % PyLong_SHIFT;

`

4316

4347

`hishift = PyLong_SHIFT - loshift;

`

4317

4348

`lomask = ((digit)1 << hishift) - 1;

`

4318

4349

`himask = PyLong_MASK ^ lomask;

`

`@@ -4336,27 +4367,22 @@ long_lshift(PyObject *v, PyObject *w)

`

4336

4367

`PyLongObject a = (PyLongObject)v;

`

4337

4368

`PyLongObject b = (PyLongObject)w;

`

4338

4369

`PyLongObject *z = NULL;

`

4339

``

`-

Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j;

`

``

4370

`+

Py_ssize_t oldsize, newsize, wordshift, i, j;

`

``

4371

`+

digit remshift;

`

4340

4372

`twodigits accum;

`

4341

4373

``

4342

4374

`CHECK_BINOP(a, b);

`

4343

4375

``

4344

``

`-

shiftby = PyLong_AsSsize_t((PyObject *)b);

`

4345

``

`-

if (shiftby == -1L && PyErr_Occurred())

`

4346

``

`-

return NULL;

`

4347

``

`-

if (shiftby < 0) {

`

``

4376

`+

if (Py_SIZE(b) < 0) {

`

4348

4377

`PyErr_SetString(PyExc_ValueError, "negative shift count");

`

4349

4378

`return NULL;

`

4350

4379

` }

`

4351

``

-

4352

4380

`if (Py_SIZE(a) == 0) {

`

4353

4381

`return PyLong_FromLong(0);

`

4354

4382

` }

`

4355

4383

``

4356

``

`-

/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */

`

4357

``

`-

wordshift = shiftby / PyLong_SHIFT;

`

4358

``

`-

remshift = shiftby - wordshift * PyLong_SHIFT;

`

4359

``

-

``

4384

`+

if (divmod_shift(b, &wordshift, &remshift) < 0)

`

``

4385

`+

return NULL;

`

4360

4386

`oldsize = Py_ABS(Py_SIZE(a));

`

4361

4387

`newsize = oldsize + wordshift;

`

4362

4388

`if (remshift)

`