From dda795c500534a42501d5c85422645a0b3bc7162 Mon Sep 17 00:00:00 2001 From: Ariel Gentile Date: Wed, 30 Aug 2023 20:55:02 -0300 Subject: [PATCH 1/3] fix(js): free strings before returning to caller Signed-off-by: Ariel Gentile --- .../anoncreds-nodejs/src/NodeJSAnoncreds.ts | 23 +++++++++++-------- .../anoncreds-nodejs/src/library/bindings.ts | 1 + .../cpp/turboModuleUtility.cpp | 2 ++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts b/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts index bbc99e64..6ec39b52 100644 --- a/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts +++ b/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts @@ -32,12 +32,15 @@ import { } from './ffi' import { getNativeAnoncreds } from './library' -function handleReturnPointer(returnValue: Buffer): Return { +function handleReturnPointer(returnValue: Buffer, cleanupCallback?: (buffer: Buffer) => void): Return { if (returnValue.address() === 0) { throw AnoncredsError.customError({ message: 'Unexpected null pointer' }) } - return returnValue.deref() as Return + const ret = returnValue.deref() as Return + if (cleanupCallback) cleanupCallback(returnValue) + + return ret } export class NodeJSAnoncreds implements Anoncreds { @@ -60,7 +63,7 @@ export class NodeJSAnoncreds implements Anoncreds { this.nativeAnoncreds.anoncreds_generate_nonce(ret) this.handleError() - return handleReturnPointer(ret) + return handleReturnPointer(ret, this.nativeAnoncreds.anoncreds_string_free) } public createSchema(options: { @@ -86,7 +89,7 @@ export class NodeJSAnoncreds implements Anoncreds { this.nativeAnoncreds.anoncreds_revocation_registry_definition_get_attribute(objectHandle, name, ret) this.handleError() - return handleReturnPointer(ret) + return handleReturnPointer(ret, this.nativeAnoncreds.anoncreds_string_free) } public credentialGetAttribute(options: { objectHandle: ObjectHandle; name: string }) { @@ -96,7 +99,7 @@ export class NodeJSAnoncreds implements Anoncreds { this.nativeAnoncreds.anoncreds_credential_get_attribute(objectHandle, name, ret) this.handleError() - return handleReturnPointer(ret) + return handleReturnPointer(ret, this.nativeAnoncreds.anoncreds_string_free) } public createCredentialDefinition(options: { @@ -215,7 +218,7 @@ export class NodeJSAnoncreds implements Anoncreds { this.nativeAnoncreds.anoncreds_encode_credential_attributes(attributeRawValues, ret) this.handleError() - const result = handleReturnPointer(ret) + const result = handleReturnPointer(ret, this.nativeAnoncreds.anoncreds_string_free) return result.split(',') } @@ -296,7 +299,7 @@ export class NodeJSAnoncreds implements Anoncreds { this.nativeAnoncreds.anoncreds_create_link_secret(ret) this.handleError() - return handleReturnPointer(ret) + return handleReturnPointer(ret, this.nativeAnoncreds.anoncreds_string_free) } public createPresentation(options: { @@ -639,7 +642,7 @@ export class NodeJSAnoncreds implements Anoncreds { this.nativeAnoncreds.anoncreds_get_current_error(ret) this.handleError() - return handleReturnPointer(ret) + return handleReturnPointer(ret, this.nativeAnoncreds.anoncreds_string_free) } private objectFromJson(method: (byteBuffer: Buffer, ret: Buffer) => unknown, options: { json: string }) { @@ -723,6 +726,8 @@ export class NodeJSAnoncreds implements Anoncreds { const returnValue = handleReturnPointer<{ data: Buffer; len: number }>(ret) const output = new Uint8Array(byteBufferToBuffer(returnValue)) + this.nativeAnoncreds.anoncreds_buffer_free(returnValue.data) + return new TextDecoder().decode(output) } @@ -734,7 +739,7 @@ export class NodeJSAnoncreds implements Anoncreds { this.nativeAnoncreds.anoncreds_object_get_type_name(objectHandle, ret) this.handleError() - return handleReturnPointer(ret) + return handleReturnPointer(ret, this.nativeAnoncreds.anoncreds_string_free) } public objectFree(options: { objectHandle: ObjectHandle }) { diff --git a/wrappers/javascript/anoncreds-nodejs/src/library/bindings.ts b/wrappers/javascript/anoncreds-nodejs/src/library/bindings.ts index d3aeb46d..02c11192 100644 --- a/wrappers/javascript/anoncreds-nodejs/src/library/bindings.ts +++ b/wrappers/javascript/anoncreds-nodejs/src/library/bindings.ts @@ -120,6 +120,7 @@ export const nativeBindings = { anoncreds_generate_nonce: [FFI_ERRORCODE, [FFI_STRING_PTR]], anoncreds_get_current_error: [FFI_ERRORCODE, [FFI_STRING_PTR]], anoncreds_object_free: [FFI_VOID, [FFI_OBJECT_HANDLE]], + anoncreds_string_free: [FFI_VOID, [FFI_STRING_PTR]], anoncreds_object_get_json: [FFI_ERRORCODE, [FFI_OBJECT_HANDLE, ByteBufferStructPtr]], anoncreds_object_get_type_name: [FFI_ERRORCODE, [FFI_OBJECT_HANDLE, FFI_STRING_PTR]], anoncreds_presentation_request_from_json: [FFI_ERRORCODE, [ByteBufferStruct, FFI_STRING_PTR]], diff --git a/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp b/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp index bcfd32f2..5f3de3aa 100644 --- a/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp +++ b/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp @@ -49,6 +49,8 @@ jsi::Value createReturnValue(jsi::Runtime &rt, ErrorCode code, ? jsi::Value::null() : jsi::String::createFromAscii(rt, *value); object.setProperty(rt, "value", valueWithoutNullptr); + + if (!isNullptr) anoncreds_string_free((char *)*value); } object.setProperty(rt, "errorCode", int(code)); From 720d05d5e5069ebcfd8d67b763fd674ea8d58abc Mon Sep 17 00:00:00 2001 From: Ariel Gentile Date: Thu, 31 Aug 2023 08:57:03 -0300 Subject: [PATCH 2/3] fix: add buffer cleanup Signed-off-by: Ariel Gentile --- .../anoncreds-react-native/cpp/turboModuleUtility.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp b/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp index 5f3de3aa..0e83609e 100644 --- a/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp +++ b/wrappers/javascript/anoncreds-react-native/cpp/turboModuleUtility.cpp @@ -100,6 +100,8 @@ jsi::Value createReturnValue(jsi::Runtime &rt, ErrorCode code, ? jsi::Value::null() : jsi::String::createFromUtf8(rt, value->data, value->len); object.setProperty(rt, "value", valueWithoutNullptr); + + if (value != nullptr) anoncreds_buffer_free(*value); } object.setProperty(rt, "errorCode", int(code)); From 9cd430c5e2a63d6eb6e7dcd27c4bea8d722515f8 Mon Sep 17 00:00:00 2001 From: Ariel Gentile Date: Thu, 31 Aug 2023 09:16:04 -0300 Subject: [PATCH 3/3] fix: buffer free after decoding to string Signed-off-by: Ariel Gentile --- wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts b/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts index 6ec39b52..20e60e75 100644 --- a/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts +++ b/wrappers/javascript/anoncreds-nodejs/src/NodeJSAnoncreds.ts @@ -724,11 +724,13 @@ export class NodeJSAnoncreds implements Anoncreds { this.handleError() const returnValue = handleReturnPointer<{ data: Buffer; len: number }>(ret) - const output = new Uint8Array(byteBufferToBuffer(returnValue)) + const jsonAsArray = new Uint8Array(byteBufferToBuffer(returnValue)) + + const output = new TextDecoder().decode(jsonAsArray) this.nativeAnoncreds.anoncreds_buffer_free(returnValue.data) - return new TextDecoder().decode(output) + return output } public getTypeName(options: { objectHandle: ObjectHandle }) {