Skip to content

Commit bf414b7

Browse files
C API tests: use special markers to test that output parameters were set (GH-109014)
1 parent db1ee6a commit bf414b7

File tree

7 files changed

+60
-30
lines changed

7 files changed

+60
-30
lines changed

Modules/_testcapi/abstract.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ object_getattrstring(PyObject *self, PyObject *args)
3232
static PyObject *
3333
object_getoptionalattr(PyObject *self, PyObject *args)
3434
{
35-
PyObject *obj, *attr_name, *value;
35+
PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR;
3636
if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) {
3737
return NULL;
3838
}
@@ -57,7 +57,7 @@ object_getoptionalattr(PyObject *self, PyObject *args)
5757
static PyObject *
5858
object_getoptionalattrstring(PyObject *self, PyObject *args)
5959
{
60-
PyObject *obj, *value;
60+
PyObject *obj, *value = UNINITIALIZED_PTR;
6161
const char *attr_name;
6262
Py_ssize_t size;
6363
if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) {
@@ -207,7 +207,7 @@ mapping_getitemstring(PyObject *self, PyObject *args)
207207
static PyObject *
208208
mapping_getoptionalitem(PyObject *self, PyObject *args)
209209
{
210-
PyObject *obj, *attr_name, *value;
210+
PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR;
211211
if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) {
212212
return NULL;
213213
}
@@ -232,7 +232,7 @@ mapping_getoptionalitem(PyObject *self, PyObject *args)
232232
static PyObject *
233233
mapping_getoptionalitemstring(PyObject *self, PyObject *args)
234234
{
235-
PyObject *obj, *value;
235+
PyObject *obj, *value = UNINITIALIZED_PTR;
236236
const char *attr_name;
237237
Py_ssize_t size;
238238
if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) {

Modules/_testcapi/code.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "parts.h"
2+
#include "util.h"
23

34
static Py_ssize_t
45
get_code_extra_index(PyInterpreterState* interp) {
@@ -75,7 +76,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
7576
}
7677

7778
// Check the value is initially NULL
78-
void *extra;
79+
void *extra = UNINITIALIZED_PTR;
7980
int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
8081
if (res < 0) {
8182
goto finally;
@@ -88,6 +89,7 @@ test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
8889
goto finally;
8990
}
9091
// Assert it was set correctly
92+
extra = UNINITIALIZED_PTR;
9193
res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
9294
if (res < 0) {
9395
goto finally;

Modules/_testcapi/dict.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ dict_getitemwitherror(PyObject *self, PyObject *args)
139139
static PyObject *
140140
dict_getitemref(PyObject *self, PyObject *args)
141141
{
142-
PyObject *obj, *attr_name, *value;
142+
PyObject *obj, *attr_name, *value = UNINITIALIZED_PTR;
143143
if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) {
144144
return NULL;
145145
}
@@ -164,7 +164,7 @@ dict_getitemref(PyObject *self, PyObject *args)
164164
static PyObject *
165165
dict_getitemstringref(PyObject *self, PyObject *args)
166166
{
167-
PyObject *obj, *value;
167+
PyObject *obj, *value = UNINITIALIZED_PTR;
168168
const char *attr_name;
169169
Py_ssize_t size;
170170
if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) {
@@ -276,7 +276,7 @@ dict_items(PyObject *self, PyObject *obj)
276276
static PyObject *
277277
dict_next(PyObject *self, PyObject *args)
278278
{
279-
PyObject *mapping, *key, *value;
279+
PyObject *mapping, *key = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR;
280280
Py_ssize_t pos;
281281
if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) {
282282
return NULL;
@@ -286,6 +286,8 @@ dict_next(PyObject *self, PyObject *args)
286286
if (rc != 0) {
287287
return Py_BuildValue("inOO", rc, pos, key, value);
288288
}
289+
assert(key == UNINITIALIZED_PTR);
290+
assert(value == UNINITIALIZED_PTR);
289291
if (PyErr_Occurred()) {
290292
return NULL;
291293
}

Modules/_testcapi/exceptions.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,15 @@ _testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc,
120120
PyObject *obj)
121121
/*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/
122122
{
123-
PyObject *type;
124-
PyObject *value;
125-
PyObject *tb;
123+
PyObject *type = UNINITIALIZED_PTR;
124+
PyObject *value = UNINITIALIZED_PTR;
125+
PyObject *tb = UNINITIALIZED_PTR;
126126

127127
PyErr_SetObject(exc, obj);
128128
PyErr_Fetch(&type, &value, &tb);
129+
assert(type != UNINITIALIZED_PTR);
130+
assert(value != UNINITIALIZED_PTR);
131+
assert(tb != UNINITIALIZED_PTR);
129132
Py_XDECREF(type);
130133
Py_XDECREF(tb);
131134
return value;
@@ -244,7 +247,7 @@ _testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type,
244247
PyObject *new_value, PyObject *new_tb)
245248
/*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/
246249
{
247-
PyObject *type, *value, *tb;
250+
PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR;
248251
PyErr_GetExcInfo(&type, &value, &tb);
249252

250253
Py_INCREF(new_type);

Modules/_testcapi/unicode.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -490,16 +490,18 @@ static PyObject *
490490
unicode_aswidecharstring(PyObject *self, PyObject *args)
491491
{
492492
PyObject *unicode, *result;
493-
Py_ssize_t size = 100;
493+
Py_ssize_t size = UNINITIALIZED_SIZE;
494494
wchar_t *buffer;
495495

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

499499
NULLABLE(unicode);
500500
buffer = PyUnicode_AsWideCharString(unicode, &size);
501-
if (buffer == NULL)
501+
if (buffer == NULL) {
502+
assert(size == UNINITIALIZED_SIZE);
502503
return NULL;
504+
}
503505

504506
result = PyUnicode_FromWideChar(buffer, size + 1);
505507
PyMem_Free(buffer);
@@ -624,15 +626,17 @@ unicode_asutf8andsize(PyObject *self, PyObject *args)
624626
PyObject *unicode;
625627
Py_ssize_t buflen;
626628
const char *s;
627-
Py_ssize_t size = -100;
629+
Py_ssize_t size = UNINITIALIZED_SIZE;
628630

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

632634
NULLABLE(unicode);
633635
s = PyUnicode_AsUTF8AndSize(unicode, &size);
634-
if (s == NULL)
636+
if (s == NULL) {
637+
assert(size == UNINITIALIZED_SIZE);
635638
return NULL;
639+
}
636640

637641
return Py_BuildValue("(y#n)", s, buflen, size);
638642
}
@@ -726,14 +730,15 @@ unicode_decodeutf7stateful(PyObject *self, PyObject *args)
726730
const char *data;
727731
Py_ssize_t size;
728732
const char *errors = NULL;
729-
Py_ssize_t consumed;
733+
Py_ssize_t consumed = UNINITIALIZED_SIZE;
730734
PyObject *result;
731735

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

735739
result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed);
736740
if (!result) {
741+
assert(consumed == UNINITIALIZED_SIZE);
737742
return NULL;
738743
}
739744
return Py_BuildValue("(Nn)", result, consumed);
@@ -760,14 +765,15 @@ unicode_decodeutf8stateful(PyObject *self, PyObject *args)
760765
const char *data;
761766
Py_ssize_t size;
762767
const char *errors = NULL;
763-
Py_ssize_t consumed = 123456789;
768+
Py_ssize_t consumed = UNINITIALIZED_SIZE;
764769
PyObject *result;
765770

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

769774
result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed);
770775
if (!result) {
776+
assert(consumed == UNINITIALIZED_SIZE);
771777
return NULL;
772778
}
773779
return Py_BuildValue("(Nn)", result, consumed);
@@ -788,7 +794,7 @@ unicode_decodeutf32(PyObject *self, PyObject *args)
788794
const char *data;
789795
Py_ssize_t size;
790796
const char *errors = NULL;
791-
int byteorder;
797+
int byteorder = UNINITIALIZED_INT;
792798
PyObject *result;
793799

794800
if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
@@ -808,15 +814,16 @@ unicode_decodeutf32stateful(PyObject *self, PyObject *args)
808814
const char *data;
809815
Py_ssize_t size;
810816
const char *errors = NULL;
811-
int byteorder;
812-
Py_ssize_t consumed;
817+
int byteorder = UNINITIALIZED_INT;
818+
Py_ssize_t consumed = UNINITIALIZED_SIZE;
813819
PyObject *result;
814820

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

818824
result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed);
819825
if (!result) {
826+
assert(consumed == UNINITIALIZED_SIZE);
820827
return NULL;
821828
}
822829
return Py_BuildValue("(iNn)", byteorder, result, consumed);
@@ -837,7 +844,7 @@ unicode_decodeutf16(PyObject *self, PyObject *args)
837844
const char *data;
838845
Py_ssize_t size;
839846
const char *errors = NULL;
840-
int byteorder = 0;
847+
int byteorder = UNINITIALIZED_INT;
841848
PyObject *result;
842849

843850
if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
@@ -857,15 +864,16 @@ unicode_decodeutf16stateful(PyObject *self, PyObject *args)
857864
const char *data;
858865
Py_ssize_t size;
859866
const char *errors = NULL;
860-
int byteorder;
861-
Py_ssize_t consumed;
867+
int byteorder = UNINITIALIZED_INT;
868+
Py_ssize_t consumed = UNINITIALIZED_SIZE;
862869
PyObject *result;
863870

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

867874
result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed);
868875
if (!result) {
876+
assert(consumed == UNINITIALIZED_SIZE);
869877
return NULL;
870878
}
871879
return Py_BuildValue("(iNn)", byteorder, result, consumed);
@@ -1019,14 +1027,15 @@ unicode_decodembcsstateful(PyObject *self, PyObject *args)
10191027
const char *data;
10201028
Py_ssize_t size;
10211029
const char *errors = NULL;
1022-
Py_ssize_t consumed;
1030+
Py_ssize_t consumed = UNINITIALIZED_SIZE;
10231031
PyObject *result;
10241032

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

10281036
result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed);
10291037
if (!result) {
1038+
assert(consumed == UNINITIALIZED_SIZE);
10301039
return NULL;
10311040
}
10321041
return Py_BuildValue("(Nn)", result, consumed);
@@ -1040,14 +1049,15 @@ unicode_decodecodepagestateful(PyObject *self, PyObject *args)
10401049
const char *data;
10411050
Py_ssize_t size;
10421051
const char *errors = NULL;
1043-
Py_ssize_t consumed;
1052+
Py_ssize_t consumed = UNINITIALIZED_SIZE;
10441053
PyObject *result;
10451054

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

10491058
result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed);
10501059
if (!result) {
1060+
assert(consumed == UNINITIALIZED_SIZE);
10511061
return NULL;
10521062
}
10531063
return Py_BuildValue("(Nn)", result, consumed);

Modules/_testcapi/util.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,10 @@
2323
assert(!PyErr_Occurred()); \
2424
return PyLong_FromSsize_t(_ret); \
2525
} while (0)
26+
27+
/* Marker to check that pointer value was set. */
28+
#define UNINITIALIZED_PTR ((void *)"uninitialized")
29+
/* Marker to check that Py_ssize_t value was set. */
30+
#define UNINITIALIZED_SIZE ((Py_ssize_t)236892191)
31+
/* Marker to check that integer value was set. */
32+
#define UNINITIALIZED_INT (63256717)

Modules/_testcapimodule.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,13 @@ test_dict_inner(int count)
217217
Py_DECREF(v);
218218
}
219219

220+
k = v = UNINITIALIZED_PTR;
220221
while (PyDict_Next(dict, &pos, &k, &v)) {
221222
PyObject *o;
222223
iterations++;
223224

225+
assert(k != UNINITIALIZED_PTR);
226+
assert(v != UNINITIALIZED_PTR);
224227
i = PyLong_AS_LONG(v) + 1;
225228
o = PyLong_FromLong(i);
226229
if (o == NULL)
@@ -230,7 +233,10 @@ test_dict_inner(int count)
230233
return -1;
231234
}
232235
Py_DECREF(o);
236+
k = v = UNINITIALIZED_PTR;
233237
}
238+
assert(k == UNINITIALIZED_PTR);
239+
assert(v == UNINITIALIZED_PTR);
234240

235241
Py_DECREF(dict);
236242

@@ -3118,7 +3124,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
31183124
assert(Py_REFCNT(obj) == refcnt);
31193125

31203126
// test PyWeakref_GetRef(), reference is alive
3121-
PyObject *ref = Py_True; // marker to check that value was set
3127+
PyObject *ref = UNINITIALIZED_PTR;
31223128
assert(PyWeakref_GetRef(weakref, &ref) == 1);
31233129
assert(ref == obj);
31243130
assert(Py_REFCNT(obj) == (refcnt + 1));
@@ -3140,7 +3146,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
31403146
assert(PyWeakref_GET_OBJECT(weakref) == Py_None);
31413147

31423148
// test PyWeakref_GetRef(), reference is dead
3143-
ref = Py_True;
3149+
ref = UNINITIALIZED_PTR;
31443150
assert(PyWeakref_GetRef(weakref, &ref) == 0);
31453151
assert(ref == NULL);
31463152

@@ -3152,7 +3158,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
31523158

31533159
// test PyWeakref_GetRef(), invalid type
31543160
assert(!PyErr_Occurred());
3155-
ref = Py_True;
3161+
ref = UNINITIALIZED_PTR;
31563162
assert(PyWeakref_GetRef(invalid_weakref, &ref) == -1);
31573163
assert(PyErr_ExceptionMatches(PyExc_TypeError));
31583164
PyErr_Clear();
@@ -3164,7 +3170,7 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
31643170
PyErr_Clear();
31653171

31663172
// test PyWeakref_GetRef(NULL)
3167-
ref = Py_True; // marker to check that value was set
3173+
ref = UNINITIALIZED_PTR;
31683174
assert(PyWeakref_GetRef(NULL, &ref) == -1);
31693175
assert(PyErr_ExceptionMatches(PyExc_SystemError));
31703176
assert(ref == NULL);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy