pos is not guaranteed contiguous, and pypy increments past the end of the dict size --- bindings/python/gpiod/ext/request.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bindings/python/gpiod/ext/request.c b/bindings/python/gpiod/ext/request.c index e1a2a42..4e49289 100644 --- a/bindings/python/gpiod/ext/request.c +++ b/bindings/python/gpiod/ext/request.c @@ -206,6 +206,7 @@ static PyObject *request_set_values(request_object *self, PyObject *args) { PyObject *values, *key, *val, *val_stripped; Py_ssize_t pos = 0; + Py_ssize_t index = 0; int ret; ret = PyArg_ParseTuple(args, "O", &values); @@ -214,8 +215,10 @@ static PyObject *request_set_values(request_object *self, PyObject *args) clear_buffers(self); + // Note: pos may not be contiguous and in pypy, is incremented + // past the end of the dict size. while (PyDict_Next(values, &pos, &key, &val)) { - self->offsets[pos - 1] = Py_gpiod_PyLongAsUnsignedInt(key); + self->offsets[index] = Py_gpiod_PyLongAsUnsignedInt(key); if (PyErr_Occurred()) return NULL; @@ -223,15 +226,17 @@ static PyObject *request_set_values(request_object *self, PyObject *args) if (!val_stripped) return NULL; - self->values[pos - 1] = PyLong_AsLong(val_stripped); + self->values[index] = PyLong_AsLong(val_stripped); Py_DECREF(val_stripped); if (PyErr_Occurred()) return NULL; + + index += 1; } Py_BEGIN_ALLOW_THREADS; ret = gpiod_line_request_set_values_subset(self->request, - pos, + index, self->offsets, self->values); Py_END_ALLOW_THREADS; -- 2.39.5