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+
122143static PyObject *
123144dbm_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
172193dbm_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