Skip to content

Commit

Permalink
n-api: add check for large strings
Browse files Browse the repository at this point in the history
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.

Backport-PR-URL: #19447
PR-URL: #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>
  • Loading branch information
mhdawson authored and MylesBorins committed Apr 16, 2018
1 parent e9a6dff commit 00d094f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/node_api.cc
Expand Up @@ -10,7 +10,7 @@

#include <node_buffer.h>
#include <node_object_wrap.h>

#include <limits.h> // INT_MAX
#include <string.h>
#include <algorithm>
#include <cmath>
Expand Down Expand Up @@ -129,6 +129,9 @@ struct napi_env__ {
do { \
static_assert(static_cast<int>(NAPI_AUTO_LENGTH) == -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( \
(env)->isolate, (str), v8::NewStringType::kInternalized, \
static_cast<int>(len)); \
Expand Down Expand Up @@ -871,7 +874,7 @@ void napi_module_register(napi_module* mod) {

// Warning: Keep in-sync with napi_status enum
const char* error_messages[] = {nullptr,
"Invalid pointer passed as argument",
"Invalid argument",
"An object was expected",
"A string was expected",
"A string or symbol was expected",
Expand Down
4 changes: 4 additions & 0 deletions test/addons-napi/test_string/test.js
Expand Up @@ -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.Utf16Length(str6), 5);
assert.strictEqual(test_string.Utf8Length(str6), 14);

assert.throws(() => {
test_string.TestLargeUtf8();
}, /^Error: Invalid argument$/);
15 changes: 15 additions & 0 deletions test/addons-napi/test_string/test_string.c
@@ -1,3 +1,4 @@
#include <limits.h> // INT_MAX
#include <node_api.h>
#include "../common.h"

Expand Down Expand Up @@ -201,6 +202,19 @@ napi_value Utf8Length(napi_env env, napi_callback_info info) {
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_property_descriptor properties[] = {
DECLARE_NAPI_PROPERTY("TestLatin1", TestLatin1),
Expand All @@ -211,6 +225,7 @@ napi_value Init(napi_env env, napi_value exports) {
DECLARE_NAPI_PROPERTY("TestUtf16Insufficient", TestUtf16Insufficient),
DECLARE_NAPI_PROPERTY("Utf16Length", Utf16Length),
DECLARE_NAPI_PROPERTY("Utf8Length", Utf8Length),
DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8),
};

NAPI_CALL(env, napi_define_properties(
Expand Down

0 comments on commit 00d094f

Please sign in to comment.