Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bdb17ae

Browse files
authored
FIX: guard second usage of PyWeakref_GetObject (#934)
* FIX: guard second usage of PyWeakref_GetObject This function was deprecated in 3.13 and will be removed in 3.15. There are two usages in pycurl, one in easy.c was already correctly guarded, the other in share.c was not. * MNT: Handle NULL / dead case in 3.13+ code path correctly * MNT: further simplify handling the both old and new code paths obj is only `None` in the <3.13 code path if the weakref is dead. Handle and return early to simplify later code. * MNT: let weakref errors propogate up and out
1 parent 8c0a5a8 commit bdb17ae

1 file changed

Lines changed: 38 additions & 11 deletions

File tree

src/share.c

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,29 +262,53 @@ share_cleanup_and_count_live_easies(CurlShareObject *self)
262262

263263
if (it && to_remove) {
264264
PyObject *wr;
265+
PyObject *obj = NULL;
265266

266267
while ((wr = PyIter_Next(it))) {
267-
PyObject *obj = PyWeakref_GetObject(wr);
268+
#if PY_VERSION_HEX >= 0x030D0000 /* Python 3.13+ */
269+
int rc = PyWeakref_GetRef(wr, &obj);
270+
// return -1 on error, 0 on dead object
271+
// in either case, mark as removable and
272+
// move to the next reference
273+
if (rc < 0) {
274+
Py_DECREF(wr);
275+
return -1;
276+
} else if (rc == 0 || obj == NULL) {
277+
PyList_Append(to_remove, wr);
278+
Py_DECREF(wr);
279+
continue;
280+
}
281+
282+
#else
283+
// will borrowed reference, None if object dead
284+
obj = PyWeakref_GetObject(wr);
268285
if (obj != Py_None) {
269-
CurlObject *easy = (CurlObject *)obj;
286+
// If not None, real object, INCREF and carry on
287+
Py_INCREF(obj);
288+
} else {
289+
// otherwise mark for removal and move to the next ref
290+
PyList_Append(to_remove, wr);
291+
Py_DECREF(wr);
292+
continue;
293+
}
294+
#endif
295+
CurlObject *easy = (CurlObject *)obj;
270296

271-
if (easy && easy->share == self) {
272-
if (self->detach_on_close) {
273-
curl_easy_setopt(easy->handle, CURLOPT_SHARE, NULL);
274-
easy->share = NULL;
297+
if (easy && easy->share == self) {
298+
if (self->detach_on_close) {
299+
curl_easy_setopt(easy->handle, CURLOPT_SHARE, NULL);
300+
easy->share = NULL;
275301

276-
PyList_Append(to_remove, wr);
277-
} else {
278-
has_live += 1;
279-
}
280-
} else {
281302
PyList_Append(to_remove, wr);
303+
} else {
304+
has_live += 1;
282305
}
283306
} else {
284307
PyList_Append(to_remove, wr);
285308
}
286309

287310
Py_DECREF(wr);
311+
Py_DECREF(obj);
288312
}
289313

290314
Py_ssize_t i, n = PyList_GET_SIZE(to_remove);
@@ -329,6 +353,9 @@ do_share_close(CurlShareObject *self, PyObject *Py_UNUSED(ignored))
329353
(nlive == 1 ? "" : "s")
330354
);
331355
return NULL;
356+
} else if (nlive < 0) {
357+
// Error in share_cleanup_and_count_live_easies, propagate up
358+
return NULL;
332359
}
333360

334361
util_share_close(self);

0 commit comments

Comments
 (0)