summaryrefslogtreecommitdiff
path: root/Modules/_testcapimodule.c
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2017-02-04 15:05:40 -0800
committerSteve Dower <steve.dower@microsoft.com>2017-02-04 15:05:40 -0800
commitb2fa705fd3887c326e811c418469c784353027f4 (patch)
treeb3428f73de91453edbfd4df1a5d4a212d182eb44 /Modules/_testcapimodule.c
parent134e58fd3aaa2e91390041e143f3f0a21a60142b (diff)
parentb53654b6dbfce8318a7d4d1cdaddca7a7fec194b (diff)
downloadcpython-b2fa705fd3887c326e811c418469c784353027f4.tar.gz
Issue #29392: Prevent crash when passing invalid arguments into msvcrt module.
Diffstat (limited to 'Modules/_testcapimodule.c')
-rw-r--r--Modules/_testcapimodule.c314
1 files changed, 241 insertions, 73 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 060a92da4b..f09205f63c 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -60,9 +60,7 @@ test_config(PyObject *self)
CHECK_SIZEOF(SIZEOF_LONG, long);
CHECK_SIZEOF(SIZEOF_VOID_P, void*);
CHECK_SIZEOF(SIZEOF_TIME_T, time_t);
-#ifdef HAVE_LONG_LONG
- CHECK_SIZEOF(SIZEOF_LONG_LONG, PY_LONG_LONG);
-#endif
+ CHECK_SIZEOF(SIZEOF_LONG_LONG, long long);
#undef CHECK_SIZEOF
@@ -100,22 +98,14 @@ test_sizeof_c_types(PyObject *self)
CHECK_SIGNNESS(Py_UCS1, 0);
CHECK_SIGNNESS(Py_UCS2, 0);
CHECK_SIGNNESS(Py_UCS4, 0);
-#ifdef HAVE_INT32_T
- CHECK_SIZEOF(PY_INT32_T, 4);
- CHECK_SIGNNESS(PY_INT32_T, 1);
-#endif
-#ifdef HAVE_UINT32_T
- CHECK_SIZEOF(PY_UINT32_T, 4);
- CHECK_SIGNNESS(PY_UINT32_T, 0);
-#endif
-#ifdef HAVE_INT64_T
- CHECK_SIZEOF(PY_INT64_T, 8);
- CHECK_SIGNNESS(PY_INT64_T, 1);
-#endif
-#ifdef HAVE_UINT64_T
- CHECK_SIZEOF(PY_UINT64_T, 8);
- CHECK_SIGNNESS(PY_UINT64_T, 0);
-#endif
+ CHECK_SIZEOF(int32_t, 4);
+ CHECK_SIGNNESS(int32_t, 1);
+ CHECK_SIZEOF(uint32_t, 4);
+ CHECK_SIGNNESS(uint32_t, 0);
+ CHECK_SIZEOF(int64_t, 8);
+ CHECK_SIGNNESS(int64_t, 1);
+ CHECK_SIZEOF(uint64_t, 8);
+ CHECK_SIGNNESS(uint64_t, 0);
/* pointer/size types */
CHECK_SIZEOF(size_t, sizeof(void *));
@@ -123,10 +113,10 @@ test_sizeof_c_types(PyObject *self)
CHECK_SIZEOF(Py_ssize_t, sizeof(void *));
CHECK_SIGNNESS(Py_ssize_t, 1);
- CHECK_SIZEOF(Py_uintptr_t, sizeof(void *));
- CHECK_SIGNNESS(Py_uintptr_t, 0);
- CHECK_SIZEOF(Py_intptr_t, sizeof(void *));
- CHECK_SIGNNESS(Py_intptr_t, 1);
+ CHECK_SIZEOF(uintptr_t, sizeof(void *));
+ CHECK_SIGNNESS(uintptr_t, 0);
+ CHECK_SIZEOF(intptr_t, sizeof(void *));
+ CHECK_SIGNNESS(intptr_t, 1);
Py_INCREF(Py_None);
return Py_None;
@@ -248,13 +238,37 @@ test_dict_iteration(PyObject* self)
return Py_None;
}
+static PyObject*
+dict_getitem_knownhash(PyObject *self, PyObject *args)
+{
+ PyObject *mp, *key, *result;
+ Py_ssize_t hash;
+
+ if (!PyArg_ParseTuple(args, "OOn:dict_getitem_knownhash",
+ &mp, &key, &hash)) {
+ return NULL;
+ }
+
+ result = _PyDict_GetItem_KnownHash(mp, key, (Py_hash_t)hash);
+ if (result == NULL && !PyErr_Occurred()) {
+ _PyErr_SetKeyError(key);
+ return NULL;
+ }
+
+ Py_XINCREF(result);
+ return result;
+}
static PyObject*
dict_hassplittable(PyObject *self, PyObject *arg)
{
- if (!PyArg_Parse(arg, "O!:dict_hassplittable", &PyDict_Type, &arg)) {
+ if (!PyDict_Check(arg)) {
+ PyErr_Format(PyExc_TypeError,
+ "dict_hassplittable() argument must be dict, not '%s'",
+ arg->ob_type->tp_name);
return NULL;
}
+
return PyBool_FromLong(_PyDict_HasSplitTable((PyDictObject*)arg));
}
@@ -366,12 +380,12 @@ test_lazy_hash_inheritance(PyObject* self)
}
-/* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)
+/* Tests of PyLong_{As, From}{Unsigned,}Long(), and
PyLong_{As, From}{Unsigned,}LongLong().
Note that the meat of the test is contained in testcapi_long.h.
This is revolting, but delicate code duplication is worse: "almost
- exactly the same" code is needed to test PY_LONG_LONG, but the ubiquitous
+ exactly the same" code is needed to test long long, but the ubiquitous
dependence on type names makes it impossible to use a parameterized
function. A giant macro would be even worse than this. A C++ template
would be perfect.
@@ -411,8 +425,6 @@ test_long_api(PyObject* self)
#undef F_U_TO_PY
#undef F_PY_TO_U
-#ifdef HAVE_LONG_LONG
-
static PyObject *
raise_test_longlong_error(const char* msg)
{
@@ -420,7 +432,7 @@ raise_test_longlong_error(const char* msg)
}
#define TESTNAME test_longlong_api_inner
-#define TYPENAME PY_LONG_LONG
+#define TYPENAME long long
#define F_S_TO_PY PyLong_FromLongLong
#define F_PY_TO_S PyLong_AsLongLong
#define F_U_TO_PY PyLong_FromUnsignedLongLong
@@ -607,7 +619,7 @@ test_long_and_overflow(PyObject *self)
}
/* Test the PyLong_AsLongLongAndOverflow API. General conversion to
- PY_LONG_LONG is tested by test_long_api_inner. This test will
+ long long is tested by test_long_api_inner. This test will
concentrate on proper handling of overflow.
*/
@@ -615,7 +627,7 @@ static PyObject *
test_long_long_and_overflow(PyObject *self)
{
PyObject *num, *one, *temp;
- PY_LONG_LONG value;
+ long long value;
int overflow;
/* Test that overflow is set properly for a large value. */
@@ -833,7 +845,7 @@ test_long_as_double(PyObject *self)
return Py_None;
}
-/* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG
+/* Test the L code for PyArg_ParseTuple. This should deliver a long long
for both long and int arguments. The test may leak a little memory if
it fails.
*/
@@ -841,7 +853,7 @@ static PyObject *
test_L_code(PyObject *self)
{
PyObject *tuple, *num;
- PY_LONG_LONG value;
+ long long value;
tuple = PyTuple_New(1);
if (tuple == NULL)
@@ -879,8 +891,6 @@ test_L_code(PyObject *self)
return Py_None;
}
-#endif /* ifdef HAVE_LONG_LONG */
-
static PyObject *
return_none(void *unused)
{
@@ -1010,7 +1020,7 @@ static PyObject *
getargs_keywords(PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *keywords[] = {"arg1","arg2","arg3","arg4","arg5", NULL};
- static char *fmt="(ii)i|(i(ii))(iii)i";
+ static const char fmt[] = "(ii)i|(i(ii))(iii)i";
int int_args[10]={-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords,
@@ -1037,6 +1047,21 @@ getargs_keyword_only(PyObject *self, PyObject *args, PyObject *kwargs)
return Py_BuildValue("iii", required, optional, keyword_only);
}
+/* test PyArg_ParseTupleAndKeywords positional-only arguments */
+static PyObject *
+getargs_positional_only_and_keywords(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *keywords[] = {"", "", "keyword", NULL};
+ int required = -1;
+ int optional = -1;
+ int keyword = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii", keywords,
+ &required, &optional, &keyword))
+ return NULL;
+ return Py_BuildValue("iii", required, optional, keyword);
+}
+
/* Functions to call PyArg_ParseTuple with integer format codes,
and return the result.
*/
@@ -1130,11 +1155,10 @@ getargs_p(PyObject *self, PyObject *args)
return PyLong_FromLong(value);
}
-#ifdef HAVE_LONG_LONG
static PyObject *
getargs_L(PyObject *self, PyObject *args)
{
- PY_LONG_LONG value;
+ long long value;
if (!PyArg_ParseTuple(args, "L", &value))
return NULL;
return PyLong_FromLongLong(value);
@@ -1143,12 +1167,11 @@ getargs_L(PyObject *self, PyObject *args)
static PyObject *
getargs_K(PyObject *self, PyObject *args)
{
- unsigned PY_LONG_LONG value;
+ unsigned long long value;
if (!PyArg_ParseTuple(args, "K", &value))
return NULL;
return PyLong_FromUnsignedLongLong(value);
}
-#endif
/* This function not only tests the 'k' getargs code, but also the
PyLong_AsUnsignedLongMask() and PyLong_AsUnsignedLongMask() functions. */
@@ -1170,7 +1193,7 @@ test_k_code(PyObject *self)
value = PyLong_AsUnsignedLongMask(num);
if (value != ULONG_MAX)
return raiseTestError("test_k_code",
- "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
+ "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
PyTuple_SET_ITEM(tuple, 0, num);
@@ -1189,7 +1212,7 @@ test_k_code(PyObject *self)
value = PyLong_AsUnsignedLongMask(num);
if (value != (unsigned long)-0x42)
return raiseTestError("test_k_code",
- "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
+ "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
PyTuple_SET_ITEM(tuple, 0, num);
@@ -2202,7 +2225,7 @@ _make_call(void *callable)
PyObject *rc;
int success;
PyGILState_STATE s = PyGILState_Ensure();
- rc = PyObject_CallFunction((PyObject *)callable, "");
+ rc = _PyObject_CallNoArg((PyObject *)callable);
success = (rc != NULL);
Py_XDECREF(rc);
PyGILState_Release(s);
@@ -2336,10 +2359,8 @@ test_string_from_format(PyObject *self, PyObject *args)
CHECK_1_FORMAT("%zu", size_t);
/* "%lld" and "%llu" support added in Python 2.7. */
-#ifdef HAVE_LONG_LONG
- CHECK_1_FORMAT("%llu", unsigned PY_LONG_LONG);
- CHECK_1_FORMAT("%lld", PY_LONG_LONG);
-#endif
+ CHECK_1_FORMAT("%llu", unsigned long long);
+ CHECK_1_FORMAT("%lld", long long);
Py_RETURN_NONE;
@@ -2384,7 +2405,7 @@ test_string_to_double(PyObject *self) {
result = PyOS_string_to_double(STR, NULL, NULL); \
if (result == -1.0 && PyErr_Occurred()) \
return NULL; \
- if (result != expected) { \
+ if (result != (double)expected) { \
msg = "conversion of " STR " to float failed"; \
goto fail; \
}
@@ -2976,7 +2997,9 @@ run_in_subinterp(PyObject *self, PyObject *args)
static int
check_time_rounding(int round)
{
- if (round != _PyTime_ROUND_FLOOR && round != _PyTime_ROUND_CEILING) {
+ if (round != _PyTime_ROUND_FLOOR
+ && round != _PyTime_ROUND_CEILING
+ && round != _PyTime_ROUND_HALF_EVEN) {
PyErr_SetString(PyExc_ValueError, "invalid rounding");
return -1;
}
@@ -3471,7 +3494,7 @@ temporary_c_thread(void *data)
/* Allocate a Python thread state for this thread */
state = PyGILState_Ensure();
- res = PyObject_CallFunction(test_c_thread->callback, "", NULL);
+ res = _PyObject_CallNoArg(test_c_thread->callback);
Py_CLEAR(test_c_thread->callback);
if (res == NULL) {
@@ -3761,7 +3784,7 @@ test_pytime_fromsecondsobject(PyObject *self, PyObject *args)
static PyObject *
test_pytime_assecondsdouble(PyObject *self, PyObject *args)
{
- PY_LONG_LONG ns;
+ long long ns;
_PyTime_t ts;
double d;
@@ -3775,7 +3798,7 @@ test_pytime_assecondsdouble(PyObject *self, PyObject *args)
static PyObject *
test_PyTime_AsTimeval(PyObject *self, PyObject *args)
{
- PY_LONG_LONG ns;
+ long long ns;
int round;
_PyTime_t t;
struct timeval tv;
@@ -3789,7 +3812,7 @@ test_PyTime_AsTimeval(PyObject *self, PyObject *args)
if (_PyTime_AsTimeval(t, &tv, round) < 0)
return NULL;
- seconds = PyLong_FromLong((PY_LONG_LONG)tv.tv_sec);
+ seconds = PyLong_FromLong((long long)tv.tv_sec);
if (seconds == NULL)
return NULL;
return Py_BuildValue("Nl", seconds, tv.tv_usec);
@@ -3799,7 +3822,7 @@ test_PyTime_AsTimeval(PyObject *self, PyObject *args)
static PyObject *
test_PyTime_AsTimespec(PyObject *self, PyObject *args)
{
- PY_LONG_LONG ns;
+ long long ns;
_PyTime_t t;
struct timespec ts;
@@ -3815,7 +3838,7 @@ test_PyTime_AsTimespec(PyObject *self, PyObject *args)
static PyObject *
test_PyTime_AsMilliseconds(PyObject *self, PyObject *args)
{
- PY_LONG_LONG ns;
+ long long ns;
int round;
_PyTime_t t, ms;
@@ -3833,7 +3856,7 @@ test_PyTime_AsMilliseconds(PyObject *self, PyObject *args)
static PyObject *
test_PyTime_AsMicroseconds(PyObject *self, PyObject *args)
{
- PY_LONG_LONG ns;
+ long long ns;
int round;
_PyTime_t t, ms;
@@ -3857,6 +3880,152 @@ get_recursion_depth(PyObject *self, PyObject *args)
return PyLong_FromLong(tstate->recursion_depth - 1);
}
+static PyObject*
+pymem_buffer_overflow(PyObject *self, PyObject *args)
+{
+ char *buffer;
+
+ /* Deliberate buffer overflow to check that PyMem_Free() detects
+ the overflow when debug hooks are installed. */
+ buffer = PyMem_Malloc(16);
+ buffer[16] = 'x';
+ PyMem_Free(buffer);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+pymem_api_misuse(PyObject *self, PyObject *args)
+{
+ char *buffer;
+
+ /* Deliberate misusage of Python allocators:
+ allococate with PyMem but release with PyMem_Raw. */
+ buffer = PyMem_Malloc(16);
+ PyMem_RawFree(buffer);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+pymem_malloc_without_gil(PyObject *self, PyObject *args)
+{
+ char *buffer;
+
+ /* Deliberate bug to test debug hooks on Python memory allocators:
+ call PyMem_Malloc() without holding the GIL */
+ Py_BEGIN_ALLOW_THREADS
+ buffer = PyMem_Malloc(10);
+ Py_END_ALLOW_THREADS
+
+ PyMem_Free(buffer);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject*
+pyobject_malloc_without_gil(PyObject *self, PyObject *args)
+{
+ char *buffer;
+
+ /* Deliberate bug to test debug hooks on Python memory allocators:
+ call PyObject_Malloc() without holding the GIL */
+ Py_BEGIN_ALLOW_THREADS
+ buffer = PyObject_Malloc(10);
+ Py_END_ALLOW_THREADS
+
+ PyObject_Free(buffer);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+tracemalloc_track(PyObject *self, PyObject *args)
+{
+ unsigned int domain;
+ PyObject *ptr_obj;
+ void *ptr;
+ Py_ssize_t size;
+ int release_gil = 0;
+ int res;
+
+ if (!PyArg_ParseTuple(args, "IOn|i", &domain, &ptr_obj, &size, &release_gil))
+ return NULL;
+ ptr = PyLong_AsVoidPtr(ptr_obj);
+ if (PyErr_Occurred())
+ return NULL;
+
+ if (release_gil) {
+ Py_BEGIN_ALLOW_THREADS
+ res = _PyTraceMalloc_Track(domain, (uintptr_t)ptr, size);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ res = _PyTraceMalloc_Track(domain, (uintptr_t)ptr, size);
+ }
+
+ if (res < 0) {
+ PyErr_SetString(PyExc_RuntimeError, "_PyTraceMalloc_Track error");
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+tracemalloc_untrack(PyObject *self, PyObject *args)
+{
+ unsigned int domain;
+ PyObject *ptr_obj;
+ void *ptr;
+ int res;
+
+ if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj))
+ return NULL;
+ ptr = PyLong_AsVoidPtr(ptr_obj);
+ if (PyErr_Occurred())
+ return NULL;
+
+ res = _PyTraceMalloc_Untrack(domain, (uintptr_t)ptr);
+ if (res < 0) {
+ PyErr_SetString(PyExc_RuntimeError, "_PyTraceMalloc_Track error");
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+tracemalloc_get_traceback(PyObject *self, PyObject *args)
+{
+ unsigned int domain;
+ PyObject *ptr_obj;
+ void *ptr;
+
+ if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj))
+ return NULL;
+ ptr = PyLong_AsVoidPtr(ptr_obj);
+ if (PyErr_Occurred())
+ return NULL;
+
+ return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr);
+}
+
+static PyObject *
+dict_get_version(PyObject *self, PyObject *args)
+{
+ PyDictObject *dict;
+ uint64_t version;
+
+ if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
+ return NULL;
+
+ version = dict->ma_version_tag;
+
+ Py_BUILD_ASSERT(sizeof(unsigned PY_LONG_LONG) >= sizeof(version));
+ return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)version);
+}
+
static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
@@ -3867,6 +4036,7 @@ static PyMethodDef TestMethods[] = {
{"test_datetime_capi", test_datetime_capi, METH_NOARGS},
{"test_list_api", (PyCFunction)test_list_api, METH_NOARGS},
{"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS},
+ {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS},
{"dict_hassplittable", dict_hassplittable, METH_O},
{"test_lazy_hash_inheritance", (PyCFunction)test_lazy_hash_inheritance,METH_NOARGS},
{"test_long_api", (PyCFunction)test_long_api, METH_NOARGS},
@@ -3903,6 +4073,9 @@ static PyMethodDef TestMethods[] = {
METH_VARARGS|METH_KEYWORDS},
{"getargs_keyword_only", (PyCFunction)getargs_keyword_only,
METH_VARARGS|METH_KEYWORDS},
+ {"getargs_positional_only_and_keywords",
+ (PyCFunction)getargs_positional_only_and_keywords,
+ METH_VARARGS|METH_KEYWORDS},
{"getargs_b", getargs_b, METH_VARARGS},
{"getargs_B", getargs_B, METH_VARARGS},
{"getargs_h", getargs_h, METH_VARARGS},
@@ -3913,14 +4086,12 @@ static PyMethodDef TestMethods[] = {
{"getargs_l", getargs_l, METH_VARARGS},
{"getargs_n", getargs_n, METH_VARARGS},
{"getargs_p", getargs_p, METH_VARARGS},
-#ifdef HAVE_LONG_LONG
{"getargs_L", getargs_L, METH_VARARGS},
{"getargs_K", getargs_K, METH_VARARGS},
{"test_longlong_api", test_longlong_api, METH_NOARGS},
{"test_long_long_and_overflow",
(PyCFunction)test_long_long_and_overflow, METH_NOARGS},
{"test_L_code", (PyCFunction)test_L_code, METH_NOARGS},
-#endif
{"getargs_f", getargs_f, METH_VARARGS},
{"getargs_d", getargs_d, METH_VARARGS},
{"getargs_D", getargs_D, METH_VARARGS},
@@ -4051,6 +4222,14 @@ static PyMethodDef TestMethods[] = {
{"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS},
{"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS},
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
+ {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS},
+ {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS},
+ {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS},
+ {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS},
+ {"tracemalloc_track", tracemalloc_track, METH_VARARGS},
+ {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS},
+ {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS},
+ {"dict_get_version", dict_get_version, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
@@ -4070,10 +4249,8 @@ typedef struct {
float float_member;
double double_member;
char inplace_member[6];
-#ifdef HAVE_LONG_LONG
- PY_LONG_LONG longlong_member;
- unsigned PY_LONG_LONG ulonglong_member;
-#endif
+ long long longlong_member;
+ unsigned long long ulonglong_member;
} all_structmembers;
typedef struct {
@@ -4095,10 +4272,8 @@ static struct PyMemberDef test_members[] = {
{"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
{"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
{"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL},
-#ifdef HAVE_LONG_LONG
{"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL},
{"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL},
-#endif
{NULL}
};
@@ -4110,15 +4285,9 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
"T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT",
"T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET",
"T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE",
-#ifdef HAVE_LONG_LONG
"T_LONGLONG", "T_ULONGLONG",
-#endif
NULL};
- static char *fmt = "|bbBhHiIlknfds#"
-#ifdef HAVE_LONG_LONG
- "LK"
-#endif
- ;
+ static const char fmt[] = "|bbBhHiIlknfds#LK";
test_structmembers *ob;
const char *s = NULL;
Py_ssize_t string_len = 0;
@@ -4140,10 +4309,8 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
&ob->structmembers.float_member,
&ob->structmembers.double_member,
&s, &string_len
-#ifdef HAVE_LONG_LONG
, &ob->structmembers.longlong_member,
&ob->structmembers.ulonglong_member
-#endif
)) {
Py_DECREF(ob);
return NULL;
@@ -4469,6 +4636,7 @@ PyInit__testcapi(void)
PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyLong_FromSsize_t(PY_SSIZE_T_MAX));
PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyLong_FromSsize_t(PY_SSIZE_T_MIN));
PyModule_AddObject(m, "SIZEOF_PYGC_HEAD", PyLong_FromSsize_t(sizeof(PyGC_Head)));
+ PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t)));
Py_INCREF(&PyInstanceMethod_Type);
PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type);