]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-99537: Use Py_SETREF() function in C code (#99656)
authorVictor Stinner <vstinner@python.org>
Tue, 22 Nov 2022 13:22:22 +0000 (14:22 +0100)
committerGitHub <noreply@github.com>
Tue, 22 Nov 2022 13:22:22 +0000 (14:22 +0100)
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.

20 files changed:
Doc/includes/custom2.c
Doc/includes/custom3.c
Doc/includes/custom4.c
Modules/_collectionsmodule.c
Modules/_datetimemodule.c
Modules/_elementtree.c
Modules/_functoolsmodule.c
Modules/_io/stringio.c
Modules/_io/textio.c
Modules/_json.c
Modules/_pickle.c
Modules/_sqlite/cursor.c
Modules/_testinternalcapi.c
Modules/_tkinter.c
Modules/_zoneinfo.c
Modules/audioop.c
Modules/cjkcodecs/multibytecodec.c
Modules/itertoolsmodule.c
Modules/mathmodule.c
Modules/posixmodule.c

index 6638b9fbc1d75168cf1ba0f0fdc163c436511072..a3b2d6ab78d3c4921743e2177ea8f2b9f1f44c3d 100644 (file)
@@ -42,7 +42,7 @@ static int
 Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
 {
     static char *kwlist[] = {"first", "last", "number", NULL};
-    PyObject *first = NULL, *last = NULL, *tmp;
+    PyObject *first = NULL, *last = NULL;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist,
                                      &first, &last,
@@ -50,14 +50,10 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
         return -1;
 
     if (first) {
-        tmp = self->first;
-        self->first = Py_NewRef(first);
-        Py_XDECREF(tmp);
+        Py_XSETREF(self->first, Py_NewRef(first));
     }
     if (last) {
-        tmp = self->last;
-        self->last = Py_NewRef(last);
-        Py_XDECREF(tmp);
+        Py_XSETREF(self->last, Py_NewRef(last));
     }
     return 0;
 }
index 0faf2bd4be172acfcc6555af8a2bb10fa8edaaad..1a68bc4be8c39916cfdae8ea370295f6bde31c2c 100644 (file)
@@ -42,7 +42,7 @@ static int
 Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
 {
     static char *kwlist[] = {"first", "last", "number", NULL};
-    PyObject *first = NULL, *last = NULL, *tmp;
+    PyObject *first = NULL, *last = NULL;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
                                      &first, &last,
@@ -50,14 +50,10 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
         return -1;
 
     if (first) {
-        tmp = self->first;
-        self->first = Py_NewRef(first);
-        Py_DECREF(tmp);
+        Py_SETREF(self->first, Py_NewRef(first));
     }
     if (last) {
-        tmp = self->last;
-        self->last = Py_NewRef(last);
-        Py_DECREF(tmp);
+        Py_SETREF(self->last, Py_NewRef(last));
     }
     return 0;
 }
@@ -77,7 +73,6 @@ Custom_getfirst(CustomObject *self, void *closure)
 static int
 Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
 {
-    PyObject *tmp;
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
         return -1;
@@ -87,9 +82,7 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
                         "The first attribute value must be a string");
         return -1;
     }
-    tmp = self->first;
-    self->first = Py_NewRef(value);
-    Py_DECREF(tmp);
+    Py_SETREF(self->first, Py_NewRef(value));
     return 0;
 }
 
@@ -102,7 +95,6 @@ Custom_getlast(CustomObject *self, void *closure)
 static int
 Custom_setlast(CustomObject *self, PyObject *value, void *closure)
 {
-    PyObject *tmp;
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
         return -1;
@@ -112,9 +104,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure)
                         "The last attribute value must be a string");
         return -1;
     }
-    tmp = self->last;
-    self->last = Py_NewRef(value);
-    Py_DECREF(tmp);
+    Py_SETREF(self->last, Py_NewRef(value));
     return 0;
 }
 
