Commit 1626a479 authored by Mariatta's avatar Mariatta Committed by GitHub

[2.7] bpo-29960 _random.Random corrupted on exception in setstate(). … (#1289)

(cherry picked from commit 9616a82e)
parent 96f50205
......@@ -311,6 +311,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
def test_setstate_middle_arg(self):
start_state = self.gen.getstate()
# Wrong type, s/b tuple
self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
# Wrong length, s/b 625
......@@ -324,6 +325,10 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
self.gen.setstate((2, (1,)*624+(625,), None))
with self.assertRaises((ValueError, OverflowError)):
self.gen.setstate((2, (1,)*624+(-1,), None))
# Failed calls to setstate() should not have changed the state.
bits100 = self.gen.getrandbits(100)
self.gen.setstate(start_state)
self.assertEqual(self.gen.getrandbits(100), bits100)
def test_referenceImplementation(self):
# Compare the python implementation with results from the original
......
......@@ -1021,6 +1021,7 @@ Milan Oberkirch
Pascal Oberndoerfer
Jeffrey Ollie
Adam Olsen
Bryan Olson
Grant Olson
Koray Oner
Piet van Oostrum
......
......@@ -49,6 +49,9 @@ Extension Modules
Library
-------
- bpo-29960: Preserve generator state when _random.Random.setstate()
raises an exception. Patch by Bryan Olson.
- bpo-30310: tkFont now supports unicode options (e.g. font family).
- bpo-30414: multiprocessing.Queue._feed background running
......
......@@ -341,6 +341,7 @@ random_setstate(RandomObject *self, PyObject *state)
int i;
unsigned long element;
long index;
unsigned long new_state[N];
if (!PyTuple_Check(state)) {
PyErr_SetString(PyExc_TypeError,
......@@ -357,7 +358,7 @@ random_setstate(RandomObject *self, PyObject *state)
element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
if (element == (unsigned long)-1 && PyErr_Occurred())
return NULL;
self->state[i] = element & 0xffffffffUL; /* Make sure we get sane state */
new_state[i] = element & 0xffffffffUL; /* Make sure we get sane state */
}
index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
......@@ -368,6 +369,8 @@ random_setstate(RandomObject *self, PyObject *state)
return NULL;
}
self->index = (int)index;
for (i = 0; i < N; i++)
self->state[i] = new_state[i];
Py_INCREF(Py_None);
return Py_None;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment