diff --git a/src/node_api.cc b/src/node_api.cc index ec477e1d23c92a..4d996f97a58dde 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -1993,12 +1993,15 @@ napi_status napi_create_string_latin1(napi_env env, napi_value* result) { CHECK_ENV(env); CHECK_ARG(env, result); + RETURN_STATUS_IF_FALSE(env, + (length == NAPI_AUTO_LENGTH) || length <= INT_MAX, + napi_invalid_arg); auto isolate = env->isolate; auto str_maybe = v8::String::NewFromOneByte(isolate, reinterpret_cast(str), - v8::NewStringType::kInternalized, + v8::NewStringType::kNormal, length); CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure); @@ -2012,11 +2015,18 @@ napi_status napi_create_string_utf8(napi_env env, napi_value* result) { CHECK_ENV(env); CHECK_ARG(env, result); + RETURN_STATUS_IF_FALSE(env, + (length == NAPI_AUTO_LENGTH) || length <= INT_MAX, + napi_invalid_arg); - v8::Local s; - CHECK_NEW_FROM_UTF8_LEN(env, s, str, length); - - *result = v8impl::JsValueFromV8LocalValue(s); + auto isolate = env->isolate; + auto str_maybe = + v8::String::NewFromUtf8(isolate, + str, + v8::NewStringType::kNormal, + static_cast(length)); + CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure); + *result = v8impl::JsValueFromV8LocalValue(str_maybe.ToLocalChecked()); return napi_clear_last_error(env); } @@ -2026,12 +2036,15 @@ napi_status napi_create_string_utf16(napi_env env, napi_value* result) { CHECK_ENV(env); CHECK_ARG(env, result); + RETURN_STATUS_IF_FALSE(env, + (length == NAPI_AUTO_LENGTH) || length <= INT_MAX, + napi_invalid_arg); auto isolate = env->isolate; auto str_maybe = v8::String::NewFromTwoByte(isolate, reinterpret_cast(str), - v8::NewStringType::kInternalized, + v8::NewStringType::kNormal, length); CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure); diff --git a/test/addons-napi/test_string/test.js b/test/addons-napi/test_string/test.js index 5ce3d739c7a941..86fdc1640602bc 100644 --- a/test/addons-napi/test_string/test.js +++ b/test/addons-napi/test_string/test.js @@ -73,3 +73,11 @@ assert.strictEqual(test_string.Utf8Length(str6), 14); assert.throws(() => { test_string.TestLargeUtf8(); }, /^Error: Invalid argument$/); + +assert.throws(() => { + test_string.TestLargeLatin1(); +}, /^Error: Invalid argument$/); + +assert.throws(() => { + test_string.TestLargeUtf16(); +}, /^Error: Invalid argument$/); diff --git a/test/addons-napi/test_string/test_string.c b/test/addons-napi/test_string/test_string.c index 99a3f7d3545a20..0f96112970eae1 100644 --- a/test/addons-napi/test_string/test_string.c +++ b/test/addons-napi/test_string/test_string.c @@ -215,6 +215,32 @@ napi_value TestLargeUtf8(napi_env env, napi_callback_info info) { return output; } +static napi_value TestLargeLatin1(napi_env env, napi_callback_info info) { + napi_value output; + if (SIZE_MAX > INT_MAX) { + NAPI_CALL(env, napi_create_string_latin1(env, "", ((size_t)INT_MAX) + 1, &output)); + } else { + // just throw the expected error as there is nothing to test + // in this case since we can't overflow + NAPI_CALL(env, napi_throw_error(env, NULL, "Invalid argument")); + } + + return output; +} + +static napi_value TestLargeUtf16(napi_env env, napi_callback_info info) { + napi_value output; + if (SIZE_MAX > INT_MAX) { + NAPI_CALL(env, napi_create_string_utf16(env, "", ((size_t)INT_MAX) + 1, &output)); + } else { + // just throw the expected error as there is nothing to test + // in this case since we can't overflow + NAPI_CALL(env, napi_throw_error(env, NULL, "Invalid argument")); + } + + return output; +} + napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor properties[] = { DECLARE_NAPI_PROPERTY("TestLatin1", TestLatin1), @@ -226,6 +252,8 @@ napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_PROPERTY("Utf16Length", Utf16Length), DECLARE_NAPI_PROPERTY("Utf8Length", Utf8Length), DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8), + DECLARE_NAPI_PROPERTY("TestLargeLatin1", TestLargeLatin1), + DECLARE_NAPI_PROPERTY("TestLargeUtf16", TestLargeUtf16), }; NAPI_CALL(env, napi_define_properties(