Kaydet (Commit) 1626a479 authored tarafından Mariatta's avatar Mariatta Kaydeden (comit) GitHub

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

(cherry picked from commit 9616a82e)
üst 96f50205
...@@ -311,6 +311,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps): ...@@ -311,6 +311,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
self.assertRaises(ValueError, self.gen.setstate, (1, None, None)) self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
def test_setstate_middle_arg(self): def test_setstate_middle_arg(self):
start_state = self.gen.getstate()
# Wrong type, s/b tuple # Wrong type, s/b tuple
self.assertRaises(TypeError, self.gen.setstate, (2, None, None)) self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
# Wrong length, s/b 625 # Wrong length, s/b 625
...@@ -324,6 +325,10 @@ class MersenneTwister_TestBasicOps(TestBasicOps): ...@@ -324,6 +325,10 @@ class MersenneTwister_TestBasicOps(TestBasicOps):
self.gen.setstate((2, (1,)*624+(625,), None)) self.gen.setstate((2, (1,)*624+(625,), None))
with self.assertRaises((ValueError, OverflowError)): with self.assertRaises((ValueError, OverflowError)):
self.gen.setstate((2, (1,)*624+(-1,), None)) 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): def test_referenceImplementation(self):
# Compare the python implementation with results from the original # Compare the python implementation with results from the original
......
...@@ -1021,6 +1021,7 @@ Milan Oberkirch ...@@ -1021,6 +1021,7 @@ Milan Oberkirch
Pascal Oberndoerfer Pascal Oberndoerfer
Jeffrey Ollie Jeffrey Ollie
Adam Olsen Adam Olsen
Bryan Olson
Grant Olson Grant Olson
Koray Oner Koray Oner
Piet van Oostrum Piet van Oostrum
......
...@@ -49,6 +49,9 @@ Extension Modules ...@@ -49,6 +49,9 @@ Extension Modules
Library 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-30310: tkFont now supports unicode options (e.g. font family).
- bpo-30414: multiprocessing.Queue._feed background running - bpo-30414: multiprocessing.Queue._feed background running
......
...@@ -341,6 +341,7 @@ random_setstate(RandomObject *self, PyObject *state) ...@@ -341,6 +341,7 @@ random_setstate(RandomObject *self, PyObject *state)
int i; int i;
unsigned long element; unsigned long element;
long index; long index;
unsigned long new_state[N];
if (!PyTuple_Check(state)) { if (!PyTuple_Check(state)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
...@@ -357,7 +358,7 @@ random_setstate(RandomObject *self, PyObject *state) ...@@ -357,7 +358,7 @@ random_setstate(RandomObject *self, PyObject *state)
element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
if (element == (unsigned long)-1 && PyErr_Occurred()) if (element == (unsigned long)-1 && PyErr_Occurred())
return NULL; 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)); index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
...@@ -368,6 +369,8 @@ random_setstate(RandomObject *self, PyObject *state) ...@@ -368,6 +369,8 @@ random_setstate(RandomObject *self, PyObject *state)
return NULL; return NULL;
} }
self->index = (int)index; self->index = (int)index;
for (i = 0; i < N; i++)
self->state[i] = new_state[i];
Py_INCREF(Py_None); Py_INCREF(Py_None);
return 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