Fix double free for CFFI pointers

This commit is contained in:
Joshua Granick
2018-06-15 23:55:08 -07:00
parent a3b998a18c
commit b8cdea3284
4 changed files with 78 additions and 22 deletions

View File

@@ -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_set_frame_rate (handle:Dynamic, value:Float):Void;
@:cffi private static function lime_application_update (handle:Dynamic):Bool; @: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_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 (data:Dynamic):Float;
@:cffi private static function lime_bytes_get_data_pointer_offset (data:Dynamic, offset:Int):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; @: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_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; } @: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_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") 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_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; } @:hlNative("lime", "lime_bytes_read_file") private static function lime_bytes_read_file (path:String, bytes:Bytes):Bytes { return null; }

View File

@@ -105,8 +105,8 @@ abstract Bytes(HaxeBytes) from HaxeBytes to HaxeBytes {
#if (lime_cffi && !macro) #if (lime_cffi && !macro)
public static function __fromNativePointer (data:Dynamic, length:Int):Bytes { public static function __fromNativePointer (data:Dynamic, length:Int):Bytes {
var bytes:Dynamic = NativeCFFI.lime_bytes_from_data_pointer (data, length); var bytes = Bytes.alloc (0);
return new Bytes (bytes.length, bytes.b); return NativeCFFI.lime_bytes_from_data_pointer (data, length, bytes);
} }
#end #end

View File

@@ -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; uintptr_t ptr = (uintptr_t)data;
// Bytes bytes (length); 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 bytes.Value (_bytes);
return alloc_null ();
}
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); TextLayout *text = (TextLayout*)val_data (textHandle);
Font *font = (Font*)val_data (fontHandle); Font *font = (Font*)val_data (fontHandle);
Bytes bytes (data); Bytes bytes (data);
text->Position (font, size, textString.c_str (), &bytes); text->Position (font, size, textString.c_str (), &bytes);
return bytes.Value (data); return bytes.Value (data);
#endif #endif
@@ -3930,7 +3948,7 @@ namespace lime {
DEFINE_PRIME2v (lime_application_set_frame_rate); DEFINE_PRIME2v (lime_application_set_frame_rate);
DEFINE_PRIME1 (lime_application_update); DEFINE_PRIME1 (lime_application_update);
DEFINE_PRIME2 (lime_audio_load); 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_PRIME1 (lime_bytes_get_data_pointer);
DEFINE_PRIME2 (lime_bytes_get_data_pointer_offset); DEFINE_PRIME2 (lime_bytes_get_data_pointer_offset);
DEFINE_PRIME2 (lime_bytes_read_file); DEFINE_PRIME2 (lime_bytes_read_file);
@@ -4119,7 +4137,7 @@ namespace lime {
DEFINE_HL_PRIM (_BOOL, lime_application_update, _TCFFIPOINTER); 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_bytes, _TBYTES _TAUDIOBUFFER);
DEFINE_HL_PRIM (_TAUDIOBUFFER, lime_audio_load_file, _STRING _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, _TBYTES);
DEFINE_HL_PRIM (_F64, lime_bytes_get_data_pointer_offset, _TBYTES _I32); DEFINE_HL_PRIM (_F64, lime_bytes_get_data_pointer_offset, _TBYTES _I32);
DEFINE_HL_PRIM (_TBYTES, lime_bytes_read_file, _STRING _TBYTES); DEFINE_HL_PRIM (_TBYTES, lime_bytes_read_file, _STRING _TBYTES);

View File

@@ -1,5 +1,6 @@
#include <system/System.h> #include <system/System.h>
#include <utils/Bytes.h> #include <utils/Bytes.h>
#include <map>
namespace lime { namespace lime {
@@ -9,6 +10,7 @@ namespace lime {
static int id_length; static int id_length;
static bool init = false; static bool init = false;
static bool useBuffer = false; static bool useBuffer = false;
static std::map<Bytes*, bool> usingValue;
inline void _initializeBytes () { inline void _initializeBytes () {
@@ -57,7 +59,11 @@ namespace lime {
Bytes::~Bytes () { Bytes::~Bytes () {
if (usingValue.find (this) != usingValue.end ()) {
usingValue.erase (this);
}
} }
@@ -96,7 +102,16 @@ namespace lime {
if (b) { if (b) {
free (b); if (usingValue.find (this) != usingValue.end ()) {
usingValue.erase (this);
} else {
free (b);
}
b = 0; b = 0;
length = 0; length = 0;
@@ -106,14 +121,23 @@ namespace lime {
unsigned char* data = (unsigned char*)malloc (sizeof (char) * size); unsigned char* data = (unsigned char*)malloc (sizeof (char) * size);
if (b && length) { if (b) {
memcpy (data, b, length < size ? length : size); if (length) {
free (b);
memcpy (data, b, length < size ? length : size);
}
} else if (b) { if (usingValue.find (this) != usingValue.end ()) {
free (b); usingValue.erase (this);
} else {
free (b);
}
} }
@@ -131,11 +155,19 @@ namespace lime {
if (val_is_null (bytes)) { if (val_is_null (bytes)) {
if (usingValue.find (this) != usingValue.end ()) {
usingValue.erase (this);
}
length = 0; length = 0;
b = 0; b = 0;
} else { } else {
usingValue[this] = true;
length = val_int (val_field (bytes, id_length)); length = val_int (val_field (bytes, id_length));
if (length > 0) { if (length > 0) {
@@ -174,6 +206,12 @@ namespace lime {
} else { } else {
if (usingValue.find (this) != usingValue.end ()) {
usingValue.erase (this);
}
b = 0; b = 0;
length = 0; length = 0;