quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

commit 792c9b43d374906770eb7d8ccede8240d03a7ac1
parent b17365c5b475fabf5aeed10c7d8f4952337680bf
Author: Iván Ávalos <avalos@disroot.org>
Date:   Thu, 13 Jun 2024 13:21:21 -0600

android: fix SIGSEGV when passing response

Diffstat:
MQuickJS-android/qtart/src/main/java/net/taler/qtart/Networking.kt | 13+++++++++++--
MQuickJS-android/qtart/src/main/java/net/taler/qtart/TalerWalletCore.kt | 5+++--
Mquickjs/quickjs-http.h | 10+++++-----
Mquickjs/quickjs-libc.c | 5+++++
4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/QuickJS-android/qtart/src/main/java/net/taler/qtart/Networking.kt b/QuickJS-android/qtart/src/main/java/net/taler/qtart/Networking.kt @@ -1,6 +1,8 @@ package net.taler.qtart import android.util.Log +import com.sun.jna.Memory +import com.sun.jna.Pointer import com.sun.jna.StringArray import java.util.concurrent.atomic.AtomicInteger import net.taler.qtart.TalerWalletCore.TalerNative.* @@ -8,6 +10,9 @@ import net.taler.qtart.TalerWalletCore.TalerNative.* object Networking { private val lastRequestId = AtomicInteger(0) + // Add your pointer here to protect it from the GC! + private val pointerReferences = mutableListOf<Pointer>() + interface RequestHandler { fun handleRequest(req: RequestInfo, id: Int, sendResponse: (resp: ResponseInfo) -> Unit) fun cancelRequest(id: Int): Boolean @@ -87,11 +92,15 @@ object Networking { val rawResp = JSHttpResponseInfo() rawResp.request_id = resp.requestId rawResp.status = resp.status - rawResp.errmsg = resp.errorMsg + rawResp.errmsg = resp.errorMsg ?: "" rawResp.response_headers = StringArray(resp.headers, false) rawResp.num_response_headers = resp.headers.size if (resp.body != null) { - rawResp.body = resp.body + // Manually allocate and write memory + val pointer = Memory(resp.body.size.toLong()) + pointer.write(0, resp.body, 0, resp.body.size) + pointerReferences.add(pointer) + rawResp.body = pointer rawResp.body_len = resp.body.size } else { rawResp.body_len = 0 diff --git a/QuickJS-android/qtart/src/main/java/net/taler/qtart/TalerWalletCore.kt b/QuickJS-android/qtart/src/main/java/net/taler/qtart/TalerWalletCore.kt @@ -42,6 +42,7 @@ class TalerWalletCore { internal interface TalerNative : Library { companion object { val INSTANCE: TalerNative by lazy { + Native.setProtected(true) Native.load("talerwalletcore", TalerNative::class.java) } } @@ -103,7 +104,7 @@ class TalerWalletCore { @JvmField var errmsg: String? = null @JvmField var response_headers: Pointer? = null @JvmField var num_response_headers: Int? = null - @JvmField var body: ByteArray? = null + @JvmField var body: Pointer? = null @JvmField var body_len: Int? = null override fun getFieldOrder() = mutableListOf( @@ -112,8 +113,8 @@ class TalerWalletCore { "errmsg", "response_headers", "num_response_headers", - "body", "body_len", + "body", ) } diff --git a/quickjs/quickjs-http.h b/quickjs/quickjs-http.h @@ -124,7 +124,7 @@ struct JSHttpRequestInfo { /** * Length or request body or 0. */ - size_t req_body_len; + uint32_t req_body_len; }; /** @@ -160,14 +160,14 @@ struct JSHttpResponseInfo { int num_response_headers; /** - * Response body or NULL. + * Length of the response body or 0. */ - void *body; + uint32_t body_len; /** - * Length of the response body or 0. + * Response body or NULL. */ - size_t body_len; + void *body; }; /** diff --git a/quickjs/quickjs-libc.c b/quickjs/quickjs-libc.c @@ -2206,6 +2206,8 @@ static void js_free_http_message(JSHttpMessage *msg) static void handle_http_resp(void *cls, struct JSHttpResponseInfo *resp_info) { + printf("received response for request %i from native client\n", resp_info->request_id); + // Called from a different thread. // We must enqueue something that the message loop will process // @@ -2233,6 +2235,7 @@ static void handle_http_resp(void *cls, struct JSHttpResponseInfo *resp_info) if (!msg->response_headers) { goto fail; } + memset(msg->response_headers, 0, (num_headers + 1) * sizeof (char *)); for (int i = 0; i < num_headers; i++) { msg->response_headers[i] = strdup(resp_info->response_headers[i]); @@ -2276,8 +2279,10 @@ static void handle_http_resp(void *cls, struct JSHttpResponseInfo *resp_info) } list_add_tail(&msg->link, &hp->msg_queue); pthread_mutex_unlock(&hp->mutex); + printf("finished handling http response for request %i\n", resp_info->request_id); return; fail: + printf("error handling http response for request %i\n", resp_info->request_id); js_free_http_message(msg); return; }