diff options
Diffstat (limited to 'Modules/_randommodule.c')
-rw-r--r-- | Modules/_randommodule.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index bc9b04a..6540ab9 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -210,7 +210,7 @@ random_seed(RandomObject *self, PyObject *args) PyObject *masklower = NULL; PyObject *thirtytwo = NULL; PyObject *n = NULL; - unsigned long *key = NULL; + unsigned long *new_key, *key = NULL; unsigned long keymax; /* # of allocated slots in key */ unsigned long keyused; /* # of used slots in key */ int err; @@ -228,16 +228,17 @@ random_seed(RandomObject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } - /* If the arg is an int or long, use its absolute value; else use - * the absolute value of its hash code. + /* This algorithm relies on the number being unsigned. + * So: if the arg is a PyLong, use its absolute value. + * Otherwise use its hash value, cast to unsigned. */ if (PyLong_Check(arg)) n = PyNumber_Absolute(arg); else { - long hash = PyObject_Hash(arg); + Py_hash_t hash = PyObject_Hash(arg); if (hash == -1) goto Done; - n = PyLong_FromUnsignedLong((unsigned long)hash); + n = PyLong_FromSize_t((size_t)hash); } if (n == NULL) goto Done; @@ -283,14 +284,16 @@ random_seed(RandomObject *self, PyObject *args) n = newn; if (keyused >= keymax) { unsigned long bigger = keymax << 1; - if ((bigger >> 1) != keymax) { + if ((bigger >> 1) != keymax || + bigger > PY_SSIZE_T_MAX / sizeof(*key)) { PyErr_NoMemory(); goto Done; } - key = (unsigned long *)PyMem_Realloc(key, + new_key = (unsigned long *)PyMem_Realloc(key, bigger * sizeof(*key)); - if (key == NULL) + if (new_key == NULL) goto Done; + key = new_key; keymax = bigger; } assert(keyused < keymax); |