8000 bpo-44260: Do not read system entropy without need in Random() (GH-26… · python/cpython@a6a2065 · GitHub
[go: up one dir, main page]

Skip to content

Commit a6a2065

Browse files
bpo-44260: Do not read system entropy without need in Random() (GH-26455)
1 parent 78d9a9b commit a6a2065

File tree

3 files changed

+38
-44
lines changed

3 files changed

+38
-44
lines changed

Lib/test/test_random.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -374,23 +374,6 @@ def test_pickling(self):
374374
restoredseq = [newgen.random() for i in range(10)]
375375
self.assertEqual(origseq, restoredseq)
376376

377-
@test.support.cpython_only
378-
def test_bug_41052(self):
379-
# _random.Random should not be allowed to serialization
380-
import _random
381-
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
382-
r = _random.Random()
383-
self.assertRaises(TypeError, pickle.dumps, r, proto)
384-
385-
@test.support.cpython_only
386-
def test_bug_42008(self):
387-
# _random.Random should call seed with first element of arg tuple
388-
import _random
389-
r1 = _random.Random()
390-
r1.seed(8675309)
391-
r2 = _random.Random(8675309)
392-
self.assertEqual(r1.random(), r2.random())
393-
394377
def test_bug_1727780(self):
395378
# verify that version-2-pickles can be loaded
396379
# fine, whether they are created on 32-bit or 64-bit
@@ -573,6 +556,25 @@ def test_randbelow_logic(self, _log=log, int=int):
573556
self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion
574557

575558

559+
class TestRawMersenneTwister(unittest.TestCase):
560+
@test.support.cpython_only
561+
def test_bug_41052(self):
562+
# _random.Random should not be allowed to serialization
563+
import _random
564+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
565+
r = _random.Random()
566+
self.assertRaises(TypeError, pickle.dumps, r, proto)
567+
568+
@test.support.cpython_only
569+
def test_bug_42008(self):
570+
# _random.Random should call seed with first element of arg tuple
571+
import _random
572+
r1 = _random.Random()
573+
r1.seed(8675309)
574+
r2 = _random.Random(8675309)
575+
self.assertEqual(r1.random(), r2.random())
576+
577+
576578
class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
577579
gen = random.Random()
578580

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The :class:`random.Random` constructor no longer reads system entropy
2+
without need.

Modules/_randommodule.c

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,10 @@ random_seed_time_pid(RandomObject *self)
263263
init_by_array(self, key, Py_ARRAY_LENGTH(key));
264264
}
265265

266-
static PyObject *
266+
static int
267267
random_seed(RandomObject *self, PyObject *arg)
268268
{
269-
PyObject *result = NULL; /* guilty until proved innocent */
269+
int result = -1; /* guilty until proved innocent */
270270
PyObject *n = NULL;
271271
uint32_t *key = NULL;
272272
size_t bits, keyused;
@@ -280,7 +280,7 @@ random_seed(RandomObject *self, PyObject *arg)
280280
use the current time and process identifier. */
281281
random_seed_time_pid(self);
282282
}
283-
Py_RETURN_NONE;
283+
return 0;
284284
}
285285

286286
/* This algorithm relies on the number being unsigned.
@@ -339,8 +339,7 @@ random_seed(RandomObject *self, PyObject *arg)
339339
#endif
340340
init_by_array(self, key, keyused);
341341

342-
Py_INCREF(Py_None);
343-
result = Py_None;
342+
result = 0;
344343

345344
Done:
346345
Py_XDECREF(n);
@@ -365,7 +364,10 @@ static PyObject *
365364
_random_Random_seed_impl(RandomObject *self, PyObject *n)
366365
/*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/
367366
{
368-
return random_seed(self, n);
367+
if (random_seed(self, n) < 0) {
368+
return NULL;
369+
}
370+
Py_RETURN_NONE;
369371
}
370372

371373
/*[clinic input]
@@ -515,39 +517,26 @@ _random_Random_getrandbits_impl(RandomObject *self, int k)
515517
return result;
516518
}
517519

518-
static PyObject *
519-
random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
520+
static int
521+
random_init(RandomObject *self, PyObject *args, PyObject *kwds)
520522
{
521-
RandomObject *self;
522-
PyObject *tmp;
523523
PyObject *arg = NULL;
524-
_randomstate *state = _randomstate_type(type);
524+
_randomstate *state = _randomstate_type(Py_TYPE(self));
525525

526-
if (type == (PyTypeObject*)state->Random_Type &&
526+
if (Py_IS_TYPE(self, (PyTypeObject *)state->Random_Type) &&
527527
!_PyArg_NoKeywords("Random()", kwds)) {
528-
return NULL;
528+
return -1;
529529
}
530530

531-
self = (RandomObject *)PyType_GenericAlloc(type, 0);
532-
if (self == NULL)
533-
return NULL;
534-
535531
if (PyTuple_GET_SIZE(args) > 1) {
536532
PyErr_SetString(PyExc_TypeError, "Random() requires 0 or 1 argument");
537-
return NULL;
533+
return -1;
538534
}
539535

540536
if (PyTuple_GET_SIZE(args) == 1)
541537
arg = PyTuple_GET_ITEM(args, 0);
542538

543-
tmp = random_seed(self, arg);
544-
if (tmp == NULL) {
545-
Py_DECREF(self);
546-
return NULL;
547-
}
548-
Py_DECREF(tmp);
549-
550-
return (PyObject *)self;
539+
return random_seed(self, arg);
551540
}
552541

553542

@@ -566,7 +555,8 @@ PyDoc_STRVAR(random_doc,
566555
static PyType_Slot Random_Type_slots[] = {
567556
{Py_tp_doc, (void *)random_doc},
568557
{Py_tp_methods, random_methods},
569-
{Py_tp_new, random_new},
558+
{Py_tp_new, PyType_GenericNew},
559+
{Py_tp_init, random_init},
570560
{Py_tp_free, PyObject_Free},
571561
{0, 0},
572562
};

0 commit comments

Comments
 (0)
0