index b725bc0b6fae3a317cab2e6e6dd1e4f7f6957ac4..b932d159d26e93e92e80b849bf05a06550706d01 100644 (file)
@@ -58,7 +58,7 @@ static int
 Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
 {
     static char *kwlist[] = {"first", "last", "number", NULL};
-    PyObject *first = NULL, *last = NULL, *tmp;
+    PyObject *first = NULL, *last = NULL;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist,
                                      &first, &last,
@@ -66,14 +66,10 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds)
         return -1;
 
     if (first) {
-        tmp = self->first;
-        self->first = Py_NewRef(first);
-        Py_DECREF(tmp);
+        Py_SETREF(self->first, Py_NewRef(first));
     }
     if (last) {
-        tmp = self->last;
-        self->last = Py_NewRef(last);
-        Py_DECREF(tmp);
+        Py_SETREF(self->last, Py_NewRef(last));
     }
     return 0;
 }
@@ -102,9 +98,7 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure)
                         "The first attribute value must be a string");
         return -1;
     }
-    Py_INCREF(value);
-    Py_CLEAR(self->first);
-    self->first = value;
+    Py_XSETREF(self->first, Py_NewRef(value));
     return 0;
 }
 
@@ -126,9 +120,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure)
                         "The last attribute value must be a string");
         return -1;
     }
-    Py_INCREF(value);
-    Py_CLEAR(self->last);
-    self->last = value;
+    Py_XSETREF(self->last, Py_NewRef(value));
     return 0;
 }
 
index f1fd271f6d213f51873fb5e5aff2f287222bed89..5fa583821889f30f5d3254c74d47da876ae56f9b 100644 (file)
@@ -1256,7 +1256,6 @@ deque_remove(dequeobject *deque, PyObject *value)
 static int
 deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
 {
-    PyObject *old_value;
     block *b;
     Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
 
@@ -1282,9 +1281,7 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
         while (--n >= 0)
             b = b->leftlink;
     }
-    old_value = b->data[i];
-    b->data[i] = Py_NewRef(v);
-    Py_DECREF(old_value);
+    Py_SETREF(b->data[i], Py_NewRef(v));
     return 0;
 }
 
index 20e8516fcde7fb45285e4621294b75088f44d287..712abc3346faf919f575e14384262ed8fd57e41e 100644 (file)
@@ -6247,13 +6247,10 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
     }
     else {
         /* Result is already aware - just replace tzinfo. */
-        temp = result->tzinfo;
-        result->tzinfo = Py_NewRef(PyDateTime_TimeZone_UTC);
-        Py_DECREF(temp);
+        Py_SETREF(result->tzinfo, Py_NewRef(PyDateTime_TimeZone_UTC));
     }
 
     /* Attach new tzinfo and let fromutc() do the rest. */
-    temp = result->tzinfo;
     if (tzinfo == Py_None) {
         tzinfo = local_timezone(result);
         if (tzinfo == NULL) {
@@ -6263,8 +6260,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
     }
     else
       Py_INCREF(tzinfo);
-    result->tzinfo = tzinfo;
-    Py_DECREF(temp);
+    Py_SETREF(result->tzinfo, tzinfo);
 
     temp = (PyObject *)result;
     result = (PyDateTime_DateTime *)
index 7b0977931f2ae6788e3cf23f31e6895488724293..3df93651654a766aee452c8bbbce51e46bd89e43 100644 (file)
@@ -537,8 +537,7 @@ element_get_text(ElementObject* self)
             if (!tmp)
                 return NULL;
             self->text = tmp;
-            Py_DECREF(res);
-            res = tmp;
+            Py_SETREF(res, tmp);
         }
     }
 
@@ -559,8 +558,7 @@ element_get_tail(ElementObject* self)
             if (!tmp)
                 return NULL;
             self->tail = tmp;
-            Py_DECREF(res);
-            res = tmp;
+            Py_SETREF(res, tmp);
         }
     }
 
index 9b30f41ec69932ecf16c5580e81d141e44e4307c..4032ba79374fa4fe539a4f3efcaf0ed680cb2fef 100644 (file)
@@ -1243,8 +1243,7 @@ lru_cache_clear_list(lru_list_elem *link)
 {
     while (link != NULL) {
         lru_list_elem *next = link->next;
-        Py_DECREF(link);
-        link = next;
+        Py_SETREF(link, next);
     }
 }
 
index 5c3bf353680ea4d18a3c6cb060348f55aac8741a..ae6c3125a2d9da447bea8ee1aaf72207bcb59861 100644 (file)
@@ -193,8 +193,7 @@ write_str(stringio *self, PyObject *obj)
     if (self->writenl) {
         PyObject *translated = PyUnicode_Replace(
             decoded, &_Py_STR(newline), self->writenl, -1);
-        Py_DECREF(decoded);
-        decoded = translated;
+        Py_SETREF(decoded, translated);
     }
     if (decoded == NULL)
         return -1;
