Skip to content

Commit 1626a47

Browse files
authored
[2.7] bpo-29960 _random.Random corrupted on exception in setstate(). … (#1289)
(cherry picked from commit 9616a82)
1 parent 96f5020 commit 1626a47

File tree

4 files changed

+13
-1
lines changed

4 files changed

+13
-1
lines changed

‎Lib/test/test_random.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ def test_setstate_first_arg(self):
311311
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
312312

313313
def test_setstate_middle_arg(self):
314+
start_state = self.gen.getstate()
314315
# Wrong type, s/b tuple
315316
self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
316317
# Wrong length, s/b 625
@@ -324,6 +325,10 @@ def test_setstate_middle_arg(self):
324325
self.gen.setstate((2, (1,)*624+(625,), None))
325326
with self.assertRaises((ValueError, OverflowError)):
326327
self.gen.setstate((2, (1,)*624+(-1,), None))
328+
# Failed calls to setstate() should not have changed the state.
329+
bits100 = self.gen.getrandbits(100)
330+
self.gen.setstate(start_state)
331+
self.assertEqual(self.gen.getrandbits(100), bits100)
327332

328333
def test_referenceImplementation(self):
329334
# Compare the python implementation with results from the original

‎Misc/ACKS‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,7 @@ Milan Oberkirch
10211021
Pascal Oberndoerfer
10221022
Jeffrey Ollie
10231023
Adam Olsen
1024+
Bryan Olson
10241025
Grant Olson
10251026
Koray Oner
10261027
Piet van Oostrum

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Extension Modules
4949
Library
5050
-------
5151

52+
- bpo-29960: Preserve generator state when _random.Random.setstate()
53+
raises an exception. Patch by Bryan Olson.
54+
5255
- bpo-30310: tkFont now supports unicode options (e.g. font family).
5356

5457
- bpo-30414: multiprocessing.Queue._feed background running

‎Modules/_randommodule.c‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ random_setstate(RandomObject *self, PyObject *state)
341341
int i;
342342
unsigned long element;
343343
long index;
344+
unsigned long new_state[N];
344345

345346
if (!PyTuple_Check(state)) {
346347
PyErr_SetString(PyExc_TypeError,
@@ -357,7 +358,7 @@ random_setstate(RandomObject *self, PyObject *state)
357358
element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
358359
if (element == (unsigned long)-1 && PyErr_Occurred())
359360
return NULL;
360-
self->state[i] = element & 0xffffffffUL; /* Make sure we get sane state */
361+
new_state[i] = element & 0xffffffffUL; /* Make sure we get sane state */
361362
}
362363

363364
index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
@@ -368,6 +369,8 @@ random_setstate(RandomObject *self, PyObject *state)
368369
return NULL;
369370
}
370371
self->index = (int)index;
372+
for (i = 0; i < N; i++)
373+
self->state[i] = new_state[i];
371374

372375
Py_INCREF(Py_None);
373376
return Py_None;

0 commit comments

Comments
 (0)