mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-33383: Fix crash in get() of the dbm.ndbm database object. (#6630)
This commit is contained in:
parent
5779483299
commit
2e38cc3933
7 changed files with 38 additions and 7 deletions
|
@ -86,12 +86,21 @@ class AnyDBMTestCase:
|
||||||
f = dbm.open(_fname, 'c')
|
f = dbm.open(_fname, 'c')
|
||||||
self._dict['g'] = f[b'g'] = b"indented"
|
self._dict['g'] = f[b'g'] = b"indented"
|
||||||
self.read_helper(f)
|
self.read_helper(f)
|
||||||
|
# setdefault() works as in the dict interface
|
||||||
|
self.assertEqual(f.setdefault(b'xxx', b'foo'), b'foo')
|
||||||
|
self.assertEqual(f[b'xxx'], b'foo')
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def test_anydbm_read(self):
|
def test_anydbm_read(self):
|
||||||
self.init_db()
|
self.init_db()
|
||||||
f = dbm.open(_fname, 'r')
|
f = dbm.open(_fname, 'r')
|
||||||
self.read_helper(f)
|
self.read_helper(f)
|
||||||
|
# get() works as in the dict interface
|
||||||
|
self.assertEqual(f.get(b'a'), self._dict['a'])
|
||||||
|
self.assertEqual(f.get(b'xxx', b'foo'), b'foo')
|
||||||
|
self.assertIsNone(f.get(b'xxx'))
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
f[b'xxx']
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def test_anydbm_keys(self):
|
def test_anydbm_keys(self):
|
||||||
|
|
|
@ -73,6 +73,9 @@ class DumbDBMTestCase(unittest.TestCase):
|
||||||
f = dumbdbm.open(_fname, 'w')
|
f = dumbdbm.open(_fname, 'w')
|
||||||
self._dict[b'g'] = f[b'g'] = b"indented"
|
self._dict[b'g'] = f[b'g'] = b"indented"
|
||||||
self.read_helper(f)
|
self.read_helper(f)
|
||||||
|
# setdefault() works as in the dict interface
|
||||||
|
self.assertEqual(f.setdefault(b'xxx', b'foo'), b'foo')
|
||||||
|
self.assertEqual(f[b'xxx'], b'foo')
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def test_dumbdbm_read(self):
|
def test_dumbdbm_read(self):
|
||||||
|
@ -85,6 +88,12 @@ class DumbDBMTestCase(unittest.TestCase):
|
||||||
with self.assertRaisesRegex(ValueError,
|
with self.assertRaisesRegex(ValueError,
|
||||||
'The database is opened for reading only'):
|
'The database is opened for reading only'):
|
||||||
del f[b'a']
|
del f[b'a']
|
||||||
|
# get() works as in the dict interface
|
||||||
|
self.assertEqual(f.get(b'a'), self._dict[b'a'])
|
||||||
|
self.assertEqual(f.get(b'xxx', b'foo'), b'foo')
|
||||||
|
self.assertIsNone(f.get(b'xxx'))
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
f[b'xxx']
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def test_dumbdbm_keys(self):
|
def test_dumbdbm_keys(self):
|
||||||
|
|
|
@ -32,9 +32,12 @@ class TestGdbm(unittest.TestCase):
|
||||||
self.assertIn(key, key_set)
|
self.assertIn(key, key_set)
|
||||||
key_set.remove(key)
|
key_set.remove(key)
|
||||||
key = self.g.nextkey(key)
|
key = self.g.nextkey(key)
|
||||||
self.assertRaises(KeyError, lambda: self.g['xxx'])
|
|
||||||
# get() and setdefault() work as in the dict interface
|
# get() and setdefault() work as in the dict interface
|
||||||
|
self.assertEqual(self.g.get(b'a'), b'b')
|
||||||
|
self.assertIsNone(self.g.get(b'xxx'))
|
||||||
self.assertEqual(self.g.get(b'xxx', b'foo'), b'foo')
|
self.assertEqual(self.g.get(b'xxx', b'foo'), b'foo')
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
self.g['xxx']
|
||||||
self.assertEqual(self.g.setdefault(b'xxx', b'foo'), b'foo')
|
self.assertEqual(self.g.setdefault(b'xxx', b'foo'), b'foo')
|
||||||
self.assertEqual(self.g[b'xxx'], b'foo')
|
self.assertEqual(self.g[b'xxx'], b'foo')
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class DbmTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_keys(self):
|
def test_keys(self):
|
||||||
self.d = dbm.ndbm.open(self.filename, 'c')
|
self.d = dbm.ndbm.open(self.filename, 'c')
|
||||||
self.assertTrue(self.d.keys() == [])
|
self.assertEqual(self.d.keys(), [])
|
||||||
self.d['a'] = 'b'
|
self.d['a'] = 'b'
|
||||||
self.d[b'bytes'] = b'data'
|
self.d[b'bytes'] = b'data'
|
||||||
self.d['12345678910'] = '019237410982340912840198242'
|
self.d['12345678910'] = '019237410982340912840198242'
|
||||||
|
@ -26,6 +26,14 @@ class DbmTestCase(unittest.TestCase):
|
||||||
self.assertIn('a', self.d)
|
self.assertIn('a', self.d)
|
||||||
self.assertIn(b'a', self.d)
|
self.assertIn(b'a', self.d)
|
||||||
self.assertEqual(self.d[b'bytes'], b'data')
|
self.assertEqual(self.d[b'bytes'], b'data')
|
||||||
|
# get() and setdefault() work as in the dict interface
|
||||||
|
self.assertEqual(self.d.get(b'a'), b'b')
|
||||||
|
self.assertIsNone(self.d.get(b'xxx'))
|
||||||
|
self.assertEqual(self.d.get(b'xxx', b'foo'), b'foo')
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
self.d['xxx']
|
||||||
|
self.assertEqual(self.d.setdefault(b'xxx', b'foo'), b'foo')
|
||||||
|
self.assertEqual(self.d[b'xxx'], b'foo')
|
||||||
self.d.close()
|
self.d.close()
|
||||||
|
|
||||||
def test_modes(self):
|
def test_modes(self):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when
|
||||||
|
it is called with a single argument.
|
|
@ -274,7 +274,7 @@ static PySequenceMethods dbm_as_sequence = {
|
||||||
_dbm.dbm.get
|
_dbm.dbm.get
|
||||||
|
|
||||||
key: str(accept={str, robuffer}, zeroes=True)
|
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.
|
Return the value for key if present, otherwise default.
|
||||||
|
@ -283,7 +283,7 @@ Return the value for key if present, otherwise default.
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_dbm_dbm_get_impl(dbmobject *self, const char *key,
|
_dbm_dbm_get_impl(dbmobject *self, const char *key,
|
||||||
Py_ssize_clean_t key_length, PyObject *default_value)
|
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]*/
|
/*[clinic end generated code: output=4f5c0e523eaf1251 input=9402c0af8582dc69]*/
|
||||||
{
|
{
|
||||||
datum dbm_key, val;
|
datum dbm_key, val;
|
||||||
|
|
|
@ -39,7 +39,7 @@ _dbm_dbm_keys(dbmobject *self, PyObject *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_dbm_dbm_get__doc__,
|
PyDoc_STRVAR(_dbm_dbm_get__doc__,
|
||||||
"get($self, key, default=b\'\', /)\n"
|
"get($self, key, default=None, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Return the value for key if present, otherwise default.");
|
"Return the value for key if present, otherwise default.");
|
||||||
|
@ -57,7 +57,7 @@ _dbm_dbm_get(dbmobject *self, PyObject *const *args, Py_ssize_t nargs)
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
const char *key;
|
const char *key;
|
||||||
Py_ssize_clean_t key_length;
|
Py_ssize_clean_t key_length;
|
||||||
PyObject *default_value = NULL;
|
PyObject *default_value = Py_None;
|
||||||
|
|
||||||
if (!_PyArg_ParseStack(args, nargs, "s#|O:get",
|
if (!_PyArg_ParseStack(args, nargs, "s#|O:get",
|
||||||
&key, &key_length, &default_value)) {
|
&key, &key_length, &default_value)) {
|
||||||
|
@ -141,4 +141,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=5c858b4080a011a4 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=1cba297bc8d7c2c2 input=a9049054013a1b77]*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue