From b356e42642e92c18ac632f88204a5e9aceeca558 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 9 Oct 2020 17:10:33 +0100 Subject: [PATCH 1/2] java: add CopyFromBuffer helper and ensure the properly sized ByteBuffer is used --- bindings/java/c/host.c | 53 +++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/bindings/java/c/host.c b/bindings/java/c/host.c index 99075396e..090b35768 100644 --- a/bindings/java/c/host.c +++ b/bindings/java/c/host.c @@ -5,6 +5,7 @@ #include #include +#include #include "host.h" @@ -34,6 +35,20 @@ static jbyteArray CopyDataToJava(JNIEnv* jenv, const void* ptr, size_t size) return ret; } +static void CopyFromByteBuffer(JNIEnv* jenv, jobject src, void* dst, size_t size) +{ + size_t src_size = (size_t)(*jenv)->GetDirectBufferCapacity(jenv, src); + if (src_size != size) + { + jclass exception_class = (*jenv)->FindClass(jenv, "java/lang/IllegalArgumentException"); + assert(exception_class != NULL); + (*jenv)->ThrowNew(jenv, exception_class, "Unexpected length."); + } + void* ptr = (*jenv)->GetDirectBufferAddress(jenv, src); + assert(ptr != NULL); + memcpy(dst, ptr, size); +} + static bool account_exists_fn(struct evmc_host_context* context, const evmc_address* address) { const char java_method_name[] = "account_exists"; @@ -85,11 +100,11 @@ static evmc_bytes32 get_storage_fn(struct evmc_host_context* context, // call java method jobject jresult = (*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index, jaddress, jkey); - assert(jresult != NULL); - evmc_bytes32* result_ptr = (struct evmc_bytes32*)(*jenv)->GetDirectBufferAddress(jenv, jresult); - assert(result_ptr != NULL); - return *result_ptr; // copy here + + evmc_bytes32 result; + CopyFromByteBuffer(jenv, jresult, &result, sizeof(evmc_bytes32)); + return result; } static enum evmc_storage_status set_storage_fn(struct evmc_host_context* context, @@ -148,9 +163,8 @@ static evmc_uint256be get_balance_fn(struct evmc_host_context* context, const ev (*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index, jaddress); assert(jresult != NULL); - evmc_uint256be* result_ptr = (evmc_uint256be*)(*jenv)->GetDirectBufferAddress(jenv, jresult); - assert(result_ptr != NULL); - evmc_uint256be result = *result_ptr; // copy here + evmc_uint256be result; + CopyFromByteBuffer(jenv, jresult, &result, sizeof(evmc_uint256be)); (*jenv)->ReleaseByteArrayElements(jenv, jaddress, (jbyte*)address, 0); @@ -207,9 +221,8 @@ static evmc_bytes32 get_code_hash_fn(struct evmc_host_context* context, const ev (*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index, jaddress); assert(jresult != NULL); - evmc_bytes32* result_ptr = (struct evmc_bytes32*)(*jenv)->GetDirectBufferAddress(jenv, jresult); - assert(result_ptr != NULL); - evmc_bytes32 result = *result_ptr; // copy here + evmc_bytes32 result; + CopyFromByteBuffer(jenv, jresult, &result, sizeof(evmc_bytes32)); (*jenv)->ReleaseByteArrayElements(jenv, jaddress, (jbyte*)address, 0); @@ -312,10 +325,9 @@ static struct evmc_result call_fn(struct evmc_host_context* context, const struc (*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index, jmsg); assert(jresult != NULL); - struct evmc_result* result_ptr = - (struct evmc_result*)(*jenv)->GetDirectBufferAddress(jenv, jresult); - assert(result_ptr != NULL); - return *result_ptr; // copy here + struct evmc_result result; + CopyFromByteBuffer(jenv, jresult, &result, sizeof(struct evmc_result)); + return result; } static struct evmc_tx_context get_tx_context_fn(struct evmc_host_context* context) @@ -339,10 +351,9 @@ static struct evmc_tx_context get_tx_context_fn(struct evmc_host_context* contex jobject jresult = (*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index); assert(jresult != NULL); - struct evmc_tx_context* result_ptr = - (struct evmc_tx_context*)(*jenv)->GetDirectBufferAddress(jenv, jresult); - assert(result_ptr != NULL); - return *result_ptr; // copy here + struct evmc_tx_context result; + CopyFromByteBuffer(jenv, jresult, &result, sizeof(struct evmc_tx_context)); + return result; } static evmc_bytes32 get_block_hash_fn(struct evmc_host_context* context, int64_t number) @@ -367,9 +378,9 @@ static evmc_bytes32 get_block_hash_fn(struct evmc_host_context* context, int64_t (*jenv)->CallStaticObjectMethod(jenv, host_class, method, context->index, (jlong)number); assert(jresult != NULL); - evmc_bytes32* result_ptr = (struct evmc_bytes32*)(*jenv)->GetDirectBufferAddress(jenv, jresult); - assert(result_ptr != NULL); - return *result_ptr; // copy here + evmc_bytes32 result; + CopyFromByteBuffer(jenv, jresult, &result, sizeof(evmc_bytes32)); + return result; } static void emit_log_fn(struct evmc_host_context* context, From fe5420fc55e4ae9f62020798c18f0f740c53c61e Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Sat, 8 Aug 2020 17:40:58 -0700 Subject: [PATCH 2/2] java: set proper length on ByteBuffer returned by Host in tests Co-authored-by: Alex Beregszaszi --- .../test/java/org/ethereum/evmc/TestHostContext.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bindings/java/java/src/test/java/org/ethereum/evmc/TestHostContext.java b/bindings/java/java/src/test/java/org/ethereum/evmc/TestHostContext.java index f708f5cb7..3759bc241 100644 --- a/bindings/java/java/src/test/java/org/ethereum/evmc/TestHostContext.java +++ b/bindings/java/java/src/test/java/org/ethereum/evmc/TestHostContext.java @@ -13,7 +13,7 @@ public boolean accountExists(byte[] address) { @Override public ByteBuffer getStorage(byte[] address, byte[] key) { - return ByteBuffer.allocateDirect(64).put(new byte[64]); + return ByteBuffer.allocateDirect(32).put(new byte[32]); } @Override @@ -23,7 +23,7 @@ public int setStorage(byte[] address, byte[] key, byte[] value) { @Override public ByteBuffer getBalance(byte[] address) { - return ByteBuffer.allocateDirect(64).put(new byte[64]); + return ByteBuffer.allocateDirect(32).put(new byte[32]); } @Override @@ -33,7 +33,7 @@ public int getCodeSize(byte[] address) { @Override public ByteBuffer getCodeHash(byte[] address) { - return ByteBuffer.allocateDirect(64).put(new byte[64]); + return ByteBuffer.allocateDirect(32).put(new byte[32]); } @Override @@ -51,12 +51,12 @@ public ByteBuffer call(ByteBuffer msg) { @Override public ByteBuffer getTxContext() { - return ByteBuffer.allocateDirect(64).put(new byte[64]); + return ByteBuffer.allocateDirect(160).put(new byte[160]); } @Override public ByteBuffer getBlockHash(long number) { - return ByteBuffer.allocateDirect(64).put(new byte[64]); + return ByteBuffer.allocateDirect(32).put(new byte[32]); } @Override