From 7511047125c543841f0b776de9ac39e27b52c10a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <> Date: Wed, 25 Oct 2017 00:00:00 +0000 Subject: [PATCH] Fix null pointer dereference in dbm.ndbm get. Change the default value in ndbm get method to None from b''. Previous default used to be represented with C value of NULL, and lead to a null pointer dereference when it was actually returned. This also makes the default values consistent with other implementations of dbm module. --- Lib/test/test_dbm_ndbm.py | 4 ++++ Modules/_dbmmodule.c | 4 ++-- Modules/clinic/_dbmmodule.c.h | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py index 49f4426e4c..bc45b8b6b4 100644 --- a/Lib/test/test_dbm_ndbm.py +++ b/Lib/test/test_dbm_ndbm.py @@ -25,6 +25,10 @@ class DbmTestCase(unittest.TestCase): self.assertIn('a', self.d) self.assertIn(b'a', self.d) self.assertEqual(self.d[b'bytes'], b'data') + self.assertIsNone(self.d.get(b'xxx')) + self.assertEqual(self.d.get(b'xxx', b'foo'), b'foo') + self.assertEqual(self.d.setdefault(b'xxx', b'foo'), b'foo') + self.assertEqual(self.d[b'xxx'], b'foo') self.d.close() def test_modes(self): diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 7e1344177b..f6c7846822 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -274,7 +274,7 @@ static PySequenceMethods dbm_as_sequence = { _dbm.dbm.get key: str(accept={str, robuffer}, zeroes=True) - default: object(c_default="NULL") = b'' + default: object = None / Return the value for key if present, otherwise default. @@ -283,7 +283,7 @@ Return the value for key if present, otherwise default. static PyObject * _dbm_dbm_get_impl(dbmobject *self, const char *key, Py_ssize_clean_t key_length, PyObject *default_value) -/*[clinic end generated code: output=b44f95eba8203d93 input=a3a279957f85eb6d]*/ +/*[clinic end generated code: output=b44f95eba8203d93 input=b788eba0ffad2e91]*/ /*[clinic end generated code: output=4f5c0e523eaf1251 input=9402c0af8582dc69]*/ { datum dbm_key, val; diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index c0e0b0b189..4bc16aefb7 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -39,7 +39,7 @@ _dbm_dbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(_dbm_dbm_get__doc__, -"get($self, key, default=b\'\', /)\n" +"get($self, key, default=None, /)\n" "--\n" "\n" "Return the value for key if present, otherwise default."); @@ -57,7 +57,7 @@ _dbm_dbm_get(dbmobject *self, PyObject **args, Py_ssize_t nargs) PyObject *return_value = NULL; const char *key; Py_ssize_clean_t key_length; - PyObject *default_value = NULL; + PyObject *default_value = Py_None; if (!_PyArg_ParseStack(args, nargs, "s#|O:get", &key, &key_length, &default_value)) { @@ -141,4 +141,4 @@ dbmopen(PyObject *module, PyObject **args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=627d28ce1f3188dc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=828255b052933a00 input=a9049054013a1b77]*/ -- 2.15.0.rc2