Skip to content

Commit 1dba017

Browse files
alexmalyshevmeta-codesync[bot]
authored andcommitted
Fix PyObject_IsInstance error handling in AsyncLazyValue_set_error
Summary: Two issues fixed: 1. cancelledError() can return nullptr if asyncio.exceptions import fails; passing nullptr to PyObject_IsInstance is undefined behavior. 2. PyObject_IsInstance returns -1 on error, which is truthy in C, causing the cancel path to be silently taken on internal errors. Now we check for nullptr before calling PyObject_IsInstance and properly propagate -1 errors to the caller. Reviewed By: yoney Differential Revision: D96862209 fbshipit-source-id: 4d439ae1d6a931c9387eb68546bc52d794864f7b
1 parent 208d664 commit 1dba017

1 file changed

Lines changed: 17 additions & 7 deletions

File tree

cinderx/async_lazy_value.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -487,17 +487,27 @@ static int AsyncLazyValue_set_result(AsyncLazyValueObj* self, PyObject* res) {
487487
}
488488

489489
static int AsyncLazyValue_set_error(AsyncLazyValueObj* self, PyObject* exc) {
490-
int ok;
491-
if (PyObject_IsInstance(exc, get_state()->cancelledError())) {
492-
ok = notify_futures(self->alv_futures, future_cancel_impl, exc);
493-
} else {
494-
ok = notify_futures(
495-
self->alv_futures, AsyncLazyValue_future_set_exception, exc);
490+
BorrowedRef<PyTypeObject> cancelled_error = get_state()->cancelledError();
491+
if (cancelled_error == nullptr) {
492+
return -1;
493+
}
494+
495+
int is_cancelled_error = PyObject_IsInstance(exc, cancelled_error);
496+
if (is_cancelled_error < 0) {
497+
return -1;
498+
}
499+
500+
int notified = is_cancelled_error
501+
? notify_futures(self->alv_futures, future_cancel_impl, exc)
502+
: notify_futures(
503+
self->alv_futures, AsyncLazyValue_future_set_exception, exc);
504+
if (notified < 0) {
505+
return -1;
496506
}
497507

498508
Py_CLEAR(self->alv_futures);
499509
self->alv_state = ALV_NOT_STARTED;
500-
return ok;
510+
return 0;
501511
}
502512

503513
static PyObject* AsyncLazyValue_new_computeobj(AsyncLazyValueObj* self) {

0 commit comments

Comments
 (0)