gh-104922: Make PY_SSIZE_T_CLEAN not mandatory again (#105051)

This commit is contained in:
Inada Naoki 2023-05-31 18:38:55 +09:00 committed by GitHub
parent f90d3f68db
commit adccff3b3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 105 additions and 397 deletions

View file

@ -12,44 +12,17 @@
#ifdef __cplusplus
extern "C" {
#endif
int PyArg_Parse(PyObject *, const char *, ...);
int PyArg_ParseTuple(PyObject *, const char *, ...);
int PyArg_VaParse(PyObject *, const char *, va_list);
int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
const char *, char **, ...);
int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
const char *, char **, va_list);
int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
struct _PyArg_Parser *, ...);
int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
struct _PyArg_Parser *, va_list);
#ifdef HAVE_DECLSPEC_DLL
/* Export functions */
/* Export Stable ABIs (abi only) */
PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...);
PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs,
const char *format, ...);
PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs,
PyObject *kwnames,
struct _PyArg_Parser *parser, ...);
PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
const char *, char **, ...);
PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
const char *, char **, va_list);
PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
struct _PyArg_Parser *, ...);
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
struct _PyArg_Parser *, va_list);
#endif
#define FLAG_COMPAT 1
#define FLAG_SIZE_T 2
typedef int (*destr_t)(PyObject *, void *);
@ -114,7 +87,7 @@ _PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
va_list va;
va_start(va, format);
retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
retval = vgetargs1(args, format, &va, FLAG_COMPAT);
va_end(va);
return retval;
}
@ -132,14 +105,14 @@ PyArg_ParseTuple(PyObject *args, const char *format, ...)
return retval;
}
PyAPI_FUNC(int)
int
_PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
{
int retval;
va_list va;
va_start(va, format);
retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
retval = vgetargs1(args, format, &va, 0);
va_end(va);
return retval;
}
@ -157,19 +130,6 @@ _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, .
return retval;
}
PyAPI_FUNC(int)
_PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
{
int retval;
va_list va;
va_start(va, format);
retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T);
va_end(va);
return retval;
}
int
PyArg_VaParse(PyObject *args, const char *format, va_list va)
{
@ -183,7 +143,7 @@ PyArg_VaParse(PyObject *args, const char *format, va_list va)
return retval;
}
PyAPI_FUNC(int)
int
_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
{
va_list lva;
@ -191,7 +151,7 @@ _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
va_copy(lva, va);
retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
retval = vgetargs1(args, format, &lva, 0);
va_end(lva);
return retval;
}
@ -657,13 +617,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
char *msgbuf, size_t bufsize, freelist_t *freelist)
{
#define RETURN_ERR_OCCURRED return msgbuf
/* For # codes */
#define REQUIRE_PY_SSIZE_T_CLEAN \
if (!(flags & FLAG_SIZE_T)) { \
PyErr_SetString(PyExc_SystemError, \
"PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \
RETURN_ERR_OCCURRED; \
}
const char *format = *p_format;
char c = *format++;
@ -917,7 +870,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if (count < 0)
return converterr(buf, arg, msgbuf, bufsize);
if (*format == '#') {
REQUIRE_PY_SSIZE_T_CLEAN;
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
*psize = count;
format++;
@ -961,7 +913,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
} else if (*format == '#') { /* a string or read-only bytes-like object */
/* "s#" or "z#" */
const void **p = (const void **)va_arg(*p_va, const char **);
REQUIRE_PY_SSIZE_T_CLEAN;
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
if (c == 'z' && arg == Py_None) {
@ -1099,7 +1050,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
trailing 0-byte
*/
REQUIRE_PY_SSIZE_T_CLEAN;
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
format++;
@ -1274,7 +1224,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
*p_format = format;
return NULL;
#undef REQUIRE_PY_SSIZE_T_CLEAN
#undef RETURN_ERR_OCCURRED
}
@ -1343,7 +1292,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args,
return retval;
}
PyAPI_FUNC(int)
int
_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
PyObject *keywords,
const char *format,
@ -1363,7 +1312,7 @@ _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
va_start(va, kwlist);
retval = vgetargskeywords(args, keywords, format,
kwlist, &va, FLAG_SIZE_T);
kwlist, &va, 0);
va_end(va);
return retval;
}
@ -1394,7 +1343,7 @@ PyArg_VaParseTupleAndKeywords(PyObject *args,
return retval;
}
PyAPI_FUNC(int)
int
_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
PyObject *keywords,
const char *format,
@ -1415,7 +1364,7 @@ _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
va_copy(lva, va);
retval = vgetargskeywords(args, keywords, format,
kwlist, &lva, FLAG_SIZE_T);
kwlist, &lva, 0);
va_end(lva);
return retval;
}
@ -1433,7 +1382,7 @@ _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
return retval;
}
PyAPI_FUNC(int)
int
_PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
struct _PyArg_Parser *parser, ...)
{
@ -1441,12 +1390,12 @@ _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
va_list va;
va_start(va, parser);
retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T);
retval = vgetargskeywordsfast(args, keywords, parser, &va, 0);
va_end(va);
return retval;
}
PyAPI_FUNC(int)
int
_PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
struct _PyArg_Parser *parser, ...)
{
@ -1459,7 +1408,7 @@ _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *
return retval;
}
PyAPI_FUNC(int)
int
_PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
struct _PyArg_Parser *parser, ...)
{
@ -1467,7 +1416,7 @@ _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyOb
va_list va;
va_start(va, parser);
retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T);
retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0);
va_end(va);
return retval;
}
@ -1487,20 +1436,6 @@ _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
return retval;
}
PyAPI_FUNC(int)
_PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
struct _PyArg_Parser *parser, va_list va)
{
int retval;
va_list lva;
va_copy(lva, va);
retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T);
va_end(lva);
return retval;
}
static void
error_unexpected_keyword_arg(PyObject *kwargs, PyObject *kwnames, PyObject *kwtuple, const char *fname)
{
@ -2710,9 +2645,6 @@ skipitem(const char **p_format, va_list *p_va, int flags)
}
if (*format == '#') {
if (p_va != NULL) {
if (!(flags & FLAG_SIZE_T)) {
return "PY_SSIZE_T_CLEAN macro must be defined for '#' formats";
}
(void) va_arg(*p_va, Py_ssize_t *);
}
format++;

View file

@ -5,11 +5,9 @@
#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_object.h" // _PyType_IsReady()
#define FLAG_SIZE_T 1
typedef double va_double;
static PyObject *va_build_value(const char *, va_list, int);
static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*);
static PyObject *va_build_value(const char *, va_list);
int
@ -84,21 +82,21 @@ countformat(const char *format, char endchar)
/* Generic function to create a value -- the inverse of getargs() */
/* After an original idea and first implementation by Steven Miale */
static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t, int);
static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int);
static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int);
static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int);
static PyObject *do_mkvalue(const char**, va_list *, int);
static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t);
static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t);
static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t);
static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t);
static PyObject *do_mkvalue(const char**, va_list *);
static void
do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n)
{
assert(PyErr_Occurred());
PyObject *v = PyTuple_New(n);
for (Py_ssize_t i = 0; i < n; i++) {
PyObject *exc = PyErr_GetRaisedException();
PyObject *w = do_mkvalue(p_format, p_va, flags);
PyObject *w = do_mkvalue(p_format, p_va);
PyErr_SetRaisedException(exc);
if (w != NULL) {
if (v != NULL) {
@ -121,7 +119,7 @@ do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int
}
static PyObject *
do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n)
{
PyObject *d;
Py_ssize_t i;
@ -130,27 +128,27 @@ do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int
if (n % 2) {
PyErr_SetString(PyExc_SystemError,
"Bad dict format");
do_ignore(p_format, p_va, endchar, n, flags);
do_ignore(p_format, p_va, endchar, n);
return NULL;
}
/* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */
if ((d = PyDict_New()) == NULL) {
do_ignore(p_format, p_va, endchar, n, flags);
do_ignore(p_format, p_va, endchar, n);
return NULL;
}
for (i = 0; i < n; i+= 2) {
PyObject *k, *v;
k = do_mkvalue(p_format, p_va, flags);
k = do_mkvalue(p_format, p_va);
if (k == NULL) {
do_ignore(p_format, p_va, endchar, n - i - 1, flags);
do_ignore(p_format, p_va, endchar, n - i - 1);
Py_DECREF(d);
return NULL;
}
v = do_mkvalue(p_format, p_va, flags);
v = do_mkvalue(p_format, p_va);
if (v == NULL || PyDict_SetItem(d, k, v) < 0) {
do_ignore(p_format, p_va, endchar, n - i - 2, flags);
do_ignore(p_format, p_va, endchar, n - i - 2);
Py_DECREF(k);
Py_XDECREF(v);
Py_DECREF(d);
@ -171,7 +169,7 @@ do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int
}
static PyObject *
do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n)
{
PyObject *v;
Py_ssize_t i;
@ -181,13 +179,13 @@ do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int
refcounts on any 'N' arguments. */
v = PyList_New(n);
if (v == NULL) {
do_ignore(p_format, p_va, endchar, n, flags);
do_ignore(p_format, p_va, endchar, n);
return NULL;
}
for (i = 0; i < n; i++) {
PyObject *w = do_mkvalue(p_format, p_va, flags);
PyObject *w = do_mkvalue(p_format, p_va);
if (w == NULL) {
do_ignore(p_format, p_va, endchar, n - i - 1, flags);
do_ignore(p_format, p_va, endchar, n - i - 1);
Py_DECREF(v);
return NULL;
}
@ -206,7 +204,7 @@ do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int
static int
do_mkstack(PyObject **stack, const char **p_format, va_list *p_va,
char endchar, Py_ssize_t n, int flags)
char endchar, Py_ssize_t n)
{
Py_ssize_t i;
@ -216,9 +214,9 @@ do_mkstack(PyObject **stack, const char **p_format, va_list *p_va,
/* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */
for (i = 0; i < n; i++) {
PyObject *w = do_mkvalue(p_format, p_va, flags);
PyObject *w = do_mkvalue(p_format, p_va);
if (w == NULL) {
do_ignore(p_format, p_va, endchar, n - i - 1, flags);
do_ignore(p_format, p_va, endchar, n - i - 1);
goto error;
}
stack[i] = w;
@ -242,7 +240,7 @@ error:
}
static PyObject *
do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n)
{
PyObject *v;
Py_ssize_t i;
@ -251,13 +249,13 @@ do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int
/* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */
if ((v = PyTuple_New(n)) == NULL) {
do_ignore(p_format, p_va, endchar, n, flags);
do_ignore(p_format, p_va, endchar, n);
return NULL;
}
for (i = 0; i < n; i++) {
PyObject *w = do_mkvalue(p_format, p_va, flags);
PyObject *w = do_mkvalue(p_format, p_va);
if (w == NULL) {
do_ignore(p_format, p_va, endchar, n - i - 1, flags);
do_ignore(p_format, p_va, endchar, n - i - 1);
Py_DECREF(v);
return NULL;
}
@ -275,28 +273,21 @@ do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int
}
static PyObject *
do_mkvalue(const char **p_format, va_list *p_va, int flags)
do_mkvalue(const char **p_format, va_list *p_va)
{
#define ERROR_NEED_PY_SSIZE_T_CLEAN \
{ \
PyErr_SetString(PyExc_SystemError, \
"PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \
return NULL; \
}
for (;;) {
switch (*(*p_format)++) {
case '(':
return do_mktuple(p_format, p_va, ')',
countformat(*p_format, ')'), flags);
countformat(*p_format, ')'));
case '[':
return do_mklist(p_format, p_va, ']',
countformat(*p_format, ']'), flags);
countformat(*p_format, ']'));
case '{':
return do_mkdict(p_format, p_va, '}',
countformat(*p_format, '}'), flags);
countformat(*p_format, '}'));
case 'b':
case 'B':
@ -342,13 +333,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags)
Py_ssize_t n;
if (**p_format == '#') {
++*p_format;
if (flags & FLAG_SIZE_T) {
n = va_arg(*p_va, Py_ssize_t);
}
else {
n = va_arg(*p_va, int);
ERROR_NEED_PY_SSIZE_T_CLEAN;
}
n = va_arg(*p_va, Py_ssize_t);
}
else
n = -1;
@ -392,13 +377,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags)
Py_ssize_t n;
if (**p_format == '#') {
++*p_format;
if (flags & FLAG_SIZE_T) {
n = va_arg(*p_va, Py_ssize_t);
}
else {
n = va_arg(*p_va, int);
ERROR_NEED_PY_SSIZE_T_CLEAN;
}
n = va_arg(*p_va, Py_ssize_t);
}
else
n = -1;
@ -427,13 +406,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags)
Py_ssize_t n;
if (**p_format == '#') {
++*p_format;
if (flags & FLAG_SIZE_T) {
n = va_arg(*p_va, Py_ssize_t);
}
else {
n = va_arg(*p_va, int);
ERROR_NEED_PY_SSIZE_T_CLEAN;
}
n = va_arg(*p_va, Py_ssize_t);
}
else
n = -1;
@ -499,8 +472,6 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags)
}
}
#undef ERROR_NEED_PY_SSIZE_T_CLEAN
}
@ -510,18 +481,18 @@ Py_BuildValue(const char *format, ...)
va_list va;
PyObject* retval;
va_start(va, format);
retval = va_build_value(format, va, 0);
retval = va_build_value(format, va);
va_end(va);
return retval;
}
PyObject *
PyAPI_FUNC(PyObject *) /* abi only */
_Py_BuildValue_SizeT(const char *format, ...)
{
va_list va;
PyObject* retval;
va_start(va, format);
retval = va_build_value(format, va, FLAG_SIZE_T);
retval = va_build_value(format, va);
va_end(va);
return retval;
}
@ -529,17 +500,17 @@ _Py_BuildValue_SizeT(const char *format, ...)
PyObject *
Py_VaBuildValue(const char *format, va_list va)
{
return va_build_value(format, va, 0);
return va_build_value(format, va);
}
PyObject *
PyAPI_FUNC(PyObject *) /* abi only */
_Py_VaBuildValue_SizeT(const char *format, va_list va)
{
return va_build_value(format, va, FLAG_SIZE_T);
return va_build_value(format, va);
}
static PyObject *
va_build_value(const char *format, va_list va, int flags)
va_build_value(const char *format, va_list va)
{
const char *f = format;
Py_ssize_t n = countformat(f, '\0');
@ -553,9 +524,9 @@ va_build_value(const char *format, va_list va, int flags)
}
va_copy(lva, va);
if (n == 1) {
retval = do_mkvalue(&f, &lva, flags);
retval = do_mkvalue(&f, &lva);
} else {
retval = do_mktuple(&f, &lva, '\0', n, flags);
retval = do_mktuple(&f, &lva, '\0', n);
}
va_end(lva);
return retval;
@ -564,20 +535,6 @@ va_build_value(const char *format, va_list va, int flags)
PyObject **
_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len,
const char *format, va_list va, Py_ssize_t *p_nargs)
{
return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs);
}
PyObject **
_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len,
const char *format, va_list va, Py_ssize_t *p_nargs)
{
return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs);
}
static PyObject **
va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len,
const char *format, va_list va, int flags, Py_ssize_t *p_nargs)
{
const char *f;
Py_ssize_t n;
@ -609,7 +566,7 @@ va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len,
va_copy(lva, va);
f = format;
res = do_mkstack(stack, &f, &lva, '\0', n, flags);
res = do_mkstack(stack, &f, &lva, '\0', n);
va_end(lva);
if (res < 0) {

View file

@ -211,7 +211,7 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
/* Initialize event args now */
if (argFormat && argFormat[0]) {
eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs);
eventArgs = Py_VaBuildValue(argFormat, vargs);
if (eventArgs && !PyTuple_Check(eventArgs)) {
PyObject *argTuple = PyTuple_Pack(1, eventArgs);
Py_SETREF(eventArgs, argTuple);