n-api: add check for large strings

n-api uses size_t for the size of strings when specifying
string lengths.  V8 only supports a size of int.  Add
a check so that an error will be returned if the user
passes in a string with a size larger than will fit into
an int.

PR-URL: https://github.com/nodejs/node/pull/15611
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
This commit is contained in:
Michael Dawson 2017-09-25 11:37:18 -04:00
parent 98077446f9
commit cec6e21668
3 changed files with 24 additions and 1 deletions

View File

@ -10,6 +10,7 @@
#include <node_buffer.h> #include <node_buffer.h>
#include <node_object_wrap.h> #include <node_object_wrap.h>
#include <limits.h> // INT_MAX
#include <string.h> #include <string.h>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
@ -125,6 +126,9 @@ struct napi_env__ {
do { \ do { \
static_assert(static_cast<int>(NAPI_AUTO_LENGTH) == -1, \ static_assert(static_cast<int>(NAPI_AUTO_LENGTH) == -1, \
"Casting NAPI_AUTO_LENGTH to int must result in -1"); \ "Casting NAPI_AUTO_LENGTH to int must result in -1"); \
RETURN_STATUS_IF_FALSE((env), \
(len == NAPI_AUTO_LENGTH) || len <= INT_MAX, \
napi_invalid_arg); \
auto str_maybe = v8::String::NewFromUtf8( \ auto str_maybe = v8::String::NewFromUtf8( \
(env)->isolate, (str), v8::NewStringType::kInternalized, \ (env)->isolate, (str), v8::NewStringType::kInternalized, \
static_cast<int>(len)); \ static_cast<int>(len)); \
@ -866,7 +870,7 @@ void napi_module_register(napi_module* mod) {
// Warning: Keep in-sync with napi_status enum // Warning: Keep in-sync with napi_status enum
const char* error_messages[] = {nullptr, const char* error_messages[] = {nullptr,
"Invalid pointer passed as argument", "Invalid argument",
"An object was expected", "An object was expected",
"A string was expected", "A string was expected",
"A string or symbol was expected", "A string or symbol was expected",

View File

@ -69,3 +69,7 @@ assert.strictEqual(test_string.TestUtf8Insufficient(str6), str6.slice(0, 1));
assert.strictEqual(test_string.TestUtf16Insufficient(str6), str6.slice(0, 3)); assert.strictEqual(test_string.TestUtf16Insufficient(str6), str6.slice(0, 3));
assert.strictEqual(test_string.Utf16Length(str6), 5); assert.strictEqual(test_string.Utf16Length(str6), 5);
assert.strictEqual(test_string.Utf8Length(str6), 14); assert.strictEqual(test_string.Utf8Length(str6), 14);
assert.throws(() => {
test_string.TestLargeUtf8();
}, /^Error: Invalid argument$/);

View File

@ -1,3 +1,4 @@
#include <limits.h> // INT_MAX
#include <node_api.h> #include <node_api.h>
#include "../common.h" #include "../common.h"
@ -201,6 +202,19 @@ napi_value Utf8Length(napi_env env, napi_callback_info info) {
return output; return output;
} }
napi_value TestLargeUtf8(napi_env env, napi_callback_info info) {
napi_value output;
if (SIZE_MAX > INT_MAX) {
NAPI_CALL(env, napi_create_string_utf8(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_value Init(napi_env env, napi_value exports) {
napi_property_descriptor properties[] = { napi_property_descriptor properties[] = {
DECLARE_NAPI_PROPERTY("TestLatin1", TestLatin1), DECLARE_NAPI_PROPERTY("TestLatin1", TestLatin1),
@ -211,6 +225,7 @@ napi_value Init(napi_env env, napi_value exports) {
DECLARE_NAPI_PROPERTY("TestUtf16Insufficient", TestUtf16Insufficient), DECLARE_NAPI_PROPERTY("TestUtf16Insufficient", TestUtf16Insufficient),
DECLARE_NAPI_PROPERTY("Utf16Length", Utf16Length), DECLARE_NAPI_PROPERTY("Utf16Length", Utf16Length),
DECLARE_NAPI_PROPERTY("Utf8Length", Utf8Length), DECLARE_NAPI_PROPERTY("Utf8Length", Utf8Length),
DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8),
}; };
NAPI_CALL(env, napi_define_properties( NAPI_CALL(env, napi_define_properties(