From b8cdea32840662318617f3665ce5a9e48bf1c318 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Fri, 15 Jun 2018 23:55:08 -0700 Subject: [PATCH] Fix double free for CFFI pointers --- lime/_backend/native/NativeCFFI.hx | 4 +-- lime/utils/Bytes.hx | 4 +-- project/src/ExternalInterface.cpp | 38 +++++++++++++++------ project/src/utils/Bytes.cpp | 54 +++++++++++++++++++++++++----- 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/lime/_backend/native/NativeCFFI.hx b/lime/_backend/native/NativeCFFI.hx index d4baaeb26..0c9c9664d 100644 --- a/lime/_backend/native/NativeCFFI.hx +++ b/lime/_backend/native/NativeCFFI.hx @@ -58,7 +58,7 @@ class NativeCFFI { @:cffi private static function lime_application_set_frame_rate (handle:Dynamic, value:Float):Void; @:cffi private static function lime_application_update (handle:Dynamic):Bool; @:cffi private static function lime_audio_load (data:Dynamic, buffer:Dynamic):Dynamic; - @:cffi private static function lime_bytes_from_data_pointer (data:Float, length:Int):Dynamic; + @:cffi private static function lime_bytes_from_data_pointer (data:Float, length:Int, bytes:Dynamic):Dynamic; @:cffi private static function lime_bytes_get_data_pointer (data:Dynamic):Float; @:cffi private static function lime_bytes_get_data_pointer_offset (data:Dynamic, offset:Int):Float; @:cffi private static function lime_bytes_read_file (path:String, bytes:Dynamic):Dynamic; @@ -212,7 +212,7 @@ class NativeCFFI { @:hlNative("lime", "lime_application_set_frame_rate") private static function lime_application_set_frame_rate (handle:CFFIPointer, value:Float):Void {} @:hlNative("lime", "lime_application_update") private static function lime_application_update (handle:CFFIPointer):Bool { return false; } @:cffi private static function lime_audio_load (data:Dynamic, buffer:Dynamic):Dynamic; - @:cffi private static function lime_bytes_from_data_pointer (data:Float, length:Int):Dynamic; + @:hlNative("lime", "lime_bytes_from_data_pointer") private static function lime_bytes_from_data_pointer (data:Float, length:Int, bytes:Bytes):Bytes { return null; } @:hlNative("lime", "lime_bytes_get_data_pointer") private static function lime_bytes_get_data_pointer (data:Bytes):Float { return 0; } @:hlNative("lime", "lime_bytes_get_data_pointer_offset") private static function lime_bytes_get_data_pointer_offset (data:Bytes, offset:Int):Float { return 0; } @:hlNative("lime", "lime_bytes_read_file") private static function lime_bytes_read_file (path:String, bytes:Bytes):Bytes { return null; } diff --git a/lime/utils/Bytes.hx b/lime/utils/Bytes.hx index 5b77f7a1f..de1eea8da 100644 --- a/lime/utils/Bytes.hx +++ b/lime/utils/Bytes.hx @@ -105,8 +105,8 @@ abstract Bytes(HaxeBytes) from HaxeBytes to HaxeBytes { #if (lime_cffi && !macro) public static function __fromNativePointer (data:Dynamic, length:Int):Bytes { - var bytes:Dynamic = NativeCFFI.lime_bytes_from_data_pointer (data, length); - return new Bytes (bytes.length, bytes.b); + var bytes = Bytes.alloc (0); + return NativeCFFI.lime_bytes_from_data_pointer (data, length, bytes); } #end diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 39e6f64bf..a6c0da4c0 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -411,19 +411,35 @@ namespace lime { } - value lime_bytes_from_data_pointer (double data, int length) { + value lime_bytes_from_data_pointer (double data, int length, value _bytes) { - // uintptr_t ptr = (uintptr_t)data; - // Bytes bytes (length); + uintptr_t ptr = (uintptr_t)data; + Bytes bytes (_bytes); + bytes.Resize (length); - // if (ptr) { + if (ptr) { - // memcpy (bytes.b, (const void*)ptr, length); + memcpy (bytes.b, (const void*)ptr, length); - // } + } - // return bytes.Value (); - return alloc_null (); + return bytes.Value (_bytes); + + } + + + HL_PRIM Bytes* hl_lime_bytes_from_data_pointer (double data, int length, Bytes* bytes) { + + uintptr_t ptr = (uintptr_t)data; + bytes->Resize (length); + + if (ptr) { + + memcpy (bytes->b, (const void*)ptr, length); + + } + + return bytes; } @@ -3331,7 +3347,9 @@ namespace lime { TextLayout *text = (TextLayout*)val_data (textHandle); Font *font = (Font*)val_data (fontHandle); Bytes bytes (data); + text->Position (font, size, textString.c_str (), &bytes); + return bytes.Value (data); #endif @@ -3930,7 +3948,7 @@ namespace lime { DEFINE_PRIME2v (lime_application_set_frame_rate); DEFINE_PRIME1 (lime_application_update); DEFINE_PRIME2 (lime_audio_load); - DEFINE_PRIME2 (lime_bytes_from_data_pointer); + DEFINE_PRIME3 (lime_bytes_from_data_pointer); DEFINE_PRIME1 (lime_bytes_get_data_pointer); DEFINE_PRIME2 (lime_bytes_get_data_pointer_offset); DEFINE_PRIME2 (lime_bytes_read_file); @@ -4119,7 +4137,7 @@ namespace lime { DEFINE_HL_PRIM (_BOOL, lime_application_update, _TCFFIPOINTER); DEFINE_HL_PRIM (_TAUDIOBUFFER, lime_audio_load_bytes, _TBYTES _TAUDIOBUFFER); DEFINE_HL_PRIM (_TAUDIOBUFFER, lime_audio_load_file, _STRING _TAUDIOBUFFER); - // DEFINE_PRIME2 (lime_bytes_from_data_pointer); + DEFINE_HL_PRIM (_TBYTES, lime_bytes_from_data_pointer, _F64 _I32 _TBYTES); DEFINE_HL_PRIM (_F64, lime_bytes_get_data_pointer, _TBYTES); DEFINE_HL_PRIM (_F64, lime_bytes_get_data_pointer_offset, _TBYTES _I32); DEFINE_HL_PRIM (_TBYTES, lime_bytes_read_file, _STRING _TBYTES); diff --git a/project/src/utils/Bytes.cpp b/project/src/utils/Bytes.cpp index 8eb4ec848..310a6141f 100644 --- a/project/src/utils/Bytes.cpp +++ b/project/src/utils/Bytes.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace lime { @@ -9,6 +10,7 @@ namespace lime { static int id_length; static bool init = false; static bool useBuffer = false; + static std::map usingValue; inline void _initializeBytes () { @@ -57,7 +59,11 @@ namespace lime { Bytes::~Bytes () { - + if (usingValue.find (this) != usingValue.end ()) { + + usingValue.erase (this); + + } } @@ -96,7 +102,16 @@ namespace lime { if (b) { - free (b); + if (usingValue.find (this) != usingValue.end ()) { + + usingValue.erase (this); + + } else { + + free (b); + + } + b = 0; length = 0; @@ -106,14 +121,23 @@ namespace lime { unsigned char* data = (unsigned char*)malloc (sizeof (char) * size); - if (b && length) { + if (b) { - memcpy (data, b, length < size ? length : size); - free (b); + if (length) { + + memcpy (data, b, length < size ? length : size); + + } - } else if (b) { - - free (b); + if (usingValue.find (this) != usingValue.end ()) { + + usingValue.erase (this); + + } else { + + free (b); + + } } @@ -131,11 +155,19 @@ namespace lime { if (val_is_null (bytes)) { + if (usingValue.find (this) != usingValue.end ()) { + + usingValue.erase (this); + + } + length = 0; b = 0; } else { + usingValue[this] = true; + length = val_int (val_field (bytes, id_length)); if (length > 0) { @@ -174,6 +206,12 @@ namespace lime { } else { + if (usingValue.find (this) != usingValue.end ()) { + + usingValue.erase (this); + + } + b = 0; length = 0;