Skip to content

Commit 7e3f09c

Browse files
authored
pythongh-99537: Use Py_SETREF() function in C code (python#99656)
Fix potential race condition in code patterns: * Replace "Py_DECREF(var); var = new;" with "Py_SETREF(var, new);" * Replace "Py_XDECREF(var); var = new;" with "Py_XSETREF(var, new);" * Replace "Py_CLEAR(var); var = new;" with "Py_XSETREF(var, new);" Other changes: * Replace "old = var; var = new; Py_DECREF(var)" with "Py_SETREF(var, new);" * Replace "old = var; var = new; Py_XDECREF(var)" with "Py_XSETREF(var, new);" * And remove the "old" variable.
1 parent 135ec7c commit 7e3f09c

20 files changed

+37
-89
lines changed

Doc/includes/custom2.c

+3-7
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,18 @@ static int
4242
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
4343
{
4444
static char *kwlist[] = {"first", "last", "number", NULL};
45-
PyObject *first = NULL, *last = NULL, *tmp;
45+
PyObject *first = NULL, *last = NULL;
4646

4747
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
4848
&first, &last,
4949
&self->number))
5050
return -1;
5151

5252
if (first) {
53-
tmp = self->first;
54-
self->first = Py_NewRef(first);
55-
Py_XDECREF(tmp);
53+
Py_XSETREF(self->first, Py_NewRef(first));
5654
}
5755
if (last) {
58-
tmp = self->last;
59-
self->last = Py_NewRef(last);
60-
Py_XDECREF(tmp);
56+
Py_XSETREF(self->last, Py_NewRef(last));
6157
}
6258
return 0;
6359
}

Doc/includes/custom3.c

+5-15
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,18 @@ static int
4242
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
4343
{
4444
static char *kwlist[] = {"first", "last", "number", NULL};
45-
PyObject *first = NULL, *last = NULL, *tmp;
45+
PyObject *first = NULL, *last = NULL;
4646

4747
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
4848
&first, &last,
4949
&self->number))
5050
return -1;
5151

5252
if (first) {
53-
tmp = self->first;
54-
self->first = Py_NewRef(first);
55-
Py_DECREF(tmp);
53+
Py_SETREF(self->first, Py_NewRef(first));
5654
}
5755
if (last) {
58-
tmp = self->last;
59-
self->last = Py_NewRef(last);
60-
Py_DECREF(tmp);
56+
Py_SETREF(self->last, Py_NewRef(last));
6157
}
6258
return 0;
6359
}
@@ -77,7 +73,6 @@ Custom_getfirst(CustomObject *self, void *closure)
7773
static int
7874
Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
7975
{
80-
PyObject *tmp;
8176
if (value == NULL) {
8277
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
8378
return -1;
@@ -87,9 +82,7 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
8782
"The first attribute value must be a string");
8883
return -1;
8984
}
90-
tmp = self->first;
91-
self->first = Py_NewRef(value);
92-
Py_DECREF(tmp);
85+
Py_SETREF(self->first, Py_NewRef(value));
9386
return 0;
9487
}
9588

@@ -102,7 +95,6 @@ Custom_getlast(CustomObject *self, void *closure)
10295
static int
10396
Custom_setlast(CustomObject *self, PyObject *value, void *closure)
10497
{
105-
PyObject *tmp;
10698
if (value == NULL) {
10799
PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
108100
return -1;
@@ -112,9 +104,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure)
112104
"The last attribute value must be a string");
113105
return -1;
114106
}
115-
tmp = self->last;
116-
self->last = Py_NewRef(value);
117-
Py_DECREF(tmp);
107+
Py_SETREF(self->last, Py_NewRef(value));
118108
return 0;
119109
}
120110

Doc/includes/custom4.c

+5-13
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,18 @@ static int
5858
Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
5959
{
6060
static char *kwlist[] = {"first", "last", "number", NULL};
61-
PyObject *first = NULL, *last = NULL, *tmp;
61+
PyObject *first = NULL, *last = NULL;
6262

6363
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
6464
&first, &last,
6565
&self->number))
6666
return -1;
6767

