From 74e85a5c7bf7b2b4c9098481f6c6a042e3d8826d Mon Sep 17 00:00:00 2001 From: Tyler Church Date: Wed, 23 Mar 2016 19:32:05 -0700 Subject: [PATCH 1/2] Switch from strdup to memcpy to faithfully copy all bytes and prevent a crash in some cases. --- generate/templates/partials/convert_from_v8.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/generate/templates/partials/convert_from_v8.cc b/generate/templates/partials/convert_from_v8.cc index 659e2fb0e..7dbdd1eb1 100644 --- a/generate/templates/partials/convert_from_v8.cc +++ b/generate/templates/partials/convert_from_v8.cc @@ -14,7 +14,9 @@ {%if cppClassName == 'String'%} String::Utf8Value {{ name }}(info[{{ jsArg }}]->ToString()); - from_{{ name }} = ({{ cType }}) strdup(*{{ name }}); + from_{{ name }} = ({{ cType }}) malloc({{ name }}.length() + 1); + memcpy((void *)from_{{ name }}, *{{ name }}, {{ name }}.length()); + memset((void *)(((char *)from_{{ name }}) + {{ name }}.length()), 0, 1); {%elsif cppClassName == 'GitStrarray' %} from_{{ name }} = StrArrayConverter::Convert(info[{{ jsArg }}]); @@ -24,7 +26,9 @@ {%elsif cppClassName == 'Wrapper'%} String::Utf8Value {{ name }}(info[{{ jsArg }}]->ToString()); - from_{{ name }} = ({{ cType }}) strdup(*{{ name }}); + from_{{ name }} = ({{ cType }}) malloc({{ name }}.length() + 1); + memcpy((void *)from_{{ name }}, *{{ name }}, {{ name }}.length()); + memset((void *)(((char *)from_{{ name }}) + {{ name }}.length()), 0, 1); {%elsif cppClassName == 'Array'%} Array *tmp_{{ name }} = Array::Cast(*info[{{ jsArg }}]); From c866391086889e5b4cdfdec745ecf808ea1b64e6 Mon Sep 17 00:00:00 2001 From: Tyler Church Date: Thu, 24 Mar 2016 07:00:35 -0700 Subject: [PATCH 2/2] Add some comments explaining the switch between strdup and malloc/memcpy/memset. --- generate/templates/partials/convert_from_v8.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/generate/templates/partials/convert_from_v8.cc b/generate/templates/partials/convert_from_v8.cc index 7dbdd1eb1..425e691f4 100644 --- a/generate/templates/partials/convert_from_v8.cc +++ b/generate/templates/partials/convert_from_v8.cc @@ -14,8 +14,13 @@ {%if cppClassName == 'String'%} String::Utf8Value {{ name }}(info[{{ jsArg }}]->ToString()); + // malloc with one extra byte so we can add the terminating null character C-strings expect: from_{{ name }} = ({{ cType }}) malloc({{ name }}.length() + 1); + // copy the characters from the nodejs string into our C-string (used instead of strdup or strcpy because nulls in + // the middle of strings are valid coming from nodejs): memcpy((void *)from_{{ name }}, *{{ name }}, {{ name }}.length()); + // ensure the final byte of our new string is null, extra casts added to ensure compatibility with various C types + // used in the nodejs binding generation: memset((void *)(((char *)from_{{ name }}) + {{ name }}.length()), 0, 1); {%elsif cppClassName == 'GitStrarray' %} @@ -26,8 +31,13 @@ {%elsif cppClassName == 'Wrapper'%} String::Utf8Value {{ name }}(info[{{ jsArg }}]->ToString()); + // malloc with one extra byte so we can add the terminating null character C-strings expect: from_{{ name }} = ({{ cType }}) malloc({{ name }}.length() + 1); + // copy the characters from the nodejs string into our C-string (used instead of strdup or strcpy because nulls in + // the middle of strings are valid coming from nodejs): memcpy((void *)from_{{ name }}, *{{ name }}, {{ name }}.length()); + // ensure the final byte of our new string is null, extra casts added to ensure compatibility with various C types + // used in the nodejs binding generation: memset((void *)(((char *)from_{{ name }}) + {{ name }}.length()), 0, 1); {%elsif cppClassName == 'Array'%}