Skip to content

Commit f31b50c

Browse files
Sampson GaoMylesBorins
Sampson Gao
authored andcommittedApr 16, 2018
n-api: add optional string length parameters
Backport-PR-URL: #19447 PR-URL: #15343 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
1 parent fe87a59 commit f31b50c

File tree

20 files changed

+141
-30
lines changed

20 files changed

+141
-30
lines changed
 

‎doc/api/n-api.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -552,11 +552,18 @@ thrown to immediately terminate the process.
552552
added: REPLACEME
553553
-->
554554
```C
555-
NAPI_NO_RETURN void napi_fatal_error(const char* location, const char* message);
555+
NAPI_NO_RETURN void napi_fatal_error(const char* location,
556+
size_t location_len,
557+
const char* message,
558+
size_t message_len);
556559
```
557560

558561
- `[in] location`: Optional location at which the error occurred.
562+
- `[in] location_len`: The length of the location in bytes, or -1 if it is
563+
null-terminated.
559564
- `[in] message`: The message associated with the error.
565+
- `[in] message_len`: The length of the message in bytes, or -1 if it is
566+
null-terminated.
560567

561568
The function call does not return, the process will be terminated.
562569

@@ -1248,6 +1255,7 @@ added: v8.0.0
12481255
```C
12491256
napi_status napi_create_function(napi_env env,
12501257
const char* utf8name,
1258+
size_t length,
12511259
napi_callback cb,
12521260
void* data,
12531261
napi_value* result)
@@ -1256,6 +1264,8 @@ napi_status napi_create_function(napi_env env,
12561264
- `[in] env`: The environment that the API is invoked under.
12571265
- `[in] utf8name`: A string representing the name of the function encoded as
12581266
UTF8.
1267+
- `[in] length`: The length of the utf8name in bytes, or -1 if it is
1268+
null-terminated.
12591269
- `[in] cb`: A function pointer to the native function to be invoked when the
12601270
created function is invoked from JavaScript.
12611271
- `[in] data`: Optional arbitrary context data to be passed into the native
@@ -3026,6 +3036,7 @@ added: v8.0.0
30263036
```C
30273037
napi_status napi_define_class(napi_env env,
30283038
const char* utf8name,
3039+
size_t length,
30293040
napi_callback constructor,
30303041
void* data,
30313042
size_t property_count,
@@ -3037,6 +3048,8 @@ napi_status napi_define_class(napi_env env,
30373048
- `[in] utf8name`: Name of the JavaScript constructor function; this is
30383049
not required to be the same as the C++ class name, though it is recommended
30393050
for clarity.
3051+
- `[in] length`: The length of the utf8name in bytes, or -1 if it is
3052+
null-terminated.
30403053
- `[in] constructor`: Callback function that handles constructing instances
30413054
of the class. (This should be a static method on the class, not an actual
30423055
C++ constructor function.)

‎src/node_api.cc

+22-4
Original file line numberDiff line numberDiff line change
@@ -938,12 +938,29 @@ napi_status napi_get_last_error_info(napi_env env,
938938
}
939939

940940
NAPI_NO_RETURN void napi_fatal_error(const char* location,
941-
const char* message) {
942-
node::FatalError(location, message);
941+
size_t location_len,
942+
const char* message,
943+
size_t message_len) {
944+
char* location_string = const_cast<char*>(location);
945+
char* message_string = const_cast<char*>(message);
946+
if (location_len != -1) {
947+
location_string = reinterpret_cast<char*>(
948+
malloc(location_len * sizeof(char) + 1));
949+
strncpy(location_string, location, location_len);
950+
location_string[location_len] = '\0';
951+
}
952+
if (message_len != -1) {
953+
message_string = reinterpret_cast<char*>(
954+
malloc(message_len * sizeof(char) + 1));
955+
strncpy(message_string, message, message_len);
956+
message_string[message_len] = '\0';
957+
}
958+
node::FatalError(location_string, message_string);
943959
}
944960

945961
napi_status napi_create_function(napi_env env,
946962
const char* utf8name,
963+
size_t length,
947964
napi_callback cb,
948965
void* callback_data,
949966
napi_value* result) {
@@ -970,7 +987,7 @@ napi_status napi_create_function(napi_env env,
970987

971988
if (utf8name != nullptr) {
972989
v8::Local<v8::String> name_string;
973-
CHECK_NEW_FROM_UTF8(env, name_string, utf8name);
990+
CHECK_NEW_FROM_UTF8_LEN(env, name_string, utf8name, length);
974991
return_value->SetName(name_string);
975992
}
976993

@@ -981,6 +998,7 @@ napi_status napi_create_function(napi_env env,
981998

982999
napi_status napi_define_class(napi_env env,
9831000
const char* utf8name,
1001+
size_t length,
9841002
napi_callback constructor,
9851003
void* callback_data,
9861004
size_t property_count,
@@ -1002,7 +1020,7 @@ napi_status napi_define_class(napi_env env,
10021020
isolate, v8impl::FunctionCallbackWrapper::Invoke, cbdata);
10031021

10041022
v8::Local<v8::String> name_string;
1005-
CHECK_NEW_FROM_UTF8(env, name_string, utf8name);
1023+
CHECK_NEW_FROM_UTF8_LEN(env, name_string, utf8name, length);
10061024
tpl->SetClassName(name_string);
10071025

10081026
size_t static_property_count = 0;

‎src/node_api.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ napi_get_last_error_info(napi_env env,
109109
const napi_extended_error_info** result);
110110

111111
NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location,
112-
const char* message);
112+
size_t location_len,
113+
const char* message,
114+
size_t message_len);
113115

114116
// Getters for defined singletons
115117
NAPI_EXTERN napi_status napi_get_undefined(napi_env env, napi_value* result);
@@ -154,6 +156,7 @@ NAPI_EXTERN napi_status napi_create_symbol(napi_env env,
154156
napi_value* result);
155157
NAPI_EXTERN napi_status napi_create_function(napi_env env,
156158
const char* utf8name,
159+
size_t length,
157160
napi_callback cb,
158161
void* data,
159162
napi_value* result);
@@ -336,6 +339,7 @@ NAPI_EXTERN napi_status napi_get_new_target(napi_env env,
336339
NAPI_EXTERN napi_status
337340
napi_define_class(napi_env env,
338341
const char* utf8name,
342+
size_t length,
339343
napi_callback constructor,
340344
void* data,
341345
size_t property_count,

‎test/addons-napi/4_object_factory/binding.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ napi_value CreateObject(napi_env env, napi_callback_info info) {
1616

1717
napi_value Init(napi_env env, napi_value exports) {
1818
NAPI_CALL(env,
19-
napi_create_function(env, "exports", CreateObject, NULL, &exports));
19+
napi_create_function(env, "exports", -1, CreateObject, NULL, &exports));
2020
return exports;
2121
}
2222

‎test/addons-napi/5_function_factory/binding.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,19 @@
44
napi_value MyFunction(napi_env env, napi_callback_info info) {
55
napi_value str;
66
NAPI_CALL(env, napi_create_string_utf8(env, "hello world", -1, &str));
7-
87
return str;
98
}
109

1110
napi_value CreateFunction(napi_env env, napi_callback_info info) {
1211
napi_value fn;
1312
NAPI_CALL(env,
14-
napi_create_function(env, "theFunction", MyFunction, NULL, &fn));
15-
13+
napi_create_function(env, "theFunction", -1, MyFunction, NULL, &fn));
1614
return fn;
1715
}
1816

1917
napi_value Init(napi_env env, napi_value exports) {
2018
NAPI_CALL(env,
21-
napi_create_function(env, "exports", CreateFunction, NULL, &exports));
19+
napi_create_function(env, "exports", -1, CreateFunction, NULL, &exports));
2220
return exports;
2321
}
2422

‎test/addons-napi/6_object_wrap/myobject.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ void MyObject::Init(napi_env env, napi_value exports) {
2222
};
2323

2424
napi_value cons;
25-
NAPI_CALL_RETURN_VOID(env,
26-
napi_define_class(env, "MyObject", New, nullptr, 3, properties, &cons));
25+
NAPI_CALL_RETURN_VOID(env, napi_define_class(
26+
env, "MyObject", -1, New, nullptr, 3, properties, &cons));
2727

2828
NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, cons, 1, &constructor));
2929

‎test/addons-napi/7_factory_wrap/binding.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ napi_value Init(napi_env env, napi_value exports) {
1616
NAPI_CALL(env, MyObject::Init(env));
1717

1818
NAPI_CALL(env,
19-
napi_create_function(env, "exports", CreateObject, NULL, &exports));
19+
napi_create_function(env, "exports", -1, CreateObject, NULL, &exports));
2020
return exports;
2121
}
2222

‎test/addons-napi/7_factory_wrap/myobject.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ napi_status MyObject::Init(napi_env env) {
2121
};
2222

2323
napi_value cons;
24-
status =
25-
napi_define_class(env, "MyObject", New, nullptr, 1, properties, &cons);
24+
status = napi_define_class(
25+
env, "MyObject", -1, New, nullptr, 1, properties, &cons);
2626
if (status != napi_ok) return status;
2727

2828
status = napi_create_reference(env, cons, 1, &constructor);

‎test/addons-napi/8_passing_wrapped/myobject.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ napi_status MyObject::Init(napi_env env) {
1717
napi_status status;
1818

1919
napi_value cons;
20-
status = napi_define_class(env, "MyObject", New, nullptr, 0, nullptr, &cons);
20+
status = napi_define_class(
21+
env, "MyObject", -1, New, nullptr, 0, nullptr, &cons);
2122
if (status != napi_ok) return status;
2223

2324
status = napi_create_reference(env, cons, 1, &constructor);

‎test/addons-napi/test_constructor/binding.gyp

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
{
44
"target_name": "test_constructor",
55
"sources": [ "test_constructor.c" ]
6+
},
7+
{
8+
"target_name": "test_constructor_name",
9+
"sources": [ "test_constructor_name.c" ]
610
}
711
]
812
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
const common = require('../../common');
3+
const assert = require('assert');
4+
5+
// Testing api calls for a constructor that defines properties
6+
const TestConstructor =
7+
require(`./build/${common.buildType}/test_constructor_name`);
8+
assert.strictEqual(TestConstructor.name, 'MyObject');

‎test/addons-napi/test_constructor/test_constructor.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ napi_value Init(napi_env env, napi_value exports) {
7777
};
7878

7979
napi_value cons;
80-
NAPI_CALL(env, napi_define_class(env, "MyObject", New,
80+
NAPI_CALL(env, napi_define_class(env, "MyObject", -1, New,
8181
NULL, sizeof(properties)/sizeof(*properties), properties, &cons));
8282

8383
NAPI_CALL(env, napi_create_reference(env, cons, 1, &constructor_));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <node_api.h>
2+
#include "../common.h"
3+
4+
napi_ref constructor_;
5+
6+
napi_value New(napi_env env, napi_callback_info info) {
7+
napi_value _this;
8+
NAPI_CALL(env, napi_get_cb_info(env, info, NULL, NULL, &_this, NULL));
9+
10+
return _this;
11+
}
12+
13+
napi_value Init(napi_env env, napi_value exports) {
14+
napi_value cons;
15+
NAPI_CALL(env, napi_define_class(
16+
env, "MyObject_Extra", 8, New, NULL, 0, NULL, &cons));
17+
18+
NAPI_CALL(env,
19+
napi_create_reference(env, cons, 1, &constructor_));
20+
return cons;
21+
}
22+
23+
NAPI_MODULE(addon, Init)

‎test/addons-napi/test_env_sharing/compare_env.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ napi_value compare(napi_env env, napi_callback_info info) {
1515
}
1616

1717
napi_value Init(napi_env env, napi_value exports) {
18-
NAPI_CALL(env, napi_create_function(env, "exports", compare, NULL, &exports));
18+
NAPI_CALL(env, napi_create_function(env, "exports", -1, compare, NULL, &exports));
1919
return exports;
2020
}
2121

‎test/addons-napi/test_fatal/test2.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
const common = require('../../common');
3+
const assert = require('assert');
4+
const child_process = require('child_process');
5+
const test_fatal = require(`./build/${common.buildType}/test_fatal`);
6+
7+
// Test in a child process because the test code will trigger a fatal error
8+
// that crashes the process.
9+
if (process.argv[2] === 'child') {
10+
test_fatal.TestStringLength();
11+
return;
12+
}
13+
14+
const p = child_process.spawnSync(
15+
process.execPath, [ '--napi-modules', __filename, 'child' ]);
16+
assert.ifError(p.error);
17+
assert.ok(p.stderr.toString().includes(
18+
'FATAL ERROR: test_fatal::Test fatal message'));

‎test/addons-napi/test_fatal/test_fatal.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22
#include "../common.h"
33

44
napi_value Test(napi_env env, napi_callback_info info) {
5-
napi_fatal_error("test_fatal::Test", "fatal message");
5+
napi_fatal_error("test_fatal::Test", -1, "fatal message", -1);
6+
return NULL;
7+
}
8+
9+
napi_value TestStringLength(napi_env env, napi_callback_info info) {
10+
napi_fatal_error("test_fatal::TestStringLength", 16, "fatal message", 13);
611
return NULL;
712
}
813

914
napi_value Init(napi_env env, napi_value exports) {
1015
napi_property_descriptor properties[] = {
1116
DECLARE_NAPI_PROPERTY("Test", Test),
17+
DECLARE_NAPI_PROPERTY("TestStringLength", TestStringLength),
1218
};
1319

1420
NAPI_CALL(env, napi_define_properties(

‎test/addons-napi/test_function/test.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@ const test_function = require(`./build/${common.buildType}/test_function`);
99
function func1() {
1010
return 1;
1111
}
12-
assert.strictEqual(test_function.Test(func1), 1);
12+
assert.strictEqual(test_function.TestCall(func1), 1);
1313

1414
function func2() {
1515
console.log('hello world!');
1616
return null;
1717
}
18-
assert.strictEqual(test_function.Test(func2), null);
18+
assert.strictEqual(test_function.TestCall(func2), null);
1919

2020
function func3(input) {
2121
return input + 1;
2222
}
23-
assert.strictEqual(test_function.Test(func3, 1), 2);
23+
assert.strictEqual(test_function.TestCall(func3, 1), 2);
2424

2525
function func4(input) {
2626
return func3(input);
2727
}
28-
assert.strictEqual(test_function.Test(func4, 1), 2);
28+
assert.strictEqual(test_function.TestCall(func4, 1), 2);
29+
30+
assert.strictEqual(test_function.TestName.name, 'Name');
31+
assert.strictEqual(test_function.TestNameShort.name, 'Name_');

‎test/addons-napi/test_function/test_function.c

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <node_api.h>
22
#include "../common.h"
33

4-
napi_value Test(napi_env env, napi_callback_info info) {
4+
napi_value TestCallFunction(napi_env env, napi_callback_info info) {
55
size_t argc = 10;
66
napi_value args[10];
77
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
@@ -26,10 +26,25 @@ napi_value Test(napi_env env, napi_callback_info info) {
2626
return result;
2727
}
2828

29+
void TestFunctionName(napi_env env, napi_callback_info info) {}
30+
2931
napi_value Init(napi_env env, napi_value exports) {
30-
napi_value fn;
31-
NAPI_CALL(env, napi_create_function(env, NULL, Test, NULL, &fn));
32-
NAPI_CALL(env, napi_set_named_property(env, exports, "Test", fn));
32+
napi_value fn1;
33+
NAPI_CALL(env, napi_create_function(
34+
env, NULL, -1, TestCallFunction, NULL, &fn1));
35+
36+
napi_value fn2;
37+
NAPI_CALL(env, napi_create_function(
38+
env, "Name", -1, TestFunctionName, NULL, &fn2));
39+
40+
napi_value fn3;
41+
NAPI_CALL(env, napi_create_function(
42+
env, "Name_extra", 5, TestFunctionName, NULL, &fn3));
43+
44+
NAPI_CALL(env, napi_set_named_property(env, exports, "TestCall", fn1));
45+
NAPI_CALL(env, napi_set_named_property(env, exports, "TestName", fn2));
46+
NAPI_CALL(env, napi_set_named_property(env, exports, "TestNameShort", fn3));
47+
3348
return exports;
3449
}
3550

‎test/addons-napi/test_make_callback/binding.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ napi_value MakeCallback(napi_env env, napi_callback_info info) {
4545

4646
napi_value Init(napi_env env, napi_value exports) {
4747
napi_value fn;
48-
NAPI_CALL(env, napi_create_function(env, NULL, MakeCallback, NULL, &fn));
48+
NAPI_CALL(env, napi_create_function(env, NULL, -1, MakeCallback, NULL, &fn));
4949
NAPI_CALL(env, napi_set_named_property(env, exports, "makeCallback", fn));
5050
return exports;
5151
}

‎test/addons-napi/test_make_callback_recurse/binding.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ napi_value MakeCallback(napi_env env, napi_callback_info info) {
2020

2121
napi_value Init(napi_env env, napi_value exports) {
2222
napi_value fn;
23-
NAPI_CALL(env, napi_create_function(env, NULL, MakeCallback, NULL, &fn));
23+
NAPI_CALL(env, napi_create_function(env, NULL, -1, MakeCallback, NULL, &fn));
2424
NAPI_CALL(env, napi_set_named_property(env, exports, "makeCallback", fn));
2525
return exports;
2626
}

0 commit comments

Comments
 (0)
Please sign in to comment.