6868
if (first) {
69-
tmp = self->first;
70-
self->first = Py_NewRef(first);
71-
Py_DECREF(tmp);
69+
Py_SETREF(self->first, Py_NewRef(first));
7270
}
7371
if (last) {
74-
tmp = self->last;
75-
self->last = Py_NewRef(last);
76-
Py_DECREF(tmp);
72+
Py_SETREF(self->last, Py_NewRef(last));
7773
}
7874
return 0;
7975
}
@@ -102,9 +98,7 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
10298
"The first attribute value must be a string");
10399
return -1;
104100
}
105-
Py_INCREF(value);
106-
Py_CLEAR(self->first);
107-
self->first = value;
101+
Py_XSETREF(self->first, Py_NewRef(value));
108102
return 0;
109103
}
110104

@@ -126,9 +120,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure)
126120
"The last attribute value must be a string");
127121
return -1;
128122
}
129-
Py_INCREF(value);
130-
Py_CLEAR(self->last);
131-
self->last = value;
123+
Py_XSETREF(self->last, Py_NewRef(value));
132124
return 0;
133125
}
134126

Modules/_collectionsmodule.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,6 @@ deque_remove(dequeobject *deque, PyObject *value)
12561256
static int
12571257
deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
12581258
{
1259-
PyObject *old_value;
12601259
block *b;
12611260
Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
12621261

@@ -1282,9 +1281,7 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
12821281
while (--n >= 0)
12831282
b = b->leftlink;
12841283
}
1285-
old_value = b->data[i];
1286-
b->data[i] = Py_NewRef(v);
1287-
Py_DECREF(old_value);
1284+
Py_SETREF(b->data[i], Py_NewRef(v));
12881285
return 0;
12891286
}
12901287

Modules/_datetimemodule.c

+2-6
Original file line numberDiff line numberDiff line change
@@ -6247,13 +6247,10 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
62476247
}
62486248
else {
62496249
/* Result is already aware - just replace tzinfo. */
6250-
temp = result->tzinfo;
6251-
result->tzinfo = Py_NewRef(PyDateTime_TimeZone_UTC);
6252-
Py_DECREF(temp);
6250+
Py_SETREF(result->tzinfo, Py_NewRef(PyDateTime_TimeZone_UTC));
62536251
}
62546252

62556253
/* Attach new tzinfo and let fromutc() do the rest. */
6256-
temp = result->tzinfo;
62576254
if (tzinfo == Py_None) {
62586255
tzinfo = local_timezone(result);
62596256
if (tzinfo == NULL) {
@@ -6263,8 +6260,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
62636260
}
62646261
else
62656262
Py_INCREF(tzinfo);
6266-
result->tzinfo = tzinfo;
6267-
Py_DECREF(temp);
6263+
Py_SETREF(result->tzinfo, tzinfo);
62686264

62696265
temp = (PyObject *)result;
62706266
result = (PyDateTime_DateTime *)

Modules/_elementtree.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,7 @@ element_get_text(ElementObject* self)
537537
if (!tmp)
538538
return NULL;
539539
self->text = tmp;
540-
Py_DECREF(res);
541-
res = tmp;
540+
Py_SETREF(res, tmp);
542541
}
543542
}
544543

@@ -559,8 +558,7 @@ element_get_tail(ElementObject* self)
559558
if (!tmp)
560559
return NULL;
561560
self->tail = tmp;
562-
Py_DECREF(res);
563-
res = tmp;
561+
Py_SETREF(res, tmp);
564562
}
565563
}
566564

Modules/_functoolsmodule.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1243,8 +1243,7 @@ lru_cache_clear_list(lru_list_elem *link)
12431243
{
12441244
while (link != NULL) {
12451245
lru_list_elem *next = link->next;
1246-
Py_DECREF(link);
1247-
link = next;
1246+
Py_SETREF(link, next);
12481247
}
12491248
}
12501249

