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:
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;
}