Skip to content

Commit

Permalink
Add support for passing an array of data to send()
Browse files Browse the repository at this point in the history
Fixes #48.
  • Loading branch information
oleavr committed May 16, 2015
1 parent d623c49 commit 91dbf6a
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 19 deletions.
76 changes: 67 additions & 9 deletions bindings/gumjs/gumscriptcore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <ffi.h>
#include <string.h>

#define GUM_MAX_SEND_ARRAY_LENGTH (1024 * 1024)

#define GUM_SCRIPT_CORE_LOCK() (g_mutex_lock (&self->mutex))
#define GUM_SCRIPT_CORE_UNLOCK() (g_mutex_unlock (&self->mutex))

Expand Down Expand Up @@ -468,6 +470,12 @@ _gum_script_core_realize (GumScriptCore * self)
g_assert (success);
self->cpu_context_value = new GumPersistent<Object>::type (isolate,
cpu_context_value);

self->length_key = new GumPersistent<String>::type (isolate,
String::NewFromOneByte (isolate,
reinterpret_cast<const uint8_t *> ("length"),
NewStringType::kNormal,
-1).ToLocalChecked ());
}

void
Expand Down Expand Up @@ -496,6 +504,9 @@ _gum_script_core_flush (GumScriptCore * self)
void
_gum_script_core_dispose (GumScriptCore * self)
{
delete self->length_key;
self->length_key = nullptr;

g_hash_table_unref (self->heap_blocks);
self->heap_blocks = NULL;

Expand Down Expand Up @@ -944,20 +955,65 @@ gum_script_core_on_send (const FunctionCallbackInfo<Value> & info)

String::Utf8Value message (info[0]);

guint8 * malloc_data = NULL;
const guint8 * data = NULL;
gint data_length = 0;
if (!info[1]->IsNull ())
Local<Value> data_value = info[1];
if (!data_value->IsUndefined () && !data_value->IsNull ())
{
Local<Object> array = info[1]->ToObject ();
if (array->HasIndexedPropertiesInExternalArrayData () &&
array->GetIndexedPropertiesExternalArrayDataType ()
== kExternalUint8Array)
if (data_value->IsObject ())
{
data = static_cast<guint8 *> (
array->GetIndexedPropertiesExternalArrayData ());
data_length = array->GetIndexedPropertiesExternalArrayDataLength ();
Local<Object> array = Local<Object>::Cast (data_value);
if (array->HasIndexedPropertiesInExternalArrayData () &&
array->GetIndexedPropertiesExternalArrayDataType ()
== kExternalUint8Array)
{
data = static_cast<guint8 *> (
array->GetIndexedPropertiesExternalArrayData ());
data_length = array->GetIndexedPropertiesExternalArrayDataLength ();
}
else
{
Local<String> length_key (Local<String>::New (isolate,
*self->length_key));
if (array->Has (length_key))
{
data_length = array->Get (length_key)->Uint32Value ();
if (data_length <= GUM_MAX_SEND_ARRAY_LENGTH)
{
Local<Context> context = isolate->GetCurrentContext ();

malloc_data = static_cast<guint8 *> (g_malloc (data_length));
for (gint i = 0; i != data_length; i++)
{
gboolean valid = FALSE;

Local<Value> element_value;
if (array->Get (context, i).ToLocal (&element_value))
{
Maybe<uint32_t> element = element_value->Uint32Value (context);
if (element.IsJust ())
{
malloc_data[i] = element.FromJust ();
valid = TRUE;
}
}

if (!valid)
{
g_free (malloc_data);
malloc_data = NULL;
break;
}
}

data = malloc_data;
}
}
}
}
else

if (data == NULL)
{
isolate->ThrowException (Exception::TypeError (String::NewFromUtf8 (
isolate, "unsupported data value")));
Expand All @@ -966,6 +1022,8 @@ gum_script_core_on_send (const FunctionCallbackInfo<Value> & info)
}

_gum_script_core_emit_message (self, *message, data, data_length);

g_free (malloc_data);
}

/*
Expand Down
2 changes: 2 additions & 0 deletions bindings/gumjs/gumscriptcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ struct _GumScriptCore

GumPersistent<v8::FunctionTemplate>::type * cpu_context;
GumPersistent<v8::Object>::type * cpu_context_value;

GumPersistent<v8::String>::type * length_key;
};

struct _GumHeapBlock
Expand Down
12 changes: 3 additions & 9 deletions bindings/gumjs/gumscriptmemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,6 @@ _gum_script_memory_realize (GumScriptMemory * self)
reinterpret_cast<const uint8_t *> ("base"),
NewStringType::kNormal,
-1).ToLocalChecked ());
self->length_key = new GumPersistent<String>::type (isolate,
String::NewFromOneByte (isolate,
reinterpret_cast<const uint8_t *> ("length"),
NewStringType::kNormal,
-1).ToLocalChecked ());
self->size_key = new GumPersistent<String>::type (isolate,
String::NewFromOneByte (isolate,
reinterpret_cast<const uint8_t *> ("size"),
Expand All @@ -288,10 +283,8 @@ void
_gum_script_memory_dispose (GumScriptMemory * self)
{
delete self->size_key;
delete self->length_key;
delete self->base_key;
self->size_key = nullptr;
self->length_key = nullptr;
self->base_key = nullptr;
}

Expand Down Expand Up @@ -899,7 +892,7 @@ gum_script_memory_do_write (const FunctionCallbackInfo<Value> & info,
else
{
Local<String> length_key (Local<String>::New (isolate,
*self->length_key));
*self->core->length_key));
if (array->Has (length_key))
{
uint32_t length = array->Get (length_key)->Uint32Value ();
Expand Down Expand Up @@ -1428,7 +1421,8 @@ gum_script_memory_ranges_get (GumScriptMemory * self,
}

Local<Object> obj = Handle<Object>::Cast (value);
Local<String> length_key (Local<String>::New (isolate, *self->length_key));
Local<String> length_key (Local<String>::New (isolate,
*self->core->length_key));
if (obj->Has (length_key))
{
uint32_t length =
Expand Down
1 change: 0 additions & 1 deletion bindings/gumjs/gumscriptmemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ struct _GumScriptMemory
GumScriptCore * core;

GumPersistent<v8::String>::type * base_key;
GumPersistent<v8::String>::type * length_key;
GumPersistent<v8::String>::type * size_key;

GumMemoryAccessMonitor * monitor;
Expand Down
7 changes: 7 additions & 0 deletions tests/gumjs/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ TEST_LIST_BEGIN (script)
SCRIPT_TESTENTRY (invalid_script_should_return_null)
SCRIPT_TESTENTRY (array_buffer_can_be_created)
SCRIPT_TESTENTRY (message_can_be_sent)
SCRIPT_TESTENTRY (message_can_be_sent_with_data)
SCRIPT_TESTENTRY (message_can_be_received)
SCRIPT_TESTENTRY (recv_may_specify_desired_message_type)
SCRIPT_TESTENTRY (recv_can_be_waited_for)
Expand Down Expand Up @@ -876,6 +877,12 @@ SCRIPT_TESTCASE (message_can_be_sent)
EXPECT_SEND_MESSAGE_WITH ("1234");
}

SCRIPT_TESTCASE (message_can_be_sent_with_data)
{
COMPILE_AND_LOAD_SCRIPT ("send(1234, [0x13, 0x37]);");
EXPECT_SEND_MESSAGE_WITH_PAYLOAD_AND_DATA ("1234", "13 37");
}

SCRIPT_TESTCASE (message_can_be_received)
{
COMPILE_AND_LOAD_SCRIPT (
Expand Down

0 comments on commit 91dbf6a

Please sign in to comment.