Modules/_io/stringio.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ write_str(stringio *self, PyObject *obj)
193193
if (self->writenl) {
194194
PyObject *translated = PyUnicode_Replace(
195195
decoded, &_Py_STR(newline), self->writenl, -1);
196-
Py_DECREF(decoded);
197-
decoded = translated;
196+
Py_SETREF(decoded, translated);
198197
}
199198
if (decoded == NULL)
200199
return -1;

Modules/_io/textio.c

+3-6
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself,
320320
out = PyUnicode_DATA(modified);
321321
PyUnicode_WRITE(kind, out, 0, '\r');
322322
memcpy(out + kind, PyUnicode_DATA(output), kind * output_len);
323-
Py_DECREF(output);
324-
output = modified; /* output remains ready */
323+
Py_SETREF(output, modified); /* output remains ready */
325324
self->pendingcr = 0;
326325
output_len++;
327326
}
@@ -336,8 +335,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself,
336335
PyObject *modified = PyUnicode_Substring(output, 0, output_len -1);
337336
if (modified == NULL)
338337
goto error;
339-
Py_DECREF(output);
340-
output = modified;
338+
Py_SETREF(output, modified);
341339
self->pendingcr = 1;
342340
}
343341
}
@@ -865,8 +863,7 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info,
865863
self->decoder, self->readtranslate ? Py_True : Py_False, NULL);
866864
if (incrementalDecoder == NULL)
867865
return -1;
868-
Py_CLEAR(self->decoder);
869-
self->decoder = incrementalDecoder;
866+
Py_XSETREF(self->decoder, incrementalDecoder);
870867
}
871868

872869
return 0;

Modules/_json.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -709,9 +709,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
709709
if (memokey == NULL) {
710710
goto bail;
711711
}
712-
Py_INCREF(memokey);
713-
Py_DECREF(key);
714-
key = memokey;
712+
Py_SETREF(key, Py_NewRef(memokey));
715713
idx = next_idx;
716714

717715
/* skip whitespace between key and : delimiter, read :, skip whitespace */

Modules/_pickle.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -1829,8 +1829,7 @@ get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent)
18291829
n = PyList_GET_SIZE(names);
18301830
for (i = 0; i < n; i++) {
18311831
PyObject *name = PyList_GET_ITEM(names, i);
1832-
Py_XDECREF(parent);
1833-
parent = obj;
1832+
Py_XSETREF(parent, obj);
18341833
(void)_PyObject_LookupAttr(parent, name, &obj);
18351834
if (obj == NULL) {
18361835
Py_DECREF(parent);
@@ -3717,9 +3716,7 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
37173716
else {
37183717
gen_global:
37193718
if (parent == module) {
3720-
Py_INCREF(lastname);
3721-
Py_DECREF(global_name);
3722-
global_name = lastname;
3719+
Py_SETREF(global_name, Py_NewRef(lastname));
37233720
}
37243721
if (self->proto >= 4) {
37253722
const char stack_global_op = STACK_GLOBAL;

Modules/_sqlite/cursor.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1123,8 +1123,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
11231123
PyObject *factory = self->row_factory;
11241124
PyObject *args[] = { (PyObject *)self, row, };
11251125
PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL);
1126-
Py_DECREF(row);
1127-
row = new_row;
1126+
Py_SETREF(row, new_row);
11281127
}
11291128
return row;
11301129
}

Modules/_testinternalcapi.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,7 @@ set_eval_frame_record(PyObject *self, PyObject *list)
523523
PyErr_SetString(PyExc_TypeError, "argument must be a list");
524524
return NULL;
525525
}
526-
Py_CLEAR(record_list);
527-
record_list = Py_NewRef(list);
526+
Py_XSETREF(record_list, Py_NewRef(list));
528527
_PyInterpreterState_SetEvalFrameFunc(PyInterpreterState_Get(), record_eval);
529528
Py_RETURN_NONE;
530529
}

