[2.7] bpo-31478: Prevent unwanted behavior in _random.Random.seed() i… · python/cpython@13da1a6

File tree

3 files changed

lines changed

  • Misc/NEWS.d/next/Core and Builtins

3 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -307,6 +307,22 @@ def test_randbelow_logic(self, _log=log, int=int):

307307

class MersenneTwister_TestBasicOps(TestBasicOps):

308308

gen = random.Random()

309309
310+

@test_support.cpython_only

311+

def test_bug_31478(self):

312+

# _random.Random.seed() should ignore the __abs__() method of a

313+

# long/int subclass argument.

314+

class BadInt(int):

315+

def __abs__(self):

316+

1/0

317+

class BadLong(long):

318+

def __abs__(self):

319+

1/0

320+

self.gen.seed(42)

321+

expected_value = self.gen.random()

322+

for seed_arg in [42L, BadInt(42), BadLong(42)]:

323+

self.gen.seed(seed_arg)

324+

self.assertEqual(self.gen.random(), expected_value)

325+
310326

def test_setstate_first_arg(self):

311327

self.assertRaises(ValueError, self.gen.setstate, (1, None, None))

312328
Original file line numberDiff line numberDiff line change

@@ -0,0 +1,2 @@

1+

Prevent unwanted behavior in `_random.Random.seed()` in case the argument

2+

has a bad ``__abs__()`` method. Patch by Oren Milman.

Original file line numberDiff line numberDiff line change

@@ -230,9 +230,15 @@ random_seed(RandomObject *self, PyObject *args)

230230

}

231231

/* If the arg is an int or long, use its absolute value; else use

232232

* the absolute value of its hash code.

233+

* Calling int.__abs__() or long.__abs__() prevents calling arg.__abs__(),

234+

* which might return an invalid value. See issue #31478.

233235

*/

234-

if (PyInt_Check(arg) || PyLong_Check(arg))

235-

n = PyNumber_Absolute(arg);

236+

if (PyInt_Check(arg)) {

237+

n = PyInt_Type.tp_as_number->nb_absolute(arg);

238+

}

239+

else if (PyLong_Check(arg)) {

240+

n = PyLong_Type.tp_as_number->nb_absolute(arg);

241+

}

236242

else {

237243

long hash = PyObject_Hash(arg);

238244

if (hash == -1)