@@ -17,10 +17,11 @@ int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
1717static int vgetargs1 (PyObject * , char * , va_list * , int );
1818static void seterror (int , char * , int * , char * , char * );
1919static char * convertitem (PyObject * , char * * , va_list * , int * , char * ,
20- size_t );
20+ size_t , PyObject * * );
2121static char * converttuple (PyObject * , char * * , va_list * ,
22- int * , char * , size_t , int );
23- static char * convertsimple (PyObject * , char * * , va_list * , char * , size_t );
22+ int * , char * , size_t , int , PyObject * * );
23+ static char * convertsimple (PyObject * , char * * , va_list * , char * ,
24+ size_t , PyObject * * );
2425static int convertbuffer (PyObject * , void * * p , char * * );
2526
2627static int vgetargskeywords (PyObject * , PyObject * ,
@@ -72,6 +73,49 @@ PyArg_VaParse(PyObject *args, char *format, va_list va)
7273}
7374
7475
76+ /* Handle cleanup of allocated memory in case of exception */
77+
78+ static int
79+ addcleanup (void * ptr , PyObject * * freelist )
80+ {
81+ PyObject * cobj ;
82+ if (!* freelist ) {
83+ * freelist = PyList_New (0 );
84+ if (!* freelist ) {
85+ PyMem_FREE (ptr );
86+ return -1 ;
87+ }
88+ }
89+ cobj = PyCObject_FromVoidPtr (ptr , NULL );
90+ if (!cobj ) {
91+ PyMem_FREE (ptr );
92+ return -1 ;
93+ }
94+ if (PyList_Append (* freelist , cobj )) {
95+ PyMem_FREE (ptr );
96+ Py_DECREF (cobj );
97+ return -1 ;
98+ }
99+ Py_DECREF (cobj );
100+ return 0 ;
101+ }
102+
103+ static int
104+ cleanreturn (int retval , PyObject * freelist )
105+ {
106+ if (freelist ) {
107+ if ((retval ) == 0 ) {
108+ int len = PyList_GET_SIZE (freelist ), i ;
109+ for (i = 0 ; i < len ; i ++ )
110+ PyMem_FREE (PyCObject_AsVoidPtr (
111+ PyList_GET_ITEM (freelist , i )));
112+ }
113+ Py_DECREF (freelist );
114+ }
115+ return retval ;
116+ }
117+
118+
75119static int
76120vgetargs1 (PyObject * args , char * format , va_list * p_va , int compat )
77121{
@@ -86,6 +130,7 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat)
86130 char * formatsave = format ;
87131 int i , len ;
88132 char * msg ;
133+ PyObject * freelist = NULL ;
89134
90135 assert (compat || (args != (PyObject * )NULL ));
91136
@@ -157,11 +202,11 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat)
157202 return 0 ;
158203 }
159204 msg = convertitem (args , & format , p_va , levels , msgbuf ,
160- sizeof (msgbuf ));
205+ sizeof (msgbuf ), & freelist );
161206 if (msg == NULL )
162- return 1 ;
207+ return cleanreturn ( 1 , freelist ) ;
163208 seterror (levels [0 ], msg , levels + 1 , fname , message );
164- return 0 ;
209+ return cleanreturn ( 0 , freelist ) ;
165210 }
166211 else {
167212 PyErr_SetString (PyExc_SystemError ,
@@ -200,10 +245,10 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat)
200245 if (* format == '|' )
201246 format ++ ;
202247 msg = convertitem (PyTuple_GET_ITEM (args , i ), & format , p_va ,
203- levels , msgbuf , sizeof (msgbuf ));
248+ levels , msgbuf , sizeof (msgbuf ), & freelist );
204249 if (msg ) {
205250 seterror (i + 1 , msg , levels , fname , message );
206- return 0 ;
251+ return cleanreturn ( 0 , freelist ) ;
207252 }
208253 }
209254
@@ -212,10 +257,10 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat)
212257 * format != '|' && * format != ':' && * format != ';' ) {
213258 PyErr_Format (PyExc_SystemError ,
214259 "bad format string: %.200s" , formatsave );
215- return 0 ;
260+ return cleanreturn ( 0 , freelist ) ;
216261 }
217262
218- return 1 ;
263+ return cleanreturn ( 1 , freelist ) ;
219264}
220265
221266
@@ -277,7 +322,7 @@ seterror(int iarg, char *msg, int *levels, char *fname, char *message)
277322
278323static char *
279324converttuple (PyObject * arg , char * * p_format , va_list * p_va , int * levels ,
280- char * msgbuf , size_t bufsize , int toplevel )
325+ char * msgbuf , size_t bufsize , int toplevel , PyObject * * freelist )
281326{
282327 int level = 0 ;
283328 int n = 0 ;
@@ -327,7 +372,7 @@ converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels,
327372 PyObject * item ;
328373 item = PySequence_GetItem (arg , i );
329374 msg = convertitem (item , & format , p_va , levels + 1 , msgbuf ,
330- bufsize );
375+ bufsize , freelist );
331376 /* PySequence_GetItem calls tp->sq_item, which INCREFs */
332377 Py_XDECREF (item );
333378 if (msg != NULL ) {
@@ -345,20 +390,21 @@ converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels,
345390
346391static char *
347392convertitem (PyObject * arg , char * * p_format , va_list * p_va , int * levels ,
348- char * msgbuf , size_t bufsize )
393+ char * msgbuf , size_t bufsize , PyObject * * freelist )
349394{
350395 char * msg ;
351396 char * format = * p_format ;
352397
353398 if (* format == '(' /* ')' */ ) {
354399 format ++ ;
355400 msg = converttuple (arg , & format , p_va , levels , msgbuf ,
356- bufsize , 0 );
401+ bufsize , 0 , freelist );
357402 if (msg == NULL )
358403 format ++ ;
359404 }
360405 else {
361- msg = convertsimple (arg , & format , p_va , msgbuf , bufsize );
406+ msg = convertsimple (arg , & format , p_va , msgbuf , bufsize ,
407+ freelist );
362408 if (msg != NULL )
363409 levels [0 ] = 0 ;
364410 }
@@ -409,7 +455,7 @@ float_argument_error(PyObject *arg)
409455
410456static char *
411457convertsimple (PyObject * arg , char * * p_format , va_list * p_va , char * msgbuf ,
412- size_t bufsize )
458+ size_t bufsize , PyObject * * freelist )
413459{
414460 char * format = * p_format ;
415461 char c = * format ++ ;
@@ -836,10 +882,12 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
836882 int * buffer_len = va_arg (* p_va , int * );
837883
838884 format ++ ;
839- if (buffer_len == NULL )
885+ if (buffer_len == NULL ) {
886+ Py_DECREF (s );
840887 return converterr (
841888 "(buffer_len is NULL)" ,
842889 arg , msgbuf , bufsize );
890+ }
843891 if (* buffer == NULL ) {
844892 * buffer = PyMem_NEW (char , size + 1 );
845893 if (* buffer == NULL ) {
@@ -848,6 +896,12 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
848896 "(memory error)" ,
849897 arg , msgbuf , bufsize );
850898 }
899+ if (addcleanup (* buffer , freelist )) {
900+ Py_DECREF (s );
901+ return converterr (
902+ "(cleanup problem)" ,
903+ arg , msgbuf , bufsize );
904+ }
851905 } else {
852906 if (size + 1 > * buffer_len ) {
853907 Py_DECREF (s );
@@ -874,16 +928,23 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
874928 PyMem_Free()ing it after usage
875929
876930 */
877- if ((int )strlen (PyString_AS_STRING (s )) != size )
931+ if ((int )strlen (PyString_AS_STRING (s )) != size ) {
932+ Py_DECREF (s );
878933 return converterr (
879934 "(encoded string without NULL bytes)" ,
880935 arg , msgbuf , bufsize );
936+ }
881937 * buffer = PyMem_NEW (char , size + 1 );
882938 if (* buffer == NULL ) {
883939 Py_DECREF (s );
884940 return converterr ("(memory error)" ,
885941 arg , msgbuf , bufsize );
886942 }
943+ if (addcleanup (* buffer , freelist )) {
944+ Py_DECREF (s );
945+ return converterr ("(cleanup problem)" ,
946+ arg , msgbuf , bufsize );
947+ }
887948 memcpy (* buffer ,
888949 PyString_AS_STRING (s ),
889950 size + 1 );
@@ -1103,6 +1164,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
11031164 char * formatsave ;
11041165 int i , len , nargs , nkeywords ;
11051166 char * msg , * * p ;
1167+ PyObject * freelist = NULL ;
11061168
11071169 assert (args != NULL && PyTuple_Check (args ));
11081170 assert (keywords == NULL || PyDict_Check (keywords ));
@@ -1227,16 +1289,16 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
12271289 if (* format == '|' )
12281290 format ++ ;
12291291 msg = convertitem (PyTuple_GET_ITEM (args , i ), & format , p_va ,
1230- levels , msgbuf , sizeof (msgbuf ));
1292+ levels , msgbuf , sizeof (msgbuf ), & freelist );
12311293 if (msg ) {
12321294 seterror (i + 1 , msg , levels , fname , message );
1233- return 0 ;
1295+ return cleanreturn ( 0 , freelist ) ;
12341296 }
12351297 }
12361298
12371299 /* handle no keyword parameters in call */
12381300 if (nkeywords == 0 )
1239- return 1 ;
1301+ return cleanreturn ( 1 , freelist );
12401302
12411303 /* convert the keyword arguments; this uses the format
12421304 string where it was left after processing args */
@@ -1248,23 +1310,23 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
12481310 if (item != NULL ) {
12491311 Py_INCREF (item );
12501312 msg = convertitem (item , & format , p_va , levels , msgbuf ,
1251- sizeof (msgbuf ));
1313+ sizeof (msgbuf ), & freelist );
12521314 Py_DECREF (item );
12531315 if (msg ) {
12541316 seterror (i + 1 , msg , levels , fname , message );
1255- return 0 ;
1317+ return cleanreturn ( 0 , freelist ) ;
12561318 }
12571319 -- nkeywords ;
12581320 if (nkeywords == 0 )
12591321 break ;
12601322 }
12611323 else if (PyErr_Occurred ())
1262- return 0 ;
1324+ return cleanreturn ( 0 , freelist ) ;
12631325 else {
12641326 msg = skipitem (& format , p_va );
12651327 if (msg ) {
12661328 seterror (i + 1 , msg , levels , fname , message );
1267- return 0 ;
1329+ return cleanreturn ( 0 , freelist ) ;
12681330 }
12691331 }
12701332 }
@@ -1279,7 +1341,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
12791341 if (!PyString_Check (key )) {
12801342 PyErr_SetString (PyExc_TypeError ,
12811343 "keywords must be strings" );
1282- return 0 ;
1344+ return cleanreturn ( 0 , freelist ) ;
12831345 }
12841346 ks = PyString_AsString (key );
12851347 for (i = 0 ; i < max ; i ++ ) {
@@ -1293,12 +1355,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
12931355 "'%s' is an invalid keyword "
12941356 "argument for this function" ,
12951357 ks );
1296- return 0 ;
1358+ return cleanreturn ( 0 , freelist ) ;
12971359 }
12981360 }
12991361 }
13001362
1301- return 1 ;
1363+ return cleanreturn ( 1 , freelist ) ;
13021364}
13031365
13041366
0 commit comments