C API tests: use special markers to test that output parameters were set (GH-109014)

This commit is contained in:
Serhiy Storchaka 2023-09-06 22:02:01 +03:00 committed by GitHub
parent db1ee6a19a
commit bf414b7fcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 30 deletions

View file

@ -32,7 +32,7 @@ object_getattrstring(PyObject *self, PyObject *args)
static PyObject * static PyObject *
object_getoptionalattr(PyObject *self, PyObject *args) object_getoptionalattr(PyObject *self, PyObject *args)
{ {
PyObject *obj, *attr_name, *value; PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR;
if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) {
return NULL; return NULL;
} }
@ -57,7 +57,7 @@ object_getoptionalattr(PyObject *self, PyObject *args)
static PyObject * static PyObject *
object_getoptionalattrstring(PyObject *self, PyObject *args) object_getoptionalattrstring(PyObject *self, PyObject *args)
{ {
PyObject *obj, *value; PyObject *obj, *value = UNINITIALIZED_PTR;
const char *attr_name; const char *attr_name;
Py_ssize_t size; Py_ssize_t size;
if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) {
@ -207,7 +207,7 @@ mapping_getitemstring(PyObject *self, PyObject *args)
static PyObject * static PyObject *
mapping_getoptionalitem(PyObject *self, PyObject *args) mapping_getoptionalitem(PyObject *self, PyObject *args)
{ {
PyObject *obj, *attr_name, *value; PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR;
if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) {
return NULL; return NULL;
} }
@ -232,7 +232,7 @@ mapping_getoptionalitem(PyObject *self, PyObject *args)
static PyObject * static PyObject *
mapping_getoptionalitemstring(PyObject *self, PyObject *args) mapping_getoptionalitemstring(PyObject *self, PyObject *args)
{ {
PyObject *obj, *value; PyObject *obj, *value = UNINITIALIZED_PTR;
const char *attr_name; const char *attr_name;
Py_ssize_t size; Py_ssize_t size;
if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) {

View file

@ -1,4 +1,5 @@
#include "parts.h" #include "parts.h"
#include "util.h"
static Py_ssize_t static Py_ssize_t
get_code_extra_index(PyInterpreterState* interp) { get_code_extra_index(PyInterpreterState* interp) {
@ -75,7 +76,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
} }
// Check the value is initially NULL // Check the value is initially NULL
void *extra; void *extra = UNINITIALIZED_PTR;
int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
if (res < 0) { if (res < 0) {
goto finally; goto finally;
@ -88,6 +89,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
goto finally; goto finally;
} }
// Assert it was set correctly // Assert it was set correctly
extra = UNINITIALIZED_PTR;
res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
if (res < 0) { if (res < 0) {
goto finally; goto finally;

View file

@ -139,7 +139,7 @@ dict_getitemwitherror(PyObject *self, PyObject *args)
static PyObject * static PyObject *
dict_getitemref(PyObject *self, PyObject *args) dict_getitemref(PyObject *self, PyObject *args)
{ {
PyObject *obj, *attr_name, *value; PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR;
if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) {
return NULL; return NULL;
} }
@ -164,7 +164,7 @@ dict_getitemref(PyObject *self, PyObject *args)
static PyObject * static PyObject *
dict_getitemstringref(PyObject *self, PyObject *args) dict_getitemstringref(PyObject *self, PyObject *args)
{ {
PyObject *obj, *value; PyObject *obj, *value = UNINITIALIZED_PTR;
const char *attr_name; const char *attr_name;
Py_ssize_t size; Py_ssize_t size;
if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) {
@ -276,7 +276,7 @@ dict_items(PyObject *self, PyObject *obj)
static PyObject * static PyObject *
dict_next(PyObject *self, PyObject *args) dict_next(PyObject *self, PyObject *args)
{ {
PyObject *mapping, *key, *value; PyObject *mapping, *key = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR;
Py_ssize_t pos; Py_ssize_t pos;
if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) { if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) {
return NULL; return NULL;
@ -286,6 +286,8 @@ dict_next(PyObject *self, PyObject *args)
if (rc != 0) { if (rc != 0) {
return Py_BuildValue("inOO", rc, pos, key, value); return Py_BuildValue("inOO", rc, pos, key, value);
} }
assert(key == UNINITIALIZED_PTR);
assert(value == UNINITIALIZED_PTR);
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
return NULL; return NULL;
} }

View file

@ -120,12 +120,15 @@ _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc,
PyObject *obj) PyObject *obj)
/*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/ /*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/
{ {
PyObject *type; PyObject *type = UNINITIALIZED_PTR;
PyObject *value; PyObject *value = UNINITIALIZED_PTR;
PyObject *tb; PyObject *tb = UNINITIALIZED_PTR;
PyErr_SetObject(exc, obj); PyErr_SetObject(exc, obj);
PyErr_Fetch(&type, &value, &tb); PyErr_Fetch(&type, &value, &tb);
assert(type != UNINITIALIZED_PTR);
assert(value != UNINITIALIZED_PTR);
assert(tb != UNINITIALIZED_PTR);
Py_XDECREF(type); Py_XDECREF(type);
Py_XDECREF(tb); Py_XDECREF(tb);
return value; return value;
@ -244,7 +247,7 @@ _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type,
PyObject *new_value, PyObject *new_tb) PyObject *new_value, PyObject *new_tb)
/*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/ /*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/
{ {
PyObject *type, *value, *tb; PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR;
PyErr_GetExcInfo(&type, &value, &tb); PyErr_GetExcInfo(&type, &value, &tb);
Py_INCREF(new_type); Py_INCREF(new_type);

View file

@ -490,7 +490,7 @@ static PyObject *
unicode_aswidecharstring(PyObject *self, PyObject *args) unicode_aswidecharstring(PyObject *self, PyObject *args)
{ {
PyObject *unicode, *result; PyObject *unicode, *result;
Py_ssize_t size = 100; Py_ssize_t size = UNINITIALIZED_SIZE;
wchar_t *buffer; wchar_t *buffer;
if (!PyArg_ParseTuple(args, "O", &unicode)) if (!PyArg_ParseTuple(args, "O", &unicode))
@ -498,8 +498,10 @@ unicode_aswidecharstring(PyObject *self, PyObject *args)
NULLABLE(unicode); NULLABLE(unicode);
buffer = PyUnicode_AsWideCharString(unicode, &size); buffer = PyUnicode_AsWideCharString(unicode, &size);
if (buffer == NULL) if (buffer == NULL) {
assert(size == UNINITIALIZED_SIZE);
return NULL; return NULL;
}
result = PyUnicode_FromWideChar(buffer, size + 1); result = PyUnicode_FromWideChar(buffer, size + 1);
PyMem_Free(buffer); PyMem_Free(buffer);
@ -624,15 +626,17 @@ unicode_asutf8andsize(PyObject *self, PyObject *args)
PyObject *unicode; PyObject *unicode;
Py_ssize_t buflen; Py_ssize_t buflen;
const char *s; const char *s;
Py_ssize_t size = -100; Py_ssize_t size = UNINITIALIZED_SIZE;
if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
return NULL; return NULL;
NULLABLE(unicode); NULLABLE(unicode);
s = PyUnicode_AsUTF8AndSize(unicode, &size); s = PyUnicode_AsUTF8AndSize(unicode, &size);
if (s == NULL) if (s == NULL) {
assert(size == UNINITIALIZED_SIZE);
return NULL; return NULL;
}
return Py_BuildValue("(y#n)", s, buflen, size); return Py_BuildValue("(y#n)", s, buflen, size);
} }
@ -726,7 +730,7 @@ unicode_decodeutf7stateful(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
Py_ssize_t consumed; Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
@ -734,6 +738,7 @@ unicode_decodeutf7stateful(PyObject *self, PyObject *args)
result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed); result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed);
if (!result) { if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL; return NULL;
} }
return Py_BuildValue("(Nn)", result, consumed); return Py_BuildValue("(Nn)", result, consumed);
@ -760,7 +765,7 @@ unicode_decodeutf8stateful(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
Py_ssize_t consumed = 123456789; Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
@ -768,6 +773,7 @@ unicode_decodeutf8stateful(PyObject *self, PyObject *args)
result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed); result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed);
if (!result) { if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL; return NULL;
} }
return Py_BuildValue("(Nn)", result, consumed); return Py_BuildValue("(Nn)", result, consumed);
@ -788,7 +794,7 @@ unicode_decodeutf32(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
int byteorder; int byteorder = UNINITIALIZED_INT;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
@ -808,8 +814,8 @@ unicode_decodeutf32stateful(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
int byteorder; int byteorder = UNINITIALIZED_INT;
Py_ssize_t consumed; Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
@ -817,6 +823,7 @@ unicode_decodeutf32stateful(PyObject *self, PyObject *args)
result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed); result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed);
if (!result) { if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL; return NULL;
} }
return Py_BuildValue("(iNn)", byteorder, result, consumed); return Py_BuildValue("(iNn)", byteorder, result, consumed);
@ -837,7 +844,7 @@ unicode_decodeutf16(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
int byteorder = 0; int byteorder = UNINITIALIZED_INT;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
@ -857,8 +864,8 @@ unicode_decodeutf16stateful(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
int byteorder; int byteorder = UNINITIALIZED_INT;
Py_ssize_t consumed; Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
@ -866,6 +873,7 @@ unicode_decodeutf16stateful(PyObject *self, PyObject *args)
result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed); result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed);
if (!result) { if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL; return NULL;
} }
return Py_BuildValue("(iNn)", byteorder, result, consumed); return Py_BuildValue("(iNn)", byteorder, result, consumed);
@ -1019,7 +1027,7 @@ unicode_decodembcsstateful(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
Py_ssize_t consumed; Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
@ -1027,6 +1035,7 @@ unicode_decodembcsstateful(PyObject *self, PyObject *args)
result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed); result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed);
if (!result) { if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL; return NULL;
} }
return Py_BuildValue("(Nn)", result, consumed); return Py_BuildValue("(Nn)", result, consumed);
@ -1040,7 +1049,7 @@ unicode_decodecodepagestateful(PyObject *self, PyObject *args)
const char *data; const char *data;
Py_ssize_t size; Py_ssize_t size;
const char *errors = NULL; const char *errors = NULL;
Py_ssize_t consumed; Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result; PyObject *result;
if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors)) if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors))
@ -1048,6 +1057,7 @@ unicode_decodecodepagestateful(PyObject *self, PyObject *args)
result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed); result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed);
if (!result) { if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL; return NULL;
} }
return Py_BuildValue("(Nn)", result, consumed); return Py_BuildValue("(Nn)", result, consumed);

View file

@ -23,3 +23,10 @@
assert(!PyErr_Occurred()); \ assert(!PyErr_Occurred()); \
return PyLong_FromSsize_t(_ret); \ return PyLong_FromSsize_t(_ret); \
} while (0) } while (0)
/* Marker to check that pointer value was set. */
#define UNINITIALIZED_PTR ((void *)"uninitialized")
/* Marker to check that Py_ssize_t value was set. */
#define UNINITIALIZED_SIZE ((Py_ssize_t)236892191)
/* Marker to check that integer value was set. */
#define UNINITIALIZED_INT (63256717)

View file

@ -217,10 +217,13 @@ test_dict_inner(int count)
Py_DECREF(v); Py_DECREF(v);
} }
k = v = UNINITIALIZED_PTR;
while (PyDict_Next(dict, &pos, &k, &v)) { while (PyDict_Next(dict, &pos, &k, &v)) {
PyObject *o; PyObject *o;
iterations++; iterations++;
assert(k != UNINITIALIZED_PTR);
assert(v != UNINITIALIZED_PTR);
i = PyLong_AS_LONG(v) + 1; i = PyLong_AS_LONG(v) + 1;
o = PyLong_FromLong(i); o = PyLong_FromLong(i);
if (o == NULL) if (o == NULL)
@ -230,7 +233,10 @@ test_dict_inner(int count)
return -1; return -1;
} }
Py_DECREF(o); Py_DECREF(o);
k = v = UNINITIALIZED_PTR;
} }
assert(k == UNINITIALIZED_PTR);
assert(v == UNINITIALIZED_PTR);
Py_DECREF(dict); Py_DECREF(dict);
@ -3118,7 +3124,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
assert(Py_REFCNT(obj) == refcnt); assert(Py_REFCNT(obj) == refcnt);
// test PyWeakref_GetRef(), reference is alive // test PyWeakref_GetRef(), reference is alive
PyObject *ref = Py_True; // marker to check that value was set PyObject *ref = UNINITIALIZED_PTR;
assert(PyWeakref_GetRef(weakref, &ref) == 1); assert(PyWeakref_GetRef(weakref, &ref) == 1);
assert(ref == obj); assert(ref == obj);
assert(Py_REFCNT(obj) == (refcnt + 1)); assert(Py_REFCNT(obj) == (refcnt + 1));
@ -3140,7 +3146,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
assert(PyWeakref_GET_OBJECT(weakref) == Py_None); assert(PyWeakref_GET_OBJECT(weakref) == Py_None);
// test PyWeakref_GetRef(), reference is dead // test PyWeakref_GetRef(), reference is dead
ref = Py_True; ref = UNINITIALIZED_PTR;
assert(PyWeakref_GetRef(weakref, &ref) == 0); assert(PyWeakref_GetRef(weakref, &ref) == 0);
assert(ref == NULL); assert(ref == NULL);
@ -3152,7 +3158,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
// test PyWeakref_GetRef(), invalid type // test PyWeakref_GetRef(), invalid type
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
ref = Py_True; ref = UNINITIALIZED_PTR;
assert(PyWeakref_GetRef(invalid_weakref, &ref) == -1); assert(PyWeakref_GetRef(invalid_weakref, &ref) == -1);
assert(PyErr_ExceptionMatches(PyExc_TypeError)); assert(PyErr_ExceptionMatches(PyExc_TypeError));
PyErr_Clear(); PyErr_Clear();
@ -3164,7 +3170,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
PyErr_Clear(); PyErr_Clear();
// test PyWeakref_GetRef(NULL) // test PyWeakref_GetRef(NULL)
ref = Py_True; // marker to check that value was set ref = UNINITIALIZED_PTR;
assert(PyWeakref_GetRef(NULL, &ref) == -1); assert(PyWeakref_GetRef(NULL, &ref) == -1);
assert(PyErr_ExceptionMatches(PyExc_SystemError)); assert(PyErr_ExceptionMatches(PyExc_SystemError));
assert(ref == NULL); assert(ref == NULL);