Modules/_tkinter.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1105,8 +1105,7 @@ fromBignumObj(TkappObject *tkapp, Tcl_Obj *value)
11051105
PyMem_Free(bytes);
11061106
if (res != NULL && bigValue.sign == MP_NEG) {
11071107
PyObject *res2 = PyNumber_Negative(res);
1108-
Py_DECREF(res);
1109-
res = res2;
1108+
Py_SETREF(res, res2);
11101109
}
11111110
mp_clear(&bigValue);
11121111
return res;

Modules/_zoneinfo.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1074,8 +1074,7 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj)
10741074
// that the dstoff is set correctly in that case.
10751075
if (PyObject_IsTrue(tti->dstoff)) {
10761076
_ttinfo *tti_after = &(self->tzrule_after.std);
1077-
Py_DECREF(tti_after->dstoff);
1078-
tti_after->dstoff = Py_NewRef(tti->dstoff);
1077+
Py_SETREF(tti_after->dstoff, Py_NewRef(tti->dstoff));
10791078
}
10801079
}
10811080

Modules/audioop.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1471,8 +1471,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
14711471
len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
14721472
rv = PyBytes_FromStringAndSize
14731473
(PyBytes_AsString(str), len);
1474-
Py_DECREF(str);
1475-
str = rv;
1474+
Py_SETREF(str, rv);
14761475
if (str == NULL)
14771476
goto exit;
14781477
rv = Py_BuildValue("(O(iO))", str, d, samps);

Modules/cjkcodecs/multibytecodec.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -980,8 +980,7 @@ _multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEn
980980
goto errorexit;
981981
}
982982

983-
Py_CLEAR(self->pending);
984-
self->pending = pending;
983+
Py_XSETREF(self->pending, pending);
985984
memcpy(self->state.c, statebytes+1+statebytes[0],
986985
sizeof(self->state.c));
987986

@@ -1438,8 +1437,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self,
14381437
memcpy(ctrdata + self->pendingsize,
14391438
PyBytes_AS_STRING(cres),
14401439
PyBytes_GET_SIZE(cres));
1441-
Py_DECREF(cres);
1442-
cres = ctr;
1440+
Py_SETREF(cres, ctr);
14431441
self->pendingsize = 0;
14441442
}
14451443

Modules/itertoolsmodule.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,7 @@ teedataobject_safe_decref(PyObject *obj)
834834
Py_REFCNT(obj) == 1) {
835835
PyObject *nextlink = ((teedataobject *)obj)->nextlink;
836836
((teedataobject *)obj)->nextlink = NULL;
837-
Py_DECREF(obj);
838-
obj = nextlink;
837+
Py_SETREF(obj, nextlink);
839838
}
840839
Py_XDECREF(obj);
841840
}

Modules/mathmodule.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -2069,17 +2069,15 @@ factorial_odd_part(unsigned long n)
20692069
Py_DECREF(partial);
20702070
if (tmp == NULL)
20712071
goto error;
2072-
Py_DECREF(inner);
2073-
inner = tmp;
2072+
Py_SETREF(inner, tmp);
20742073
/* Now inner is the product of all odd integers j in the range (0,
20752074
n/2**i], giving the inner product in the formula above. */
20762075

20772076
/* outer *= inner; */
20782077
tmp = PyNumber_Multiply(outer, inner);
20792078
if (tmp == NULL)
20802079
goto error;
2081-
Py_DECREF(outer);
2082-
outer = tmp;
2080+
Py_SETREF(outer, tmp);
20832081
}
20842082
Py_DECREF(inner);
20852083
return outer;

Modules/posixmodule.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -1202,8 +1202,7 @@ path_converter(PyObject *o, void *p)
12021202
}
12031203

12041204
/* still owns a reference to the original object */
1205-
Py_DECREF(o);
1206-
o = res;
1205+
Py_SETREF(o, res);
12071206
}
12081207

12091208
if (is_unicode) {

0 commit comments

Comments
 (0)