index 8b5d00fe4aafd7b1d1446c3bb4fe9833d351e7a3..ff903e9341de271bcce6badf32733305fadbd0cf 100644 (file)
@@ -320,8 +320,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself,
         out = PyUnicode_DATA(modified);
         PyUnicode_WRITE(kind, out, 0, '\r');
         memcpy(out + kind, PyUnicode_DATA(output), kind * output_len);
-        Py_DECREF(output);
-        output = modified; /* output remains ready */
+        Py_SETREF(output, modified); /* output remains ready */
         self->pendingcr = 0;
         output_len++;
     }
@@ -336,8 +335,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself,
             PyObject *modified = PyUnicode_Substring(output, 0, output_len -1);
             if (modified == NULL)
                 goto error;
-            Py_DECREF(output);
-            output = modified;
+            Py_SETREF(output, modified);
             self->pendingcr = 1;
         }
     }
@@ -865,8 +863,7 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info,
             self->decoder, self->readtranslate ? Py_True : Py_False, NULL);
         if (incrementalDecoder == NULL)
             return -1;
-        Py_CLEAR(self->decoder);
-        self->decoder = incrementalDecoder;
+        Py_XSETREF(self->decoder, incrementalDecoder);
     }
 
     return 0;
index 06f232f7d7de9b6d9481eb1669179f1b502f0204..81431aa1041c558ae06494f1c2bef21b81d6ee33 100644 (file)
@@ -709,9 +709,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
             if (memokey == NULL) {
                 goto bail;
             }
-            Py_INCREF(memokey);
-            Py_DECREF(key);
-            key = memokey;
+            Py_SETREF(key, Py_NewRef(memokey));
             idx = next_idx;
 
             /* skip whitespace between key and : delimiter, read :, skip whitespace */
index db62094c5a5af956eea305db251a2bc43483d01c..1e118e9cd10bbf25697355bc02e5f9fc7f60c754 100644 (file)
@@ -1829,8 +1829,7 @@ get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent)
     n = PyList_GET_SIZE(names);
     for (i = 0; i < n; i++) {
         PyObject *name = PyList_GET_ITEM(names, i);
-        Py_XDECREF(parent);
-        parent = obj;
+        Py_XSETREF(parent, obj);
         (void)_PyObject_LookupAttr(parent, name, &obj);
         if (obj == NULL) {
             Py_DECREF(parent);
@@ -3717,9 +3716,7 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
     else {
   gen_global:
         if (parent == module) {
-            Py_INCREF(lastname);
-            Py_DECREF(global_name);
-            global_name = lastname;
+            Py_SETREF(global_name, Py_NewRef(lastname));
         }
         if (self->proto >= 4) {
             const char stack_global_op = STACK_GLOBAL;
index 7844b6e26cdbda7d28962f8b042e6e951739ebc7..a4e22bb4a2b58d71bb6ed7da01b03e4c05537a8f 100644 (file)
@@ -1123,8 +1123,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self)
         PyObject *factory = self->row_factory;
         PyObject *args[] = { (PyObject *)self, row, };
         PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL);
-        Py_DECREF(row);
-        row = new_row;
+        Py_SETREF(row, new_row);
     }
     return row;
 }
index cec114cb5919da295fe3ea885e336a8ccefb6c99..b14b8ac3c7405465f21cc94ab034ae7d01489a9e 100644 (file)
@@ -523,8 +523,7 @@ set_eval_frame_record(PyObject *self, PyObject *list)
         PyErr_SetString(PyExc_TypeError, "argument must be a list");
         return NULL;
     }
-    Py_CLEAR(record_list);
-    record_list = Py_NewRef(list);
+    Py_XSETREF(record_list, Py_NewRef(list));
     _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState_Get(), record_eval);
     Py_RETURN_NONE;
 }
