From 1716cdf51c533107deef4f40945c09b4f17c3f6c Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Thu, 23 Mar 2023 14:15:34 +0100 Subject: [PATCH] ref(ffi): dc_receive_backup should block (#4211) The documentation says this blocks. This should block because it also means the error reporting is more accurate by calling set_last_error just before returning. --- deltachat-ffi/src/lib.rs | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index e0266e925..63d8d52bf 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -4233,21 +4233,6 @@ pub unsafe extern "C" fn dc_backup_provider_unref(provider: *mut dc_backup_provi drop(Box::from_raw(provider)); } -fn receive_backup(ctx: Context, qr_text: String) -> libc::c_int { - let qr = match block_on(qr::check_qr(&ctx, &qr_text)).log_err(&ctx, "Invalid QR code") { - Ok(qr) => qr, - Err(_) => return 0, - }; - spawn(async move { - let ctx = ctx; - imex::get_backup(&ctx, qr) - .await - .log_err(&ctx, "Get backup failed") - .ok(); - }); - 1 -} - #[no_mangle] pub unsafe extern "C" fn dc_receive_backup( context: *mut dc_context_t, @@ -4262,6 +4247,27 @@ pub unsafe extern "C" fn dc_receive_backup( receive_backup(ctx.clone(), qr_text) } +// Because this is a long-running operation make sure we own the Context. This stops a FFI +// user from deallocating it by calling unref on the object while we are using it. +fn receive_backup(ctx: Context, qr_text: String) -> libc::c_int { + let qr = match block_on(qr::check_qr(&ctx, &qr_text)) + .log_err(&ctx, "Invalid QR code") + .context("Invalid QR code") + .set_last_error(&ctx) + { + Ok(qr) => qr, + Err(_) => return 0, + }; + match block_on(imex::get_backup(&ctx, qr)) + .log_err(&ctx, "Get backup failed") + .context("Get backup failed") + .set_last_error(&ctx) + { + Ok(_) => 1, + Err(_) => 0, + } +} + trait ResultExt { /// Like `log_err()`, but: /// - returns the default value instead of an Err value.