From 80431fe7cf51b94c7ee4b063df4d6a16d1002fd3 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 3 May 2023 10:39:30 +0300 Subject: [PATCH] pyglue: use Py_ssize_t in random data generation functions Prefer 'Py_ssize_t' over 'int' in random data generation functions to match both Python and (internally used through the library layer) GnuTLS APIs, and use PyUnicode_FromStringAndSize() where the data size is known. Signed-off-by: Dmitry Antipov Reviewed-by: Joseph Sutton Reviewed-by: Andrew Bartlett [abartlet@samba.org Fixed comments to correctly match the new check for just negative numbers] --- python/pyglue.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/python/pyglue.c b/python/pyglue.c index 64be7389b70..808a86b444f 100644 --- a/python/pyglue.c +++ b/python/pyglue.c @@ -34,40 +34,41 @@ static PyObject *PyExc_DsExtendedError; static PyObject *py_generate_random_str(PyObject *self, PyObject *args) { - int len; + Py_ssize_t len; PyObject *ret; char *retstr; - if (!PyArg_ParseTuple(args, "i", &len)) { + + if (!PyArg_ParseTuple(args, "n", &len)) { return NULL; } if (len < 0) { PyErr_Format(PyExc_ValueError, - "random string length should be positive, not %d", + "random string length should be positive, not %zd", len); return NULL; } retstr = generate_random_str(NULL, len); - ret = PyUnicode_FromString(retstr); + ret = PyUnicode_FromStringAndSize(retstr, len); talloc_free(retstr); return ret; } static PyObject *py_generate_random_password(PyObject *self, PyObject *args) { - int min, max; + Py_ssize_t min, max; PyObject *ret; char *retstr; - if (!PyArg_ParseTuple(args, "ii", &min, &max)) { + + if (!PyArg_ParseTuple(args, "nn", &min, &max)) { return NULL; } if (max < 0 || min < 0) { /* - * The real range checks happen in generate_random_password(). - * Here we are just checking the values won't overflow into - * numbers when cast to size_t. + * The real range checks happens in generate_random_password(). + * Here just filter out any negative numbers. */ PyErr_Format(PyExc_ValueError, - "invalid range: %d - %d", + "invalid range: %zd - %zd", min, max); return NULL; } @@ -76,7 +77,7 @@ static PyObject *py_generate_random_password(PyObject *self, PyObject *args) if (retstr == NULL) { if (errno == EINVAL) { PyErr_Format(PyExc_ValueError, - "invalid range: %d - %d", + "invalid range: %zd - %zd", min, max); } return NULL; @@ -88,21 +89,21 @@ static PyObject *py_generate_random_password(PyObject *self, PyObject *args) static PyObject *py_generate_random_machine_password(PyObject *self, PyObject *args) { - int min, max; + Py_ssize_t min, max; PyObject *ret; char *retstr; - if (!PyArg_ParseTuple(args, "ii", &min, &max)) { + + if (!PyArg_ParseTuple(args, "nn", &min, &max)) { return NULL; } if (max < 0 || min < 0) { /* - * The real range checks happen in + * The real range checks happens in * generate_random_machine_password(). - * Here we are just checking the values won't overflow into - * numbers when cast to size_t. + * Here we are just filter out any negative numbers. */ PyErr_Format(PyExc_ValueError, - "invalid range: %d - %d", + "invalid range: %zd - %zd", min, max); return NULL; } @@ -111,7 +112,7 @@ static PyObject *py_generate_random_machine_password(PyObject *self, PyObject *a if (retstr == NULL) { if (errno == EINVAL) { PyErr_Format(PyExc_ValueError, - "invalid range: %d - %d", + "invalid range: %zd - %zd", min, max); } return NULL; @@ -134,16 +135,16 @@ static PyObject *py_check_password_quality(PyObject *self, PyObject *args) static PyObject *py_generate_random_bytes(PyObject *self, PyObject *args) { - int len; + Py_ssize_t len; PyObject *ret; uint8_t *bytes = NULL; - if (!PyArg_ParseTuple(args, "i", &len)) { + if (!PyArg_ParseTuple(args, "n", &len)) { return NULL; } if (len < 0) { PyErr_Format(PyExc_ValueError, - "random bytes length should be positive, not %d", + "random bytes length should be positive, not %zd", len); return NULL; }