index a5d5428eaf507744f823d7abb84c8d93a8d7a3f6..6ff7d2bfced29b2efca7f88c36a51168ac78ba0d 100644 (file)
@@ -1105,8 +1105,7 @@ fromBignumObj(TkappObject *tkapp, Tcl_Obj *value)
     PyMem_Free(bytes);
     if (res != NULL && bigValue.sign == MP_NEG) {
         PyObject *res2 = PyNumber_Negative(res);
-        Py_DECREF(res);
-        res = res2;
+        Py_SETREF(res, res2);
     }
     mp_clear(&bigValue);
     return res;
index 34f5abd343ece02cbbbb629ce25aa5015e9bc121..c0fef13ba17d205109760e7252a9fd532872e1af 100644 (file)
@@ -1074,8 +1074,7 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj)
         // that the dstoff is set correctly in that case.
         if (PyObject_IsTrue(tti->dstoff)) {
             _ttinfo *tti_after = &(self->tzrule_after.std);
-            Py_DECREF(tti_after->dstoff);
-            tti_after->dstoff = Py_NewRef(tti->dstoff);
+            Py_SETREF(tti_after->dstoff, Py_NewRef(tti->dstoff));
         }
     }
 
index 6d484e8bba3ec72734978e88aa9bcc12dd049ce1..9325f82f9a17e069bf5b3f1131bba72c5fe87ee4 100644 (file)
@@ -1471,8 +1471,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
                 len = (Py_ssize_t)(ncp - PyBytes_AsString(str));
                 rv = PyBytes_FromStringAndSize
                     (PyBytes_AsString(str), len);
-                Py_DECREF(str);
-                str = rv;
+                Py_SETREF(str, rv);
                 if (str == NULL)
                     goto exit;
                 rv = Py_BuildValue("(O(iO))", str, d, samps);
index 6d67fce1da0353fa986df8dfe79451dd79824e8f..8b6232695d4c13e50295ffa375fb6058aea05728 100644 (file)
@@ -980,8 +980,7 @@ _multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEn
         goto errorexit;
     }
 
-    Py_CLEAR(self->pending);
-    self->pending = pending;
+    Py_XSETREF(self->pending, pending);
     memcpy(self->state.c, statebytes+1+statebytes[0],
            sizeof(self->state.c));
 
@@ -1438,8 +1437,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self,
             memcpy(ctrdata + self->pendingsize,
                     PyBytes_AS_STRING(cres),
                     PyBytes_GET_SIZE(cres));
-            Py_DECREF(cres);
-            cres = ctr;
+            Py_SETREF(cres, ctr);
             self->pendingsize = 0;
         }
 
index 65d01425052241f369422374aa709511cd9a0568..4b0a4d88c435c62768253811ddeefe112fd47ee8 100644 (file)
@@ -834,8 +834,7 @@ teedataobject_safe_decref(PyObject *obj)
            Py_REFCNT(obj) == 1) {
         PyObject *nextlink = ((teedataobject *)obj)->nextlink;
         ((teedataobject *)obj)->nextlink = NULL;
-        Py_DECREF(obj);
-        obj = nextlink;
+        Py_SETREF(obj, nextlink);
     }
     Py_XDECREF(obj);
 }
index 16a2f45c8b84dfc1a82268606f6d104b52c5e6e7..83eb338be9b83cafc5af649cf65f20e1c6224bc6 100644 (file)
@@ -2069,8 +2069,7 @@ factorial_odd_part(unsigned long n)
         Py_DECREF(partial);
         if (tmp == NULL)
             goto error;
-        Py_DECREF(inner);
-        inner = tmp;
+        Py_SETREF(inner, tmp);
         /* Now inner is the product of all odd integers j in the range (0,
            n/2**i], giving the inner product in the formula above. */
 
@@ -2078,8 +2077,7 @@ factorial_odd_part(unsigned long n)
         tmp = PyNumber_Multiply(outer, inner);
         if (tmp == NULL)
             goto error;
-        Py_DECREF(outer);
-        outer = tmp;
+        Py_SETREF(outer, tmp);
     }
     Py_DECREF(inner);
     return outer;
index 6d65ae97c9e3186fa2a607acbe0340d3dd5be01d..98fc264aff6bf97a11474e25fc14506bcfacf736 100644 (file)
@@ -1202,8 +1202,7 @@ path_converter(PyObject *o, void *p)
         }
 
         /* still owns a reference to the original object */
-        Py_DECREF(o);
-        o = res;
+        Py_SETREF(o, res);
     }
 
     if (is_unicode) {