mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	gh-94930: skipitem() in getargs.c should return non-NULL on error (GH-94931)
(cherry picked from commit 067f0da335)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									a914fa979e
								
							
						
					
					
						commit
						ec6ed6681d
					
				
					 4 changed files with 37 additions and 8 deletions
				
			
		|  | @ -878,9 +878,19 @@ def test_s_hash(self): | |||
|     def test_s_hash_int(self): | ||||
|         # "s#" without PY_SSIZE_T_CLEAN defined. | ||||
|         from _testcapi import getargs_s_hash_int | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int, "abc") | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int, x=42) | ||||
|         # getargs_s_hash_int() don't raise SystemError because skipitem() is not called. | ||||
|         from _testcapi import getargs_s_hash_int2 | ||||
|         buf = bytearray([1, 2]) | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int, buf, "abc") | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int, buf, x=42) | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int, buf, x="abc") | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int2, buf, ("abc",)) | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int2, buf, x=42) | ||||
|         self.assertRaises(SystemError, getargs_s_hash_int2, buf, x="abc") | ||||
|         buf.append(3)  # still mutable -- not locked by a buffer export | ||||
|         # getargs_s_hash_int(buf) may not raise SystemError because skipitem() | ||||
|         # is not called. But it is an implementation detail. | ||||
|         # getargs_s_hash_int(buf) | ||||
|         # getargs_s_hash_int2(buf) | ||||
| 
 | ||||
|     def test_z(self): | ||||
|         from _testcapi import getargs_z | ||||
|  |  | |||
|  | @ -0,0 +1,2 @@ | |||
| Fix ``SystemError`` raised when :c:func:`PyArg_ParseTupleAndKeywords` is | ||||
| used with ``#`` in ``(...)`` but without ``PY_SSIZE_T_CLEAN`` defined. | ||||
|  | @ -6002,6 +6002,7 @@ settrace_to_record(PyObject *self, PyObject *list) | |||
| static PyObject *negative_dictoffset(PyObject *, PyObject *); | ||||
| static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); | ||||
| static PyObject *getargs_s_hash_int(PyObject *, PyObject *, PyObject*); | ||||
| static PyObject *getargs_s_hash_int2(PyObject *, PyObject *, PyObject*); | ||||
| 
 | ||||
| static PyMethodDef TestMethods[] = { | ||||
|     {"raise_exception",         raise_exception,                 METH_VARARGS}, | ||||
|  | @ -6116,6 +6117,8 @@ static PyMethodDef TestMethods[] = { | |||
|     {"getargs_s_hash",          getargs_s_hash,                  METH_VARARGS}, | ||||
|     {"getargs_s_hash_int",      _PyCFunction_CAST(getargs_s_hash_int), | ||||
|       METH_VARARGS|METH_KEYWORDS}, | ||||
|     {"getargs_s_hash_int2",      _PyCFunction_CAST(getargs_s_hash_int2), | ||||
|       METH_VARARGS|METH_KEYWORDS}, | ||||
|     {"getargs_z",               getargs_z,                       METH_VARARGS}, | ||||
|     {"getargs_z_star",          getargs_z_star,                  METH_VARARGS}, | ||||
|     {"getargs_z_hash",          getargs_z_hash,                  METH_VARARGS}, | ||||
|  | @ -7835,11 +7838,27 @@ PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, | |||
| static PyObject * | ||||
| getargs_s_hash_int(PyObject *self, PyObject *args, PyObject *kwargs) | ||||
| { | ||||
|     static char *keywords[] = {"", "x", NULL}; | ||||
|     static char *keywords[] = {"", "", "x", NULL}; | ||||
|     Py_buffer buf = {NULL}; | ||||
|     const char *s; | ||||
|     int len; | ||||
|     int i = 0; | ||||
|     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s#i", keywords, &s, &len, &i)) | ||||
|     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|s#i", keywords, &buf, &s, &len, &i)) | ||||
|         return NULL; | ||||
|     PyBuffer_Release(&buf); | ||||
|     Py_RETURN_NONE; | ||||
| } | ||||
| 
 | ||||
| static PyObject * | ||||
| getargs_s_hash_int2(PyObject *self, PyObject *args, PyObject *kwargs) | ||||
| { | ||||
|     static char *keywords[] = {"", "", "x", NULL}; | ||||
|     Py_buffer buf = {NULL}; | ||||
|     const char *s; | ||||
|     int len; | ||||
|     int i = 0; | ||||
|     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|(s#)i", keywords, &buf, &s, &len, &i)) | ||||
|         return NULL; | ||||
|     PyBuffer_Release(&buf); | ||||
|     Py_RETURN_NONE; | ||||
| } | ||||
|  |  | |||
|  | @ -2695,9 +2695,7 @@ skipitem(const char **p_format, va_list *p_va, int flags) | |||
|             if (*format == '#') { | ||||
|                 if (p_va != NULL) { | ||||
|                     if (!(flags & FLAG_SIZE_T)) { | ||||
|                         PyErr_SetString(PyExc_SystemError, | ||||
|                                 "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); | ||||
|                         return NULL; | ||||
|                         return "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"; | ||||
|                     } | ||||
|                     (void) va_arg(*p_va, Py_ssize_t *); | ||||
|                 } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)