Skip to content

Commit

Permalink
[3.12] C API tests: use special markers to test that output parameter…
Browse files Browse the repository at this point in the history
…s were set (GH-109014) (#109023)

[3.12] C API tests: use special markers to test that output parameters were set (GH-109014).
(cherry picked from commit bf414b7)
  • Loading branch information
serhiy-storchaka authored Sep 8, 2023
1 parent db55cfc commit e65401d
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 20 deletions.
4 changes: 3 additions & 1 deletion Modules/_testcapi/code.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "parts.h"
#include "util.h"

static Py_ssize_t
get_code_extra_index(PyInterpreterState* interp) {
Expand Down Expand Up @@ -74,7 +75,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
}

// Check the value is initially NULL
void *extra;
void *extra = UNINITIALIZED_PTR;
int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
if (res < 0) {
goto finally;
Expand All @@ -87,6 +88,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
goto finally;
}
// Assert it was set correctly
extra = UNINITIALIZED_PTR;
res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
if (res < 0) {
goto finally;
Expand Down
4 changes: 3 additions & 1 deletion Modules/_testcapi/dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ dict_items(PyObject *self, PyObject *obj)
static PyObject *
dict_next(PyObject *self, PyObject *args)
{
PyObject *mapping, *key, *value;
PyObject *mapping, *key = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR;
Py_ssize_t pos;
if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) {
return NULL;
Expand All @@ -222,6 +222,8 @@ dict_next(PyObject *self, PyObject *args)
if (rc != 0) {
return Py_BuildValue("inOO", rc, pos, key, value);
}
assert(key == UNINITIALIZED_PTR);
assert(value == UNINITIALIZED_PTR);
if (PyErr_Occurred()) {
return NULL;
}
Expand Down
11 changes: 7 additions & 4 deletions Modules/_testcapi/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,15 @@ _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc,
PyObject *obj)
/*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/
{
PyObject *type;
PyObject *value;
PyObject *tb;
PyObject *type = UNINITIALIZED_PTR;
PyObject *value = UNINITIALIZED_PTR;
PyObject *tb = UNINITIALIZED_PTR;

PyErr_SetObject(exc, obj);
PyErr_Fetch(&type, &value, &tb);
assert(type != UNINITIALIZED_PTR);
assert(value != UNINITIALIZED_PTR);
assert(tb != UNINITIALIZED_PTR);
Py_XDECREF(type);
Py_XDECREF(tb);
return value;
Expand Down Expand Up @@ -245,7 +248,7 @@ _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type,
PyObject *new_value, PyObject *new_tb)
/*[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);

Py_INCREF(new_type);
Expand Down
38 changes: 24 additions & 14 deletions Modules/_testcapi/unicode.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,16 +491,18 @@ static PyObject *
unicode_aswidecharstring(PyObject *self, PyObject *args)
{
PyObject *unicode, *result;
Py_ssize_t size = 100;
Py_ssize_t size = UNINITIALIZED_SIZE;
wchar_t *buffer;

if (!PyArg_ParseTuple(args, "O", &unicode))
return NULL;

NULLABLE(unicode);
buffer = PyUnicode_AsWideCharString(unicode, &size);
if (buffer == NULL)
if (buffer == NULL) {
assert(size == UNINITIALIZED_SIZE);
return NULL;
}

result = PyUnicode_FromWideChar(buffer, size + 1);
PyMem_Free(buffer);
Expand Down Expand Up @@ -625,15 +627,17 @@ unicode_asutf8andsize(PyObject *self, PyObject *args)
PyObject *unicode;
Py_ssize_t buflen;
const char *s;
Py_ssize_t size = -100;
Py_ssize_t size = UNINITIALIZED_SIZE;

if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
return NULL;

NULLABLE(unicode);
s = PyUnicode_AsUTF8AndSize(unicode, &size);
if (s == NULL)
if (s == NULL) {
assert(size == UNINITIALIZED_SIZE);
return NULL;
}

return Py_BuildValue("(y#n)", s, buflen, size);
}
Expand Down Expand Up @@ -735,14 +739,15 @@ unicode_decodeutf7stateful(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
Py_ssize_t consumed;
Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result;

if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
return NULL;

result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed);
if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL;
}
return Py_BuildValue("(Nn)", result, consumed);
Expand All @@ -769,14 +774,15 @@ unicode_decodeutf8stateful(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
Py_ssize_t consumed = 123456789;
Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result;

if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
return NULL;

result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed);
if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL;
}
return Py_BuildValue("(Nn)", result, consumed);
Expand All @@ -797,7 +803,7 @@ unicode_decodeutf32(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
int byteorder;
int byteorder = UNINITIALIZED_INT;
PyObject *result;

if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
Expand All @@ -817,15 +823,16 @@ unicode_decodeutf32stateful(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
int byteorder;
Py_ssize_t consumed;
int byteorder = UNINITIALIZED_INT;
Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result;

if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
return NULL;

result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed);
if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL;
}
return Py_BuildValue("(iNn)", byteorder, result, consumed);
Expand All @@ -846,7 +853,7 @@ unicode_decodeutf16(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
int byteorder = 0;
int byteorder = UNINITIALIZED_INT;
PyObject *result;

if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
Expand All @@ -866,15 +873,16 @@ unicode_decodeutf16stateful(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
int byteorder;
Py_ssize_t consumed;
int byteorder = UNINITIALIZED_INT;
Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result;

if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
return NULL;

result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed);
if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL;
}
return Py_BuildValue("(iNn)", byteorder, result, consumed);
Expand Down Expand Up @@ -1028,14 +1036,15 @@ unicode_decodembcsstateful(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
Py_ssize_t consumed;
Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result;

if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
return NULL;

result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed);
if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL;
}
return Py_BuildValue("(Nn)", result, consumed);
Expand All @@ -1049,14 +1058,15 @@ unicode_decodecodepagestateful(PyObject *self, PyObject *args)
const char *data;
Py_ssize_t size;
const char *errors = NULL;
Py_ssize_t consumed;
Py_ssize_t consumed = UNINITIALIZED_SIZE;
PyObject *result;

if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors))
return NULL;

result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed);
if (!result) {
assert(consumed == UNINITIALIZED_SIZE);
return NULL;
}
return Py_BuildValue("(Nn)", result, consumed);
Expand Down
7 changes: 7 additions & 0 deletions Modules/_testcapi/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@
assert(!PyErr_Occurred()); \
return PyLong_FromSsize_t(_ret); \
} 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)
6 changes: 6 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,13 @@ test_dict_inner(int count)
Py_DECREF(v);
}

k = v = UNINITIALIZED_PTR;
while (PyDict_Next(dict, &pos, &k, &v)) {
PyObject *o;
iterations++;

assert(k != UNINITIALIZED_PTR);
assert(v != UNINITIALIZED_PTR);
i = PyLong_AS_LONG(v) + 1;
o = PyLong_FromLong(i);
if (o == NULL)
Expand All @@ -234,7 +237,10 @@ test_dict_inner(int count)
return -1;
}
Py_DECREF(o);
k = v = UNINITIALIZED_PTR;
}
assert(k == UNINITIALIZED_PTR);
assert(v == UNINITIALIZED_PTR);

Py_DECREF(dict);

Expand Down

0 comments on commit e65401d

Please sign in to comment.