From aff42d767bd2ba90ed5f78ae4c4240ce8dc79796 Mon Sep 17 00:00:00 2001 From: lericson Date: Wed, 27 Jan 2010 11:41:07 +0100 Subject: [PATCH] Check for mappings in delete_multi and err out. Previously, this would cause internal trickery to go wrong and call an inner function with too many arguments, then fail. The error wouldn't bubble up either, and a SEGV would ensue. --- _pylibmcmodule.c | 22 +++++++++++++++++++++- tests.py | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/_pylibmcmodule.c b/_pylibmcmodule.c index 23ca112..3b9570c 100644 --- a/_pylibmcmodule.c +++ b/_pylibmcmodule.c @@ -859,6 +859,23 @@ static PyObject *PylibMC_Client_delete_multi(PylibMC_Client *self, &keys, &PyInt_Type, &time, &prefix)) return NULL; + /** + * Because of how DoMulti works, we have to prohibit the use of mappings + * here. Otherwise, the values of the mapping will be the second argument + * to the delete function; the time argument will then become a third + * argument, which delete doesn't take. + * + * So a mapping to DoMulti would produce calls like: + * DoMulti({"a": 1, "b": 2}, time=3) + * delete("a", 1, 3) + * delete("b", 2, 3) + */ + if (PyMapping_Check(keys)) { + PyErr_SetString(PyExc_TypeError, + "keys must be a sequence, not a mapping"); + return NULL; + } + if ((delete = PyObject_GetAttrString((PyObject *)self, "delete")) == NULL) return NULL; @@ -872,7 +889,10 @@ static PyObject *PylibMC_Client_delete_multi(PylibMC_Client *self, } Py_DECREF(delete); - if (PyList_GET_SIZE(retval) == 0) { + if (retval == NULL) + return NULL; + + if (PyList_Size(retval) == 0) { Py_DECREF(retval); retval = Py_True; } else { diff --git a/tests.py b/tests.py index 385284d..1eedc7d 100644 --- a/tests.py +++ b/tests.py @@ -57,6 +57,10 @@ Zero-key-test-time! False >>> c.set_multi({"": "hi"}) [''] +>>> c.delete_multi({"a": "b"}) +Traceback (most recent call last): + ... +TypeError: keys must be a sequence, not a mapping Timed stuff. The reason we, at UNIX times, set it two seconds in the future and then sleep for >3 is that memcached might round the time up and down and left