Commit 5cb69366 authored by Martin v. Löwis's avatar Martin v. Löwis

Make Py_BuildValue, PyObject_CallFunction and

PyObject_CallMethod aware of PY_SSIZE_T_CLEAN.
parent 38a76a10
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
extern "C" { extern "C" {
#endif #endif
#ifdef PY_SSIZE_T_CLEAN
#define PyObject_CallFunction _PyObject_CallFunction_SizeT
#define PyObject_CallMethod _PyObject_CallMethod_SizeT
#endif
/* Abstract Object Interface (many thanks to Jim Fulton) */ /* Abstract Object Interface (many thanks to Jim Fulton) */
/* /*
......
...@@ -17,21 +17,11 @@ extern "C" { ...@@ -17,21 +17,11 @@ extern "C" {
#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT #define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT
#define PyArg_VaParse _PyArg_VaParse_SizeT #define PyArg_VaParse _PyArg_VaParse_SizeT
#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT #define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT
#define PyArg_BuildValue _PyArg_BuildValue_SizeT #define Py_BuildValue _Py_BuildValue_SizeT
#define PyArg_VaBuildValue _PyArg_VaBuildValue_SizeT #define Py_VaBuildValue _Py_VaBuildValue_SizeT
#else #else
#ifdef HAVE_DECLSPEC_DLL
PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, 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 *, char *, va_list);
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
const char *, char **, va_list);
PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list);
#endif #endif
#endif
PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...);
PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);
......
...@@ -10,6 +10,14 @@ ...@@ -10,6 +10,14 @@
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX) #define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
#ifdef HAVE_DECLSPEC_DLL
PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable_object,
char *format, ...);
PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o, char *m,
char *format, ...);
#endif
/* Shorthands to return certain errors */ /* Shorthands to return certain errors */
static PyObject * static PyObject *
...@@ -1800,11 +1808,37 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) ...@@ -1800,11 +1808,37 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
return NULL; return NULL;
} }
static PyObject*
call_function_tail(PyObject *callable, PyObject *args)
{
PyObject *retval;
if (args == NULL)
return NULL;
if (!PyTuple_Check(args)) {
PyObject *a;
a = PyTuple_New(1);
if (a == NULL) {
Py_DECREF(args);
return NULL;
}
PyTuple_SET_ITEM(a, 0, args);
args = a;
}
retval = PyObject_Call(callable, args, NULL);
Py_DECREF(args);
return retval;
}
PyObject * PyObject *
PyObject_CallFunction(PyObject *callable, char *format, ...) PyObject_CallFunction(PyObject *callable, char *format, ...)
{ {
va_list va; va_list va;
PyObject *args, *retval; PyObject *args;
if (callable == NULL) if (callable == NULL)
return null_error(); return null_error();
...@@ -1817,31 +1851,34 @@ PyObject_CallFunction(PyObject *callable, char *format, ...) ...@@ -1817,31 +1851,34 @@ PyObject_CallFunction(PyObject *callable, char *format, ...)
else else
args = PyTuple_New(0); args = PyTuple_New(0);
if (args == NULL) return call_function_tail(callable, args);
return NULL; }
if (!PyTuple_Check(args)) { PyObject *
PyObject *a; _PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
{
va_list va;
PyObject *args;
a = PyTuple_New(1); if (callable == NULL)
if (a == NULL) return null_error();
return NULL;
if (PyTuple_SetItem(a, 0, args) < 0)
return NULL;
args = a;
}
retval = PyObject_Call(callable, args, NULL);
Py_DECREF(args); if (format && *format) {
va_start(va, format);
args = _Py_VaBuildValue_SizeT(format, va);
va_end(va);
}
else
args = PyTuple_New(0);
return retval; return call_function_tail(callable, args);
} }
PyObject * PyObject *
PyObject_CallMethod(PyObject *o, char *name, char *format, ...) PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
{ {
va_list va; va_list va;
PyObject *args = NULL; PyObject *args;
PyObject *func = NULL; PyObject *func = NULL;
PyObject *retval = NULL; PyObject *retval = NULL;
...@@ -1867,24 +1904,49 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...) ...@@ -1867,24 +1904,49 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
else else
args = PyTuple_New(0); args = PyTuple_New(0);
if (!args) retval = call_function_tail(func, args);
goto exit;
if (!PyTuple_Check(args)) { exit:
PyObject *a; /* args gets consumed in call_function_tail */
Py_XDECREF(func);
a = PyTuple_New(1); return retval;
if (a == NULL) }
goto exit;
if (PyTuple_SetItem(a, 0, args) < 0) PyObject *
_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
{
va_list va;
PyObject *args;
PyObject *func = NULL;
PyObject *retval = NULL;
if (o == NULL || name == NULL)
return null_error();
func = PyObject_GetAttrString(o, name);
if (func == NULL) {
PyErr_SetString(PyExc_AttributeError, name);
return 0;
}
if (!PyCallable_Check(func)) {
type_error("call of non-callable attribute");
goto exit; goto exit;
args = a;
} }
retval = PyObject_Call(func, args, NULL); if (format && *format) {
va_start(va, format);
args = _Py_VaBuildValue_SizeT(format, va);
va_end(va);
}
else
args = PyTuple_New(0);
retval = call_function_tail(func, args);
exit: exit:
Py_XDECREF(args); /* args gets consumed in call_function_tail */
Py_XDECREF(func); Py_XDECREF(func);
return retval; return retval;
......
/* String object implementation */ /* String object implementation */
#define PY_SSIZE_T_CLEAN
#include "Python.h" #include "Python.h"
#include <ctype.h> #include <ctype.h>
......
...@@ -36,6 +36,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -36,6 +36,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#define PY_SSIZE_T_CLEAN
#include "Python.h" #include "Python.h"
#include "unicodeobject.h" #include "unicodeobject.h"
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
* Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved. * Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved.
*/ */
#define PY_SSIZE_T_CLEAN
#include "Python.h" #include "Python.h"
#include "osdefs.h" #include "osdefs.h"
...@@ -1450,8 +1451,8 @@ PyObject * PyUnicodeDecodeError_Create( ...@@ -1450,8 +1451,8 @@ PyObject * PyUnicodeDecodeError_Create(
assert(length < INT_MAX); assert(length < INT_MAX);
assert(start < INT_MAX); assert(start < INT_MAX);
assert(end < INT_MAX); assert(end < INT_MAX);
return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#iis", return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
encoding, object, (int)length, (int)start, (int)end, reason); encoding, object, length, start, end, reason);
} }
...@@ -1565,7 +1566,7 @@ PyObject * PyUnicodeTranslateError_Create( ...@@ -1565,7 +1566,7 @@ PyObject * PyUnicodeTranslateError_Create(
const Py_UNICODE *object, Py_ssize_t length, const Py_UNICODE *object, Py_ssize_t length,
Py_ssize_t start, Py_ssize_t end, const char *reason) Py_ssize_t start, Py_ssize_t end, const char *reason)
{ {
return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#iis", return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
object, length, start, end, reason); object, length, start, end, reason);
} }
#endif #endif
......
...@@ -18,6 +18,18 @@ int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, ...@@ -18,6 +18,18 @@ int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
const char *, char **, va_list); const char *, char **, va_list);
#ifdef HAVE_DECLSPEC_DLL
/* Export functions */
PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, 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 *, char *, va_list);
PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
const char *, char **, va_list);
#endif
#define FLAG_COMPAT 1 #define FLAG_COMPAT 1
#define FLAG_SIZE_T 2 #define FLAG_SIZE_T 2
......
...@@ -3,8 +3,14 @@ ...@@ -3,8 +3,14 @@
#include "Python.h" #include "Python.h"
#define FLAG_SIZE_T 1
typedef double va_double; typedef double va_double;
static PyObject *va_build_value(const char *, va_list, int);
#ifdef HAVE_DECLSPEC_DLL
PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
#endif
/* Package context -- the full module name for package imports */ /* Package context -- the full module name for package imports */
char *_Py_PackageContext = NULL; char *_Py_PackageContext = NULL;
...@@ -146,14 +152,14 @@ countformat(const char *format, int endchar) ...@@ -146,14 +152,14 @@ countformat(const char *format, int endchar)
/* Generic function to create a value -- the inverse of getargs() */ /* Generic function to create a value -- the inverse of getargs() */
/* After an original idea and first implementation by Steven Miale */ /* After an original idea and first implementation by Steven Miale */
static PyObject *do_mktuple(const char**, va_list *, int, int); static PyObject *do_mktuple(const char**, va_list *, int, int, int);
static PyObject *do_mklist(const char**, va_list *, int, int); static PyObject *do_mklist(const char**, va_list *, int, int, int);
static PyObject *do_mkdict(const char**, va_list *, int, int); static PyObject *do_mkdict(const char**, va_list *, int, int, int);
static PyObject *do_mkvalue(const char**, va_list *); static PyObject *do_mkvalue(const char**, va_list *, int);
static PyObject * static PyObject *
do_mkdict(const char **p_format, va_list *p_va, int endchar, int n) do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{ {
PyObject *d; PyObject *d;
int i; int i;
...@@ -167,13 +173,13 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n) ...@@ -167,13 +173,13 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
for (i = 0; i < n; i+= 2) { for (i = 0; i < n; i+= 2) {
PyObject *k, *v; PyObject *k, *v;
int err; int err;
k = do_mkvalue(p_format, p_va); k = do_mkvalue(p_format, p_va, flags);
if (k == NULL) { if (k == NULL) {
itemfailed = 1; itemfailed = 1;
Py_INCREF(Py_None); Py_INCREF(Py_None);
k = Py_None; k = Py_None;
} }
v = do_mkvalue(p_format, p_va); v = do_mkvalue(p_format, p_va, flags);
if (v == NULL) { if (v == NULL) {
itemfailed = 1; itemfailed = 1;
Py_INCREF(Py_None); Py_INCREF(Py_None);
...@@ -199,7 +205,7 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n) ...@@ -199,7 +205,7 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
} }
static PyObject * static PyObject *
do_mklist(const char **p_format, va_list *p_va, int endchar, int n) do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{ {
PyObject *v; PyObject *v;
int i; int i;
...@@ -212,7 +218,7 @@ do_mklist(const char **p_format, va_list *p_va, int endchar, int n) ...@@ -212,7 +218,7 @@ do_mklist(const char **p_format, va_list *p_va, int endchar, int n)
/* Note that we can't bail immediately on error as this will leak /* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */ refcounts on any 'N' arguments. */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
PyObject *w = do_mkvalue(p_format, p_va); PyObject *w = do_mkvalue(p_format, p_va, flags);
if (w == NULL) { if (w == NULL) {
itemfailed = 1; itemfailed = 1;
Py_INCREF(Py_None); Py_INCREF(Py_None);
...@@ -249,7 +255,7 @@ _ustrlen(Py_UNICODE *u) ...@@ -249,7 +255,7 @@ _ustrlen(Py_UNICODE *u)
#endif #endif
static PyObject * static PyObject *
do_mktuple(const char **p_format, va_list *p_va, int endchar, int n) do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{ {
PyObject *v; PyObject *v;
int i; int i;
...@@ -261,7 +267,7 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n) ...@@ -261,7 +267,7 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
/* Note that we can't bail immediately on error as this will leak /* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */ refcounts on any 'N' arguments. */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
PyObject *w = do_mkvalue(p_format, p_va); PyObject *w = do_mkvalue(p_format, p_va, flags);
if (w == NULL) { if (w == NULL) {
itemfailed = 1; itemfailed = 1;
Py_INCREF(Py_None); Py_INCREF(Py_None);
...@@ -286,21 +292,21 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n) ...@@ -286,21 +292,21 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
} }
static PyObject * static PyObject *
do_mkvalue(const char **p_format, va_list *p_va) do_mkvalue(const char **p_format, va_list *p_va, int flags)
{ {
for (;;) { for (;;) {
switch (*(*p_format)++) { switch (*(*p_format)++) {
case '(': case '(':
return do_mktuple(p_format, p_va, ')', return do_mktuple(p_format, p_va, ')',
countformat(*p_format, ')')); countformat(*p_format, ')'), flags);
case '[': case '[':
return do_mklist(p_format, p_va, ']', return do_mklist(p_format, p_va, ']',
countformat(*p_format, ']')); countformat(*p_format, ']'), flags);
case '{': case '{':
return do_mkdict(p_format, p_va, '}', return do_mkdict(p_format, p_va, '}',
countformat(*p_format, '}')); countformat(*p_format, '}'), flags);
case 'b': case 'b':
case 'B': case 'B':
...@@ -351,9 +357,12 @@ do_mkvalue(const char **p_format, va_list *p_va) ...@@ -351,9 +357,12 @@ do_mkvalue(const char **p_format, va_list *p_va)
{ {
PyObject *v; PyObject *v;
Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *); Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
int n; Py_ssize_t n;
if (**p_format == '#') { if (**p_format == '#') {
++*p_format; ++*p_format;
if (flags & FLAG_SIZE_T)
n = va_arg(*p_va, Py_ssize_t);
else
n = va_arg(*p_va, int); n = va_arg(*p_va, int);
} }
else else
...@@ -393,9 +402,12 @@ do_mkvalue(const char **p_format, va_list *p_va) ...@@ -393,9 +402,12 @@ do_mkvalue(const char **p_format, va_list *p_va)
{ {
PyObject *v; PyObject *v;
char *str = va_arg(*p_va, char *); char *str = va_arg(*p_va, char *);
int n; Py_ssize_t n;
if (**p_format == '#') { if (**p_format == '#') {
++*p_format; ++*p_format;
if (flags & FLAG_SIZE_T)
n = va_arg(*p_va, Py_ssize_t);
else
n = va_arg(*p_va, int); n = va_arg(*p_va, int);
} }
else else
...@@ -472,13 +484,36 @@ Py_BuildValue(const char *format, ...) ...@@ -472,13 +484,36 @@ Py_BuildValue(const char *format, ...)
va_list va; va_list va;
PyObject* retval; PyObject* retval;
va_start(va, format); va_start(va, format);
retval = Py_VaBuildValue(format, va); retval = va_build_value(format, va, 0);
va_end(va);
return retval;
}
PyObject *
_Py_BuildValue_SizeT(const char *format, ...)
{
va_list va;
PyObject* retval;
va_start(va, format);
retval = va_build_value(format, va, FLAG_SIZE_T);
va_end(va); va_end(va);
return retval; return retval;
} }
PyObject * PyObject *
Py_VaBuildValue(const char *format, va_list va) Py_VaBuildValue(const char *format, va_list va)
{
return va_build_value(format, va, 0);
}
PyObject *
_Py_VaBuildValue_SizeT(const char *format, va_list va)
{
return va_build_value(format, va, FLAG_SIZE_T);
}
static PyObject *
va_build_value(const char *format, va_list va, int flags)
{ {
const char *f = format; const char *f = format;
int n = countformat(f, '\0'); int n = countformat(f, '\0');
...@@ -501,8 +536,8 @@ Py_VaBuildValue(const char *format, va_list va) ...@@ -501,8 +536,8 @@ Py_VaBuildValue(const char *format, va_list va)
return Py_None; return Py_None;
} }
if (n == 1) if (n == 1)
return do_mkvalue(&f, &lva); return do_mkvalue(&f, &lva, flags);
return do_mktuple(&f, &lva, '\0', n); return do_mktuple(&f, &lva, '\0', n, flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment