Skip to content

Commit c5a216e

Browse files
authored
bpo-8677: use PY_SSIZE_T_CLEAN in Modules/_gdbmodule.c (GH-12464)
1 parent 9b4a1b1 commit c5a216e

1 file changed

Lines changed: 27 additions & 9 deletions

File tree

Modules/_gdbmmodule.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/* Author: Anthony Baxter, after dbmmodule.c */
44
/* Doc strings: Mitch Chapman */
55

6-
6+
#define PY_SSIZE_T_CLEAN
77
#include "Python.h"
88

99
#include <sys/types.h>
@@ -119,15 +119,36 @@ dbm_length(dbmobject *dp)
119119
return dp->di_size;
120120
}
121121

122+
// Wrapper function for PyArg_Parse(o, "s#", &d.dptr, &d.size).
123+
// This function is needed to support PY_SSIZE_T_CLEAN.
124+
// Return 1 on success, same to PyArg_Parse().
125+
static int
126+
parse_datum(PyObject *o, datum *d, const char *failmsg)
127+
{
128+
Py_ssize_t size;
129+
if (!PyArg_Parse(o, "s#", &d->dptr, &size)) {
130+
if (failmsg != NULL) {
131+
PyErr_SetString(PyExc_TypeError, failmsg);
132+
}
133+
return 0;
134+
}
135+
if (INT_MAX < size) {
136+
PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
137+
return 0;
138+
}
139+
d->dsize = size;
140+
return 1;
141+
}
142+
122143
static PyObject *
123144
dbm_subscript(dbmobject *dp, PyObject *key)
124145
{
125146
PyObject *v;
126147
datum drec, krec;
127148

128-
if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
149+
if (!parse_datum(key, &krec, NULL)) {
129150
return NULL;
130-
151+
}
131152
if (dp->di_dbm == NULL) {
132153
PyErr_SetString(DbmError,
133154
"GDBM object has already been closed");
@@ -172,10 +193,9 @@ static int
172193
dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
173194
{
174195
datum krec, drec;
196+
const char *failmsg = "gdbm mappings have bytes or string indices only";
175197

176-
if (!PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
177-
PyErr_SetString(PyExc_TypeError,
178-
"gdbm mappings have bytes or string indices only");
198+
if (!parse_datum(v, &krec, failmsg)) {
179199
return -1;
180200
}
181201
if (dp->di_dbm == NULL) {
@@ -196,9 +216,7 @@ dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
196216
}
197217
}
198218
else {
199-
if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) {
200-
PyErr_SetString(PyExc_TypeError,
201-
"gdbm mappings have bytes or string elements only");
219+
if (!parse_datum(w, &drec, failmsg)) {
202220
return -1;
203221
}
204222
errno = 0;

0 commit comments

Comments
 (0)