diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index a09969b9adf28f..31b394ed570a34 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -2177,7 +2177,7 @@ napi_status napi_get_value_string_latin1(napi_env env, if (!buf) { CHECK_ARG(env, result); *result = val.As()->Length(); - } else { + } else if (bufsize != 0) { int copied = val.As()->WriteOneByte(env->isolate, reinterpret_cast(buf), @@ -2189,6 +2189,8 @@ napi_status napi_get_value_string_latin1(napi_env env, if (result != nullptr) { *result = copied; } + } else if (result != nullptr) { + *result = 0; } return napi_clear_last_error(env); @@ -2216,7 +2218,7 @@ napi_status napi_get_value_string_utf8(napi_env env, if (!buf) { CHECK_ARG(env, result); *result = val.As()->Utf8Length(env->isolate); - } else { + } else if (bufsize != 0) { int copied = val.As()->WriteUtf8( env->isolate, buf, @@ -2228,6 +2230,8 @@ napi_status napi_get_value_string_utf8(napi_env env, if (result != nullptr) { *result = copied; } + } else if (result != nullptr) { + *result = 0; } return napi_clear_last_error(env); @@ -2256,7 +2260,7 @@ napi_status napi_get_value_string_utf16(napi_env env, CHECK_ARG(env, result); // V8 assumes UTF-16 length is the same as the number of characters. *result = val.As()->Length(); - } else { + } else if (bufsize != 0) { int copied = val.As()->Write(env->isolate, reinterpret_cast(buf), 0, @@ -2267,6 +2271,8 @@ napi_status napi_get_value_string_utf16(napi_env env, if (result != nullptr) { *result = copied; } + } else if (result != nullptr) { + *result = 0; } return napi_clear_last_error(env); diff --git a/test/js-native-api/test_string/test.js b/test/js-native-api/test_string/test.js index 1be34212a11c3f..b03cd0b3612044 100644 --- a/test/js-native-api/test_string/test.js +++ b/test/js-native-api/test_string/test.js @@ -81,3 +81,5 @@ assert.throws(() => { assert.throws(() => { test_string.TestLargeUtf16(); }, /^Error: Invalid argument$/); + +test_string.TestMemoryCorruption(' '.repeat(64 * 1024)); diff --git a/test/js-native-api/test_string/test_string.c b/test/js-native-api/test_string/test_string.c index 471678c251677a..e840feeacf2110 100644 --- a/test/js-native-api/test_string/test_string.c +++ b/test/js-native-api/test_string/test_string.c @@ -1,4 +1,5 @@ #include // INT_MAX +#include #include #include "../common.h" @@ -244,6 +245,24 @@ static napi_value TestLargeUtf16(napi_env env, napi_callback_info info) { return output; } +static napi_value TestMemoryCorruption(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1]; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + NAPI_ASSERT(env, argc == 1, "Wrong number of arguments"); + + char buf[10] = { 0 }; + NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], buf, 0, NULL)); + + char zero[10] = { 0 }; + if (memcmp(buf, zero, sizeof(buf)) != 0) { + NAPI_CALL(env, napi_throw_error(env, NULL, "Buffer overwritten")); + } + + return NULL; +} + EXTERN_C_START napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor properties[] = { @@ -258,6 +277,7 @@ napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8), DECLARE_NAPI_PROPERTY("TestLargeLatin1", TestLargeLatin1), DECLARE_NAPI_PROPERTY("TestLargeUtf16", TestLargeUtf16), + DECLARE_NAPI_PROPERTY("TestMemoryCorruption", TestMemoryCorruption), }; NAPI_CALL(env, napi_define_properties(