Skip to content

Commit c821eef

Browse files
Octavian SoldeaBridgeAR
Octavian Soldea
authored andcommitted
src: add napi_define_class() null checks
napi_define_class is tested by passing NULL to all parameters that are pointers, one at a time. Moreover, two bugs were corrected. One was utf8name and the second was the property descriptor pointer. These pointers were assumed to be non-NULL and now we have NULL checks. PR-URL: #27945 Reviewed-By: Gabriel Schulhof <[email protected]>
1 parent f7d8384 commit c821eef

File tree

3 files changed

+172
-11
lines changed

3 files changed

+172
-11
lines changed

src/js_native_api_v8.cc

+7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
RETURN_STATUS_IF_FALSE((env), \
2525
(len == NAPI_AUTO_LENGTH) || len <= INT_MAX, \
2626
napi_invalid_arg); \
27+
RETURN_STATUS_IF_FALSE((env), \
28+
(str) != nullptr, \
29+
napi_invalid_arg); \
2730
auto str_maybe = v8::String::NewFromUtf8( \
2831
(env)->isolate, (str), v8::NewStringType::kInternalized, \
2932
static_cast<int>(len)); \
@@ -768,6 +771,10 @@ napi_status napi_define_class(napi_env env,
768771
CHECK_ARG(env, result);
769772
CHECK_ARG(env, constructor);
770773

774+
if (property_count > 0) {
775+
CHECK_ARG(env, properties);
776+
}
777+
771778
v8::Isolate* isolate = env->isolate;
772779

773780
v8::EscapableHandleScope scope(isolate);

test/js-native-api/test_constructor/test.js

+11
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,14 @@ assert.throws(() => { test_object.readonlyAccessor2 = 3; },
4848
// to the instance
4949
assert.strictEqual(TestConstructor.staticReadonlyAccessor1, 10);
5050
assert.strictEqual(test_object.staticReadonlyAccessor1, undefined);
51+
52+
// Verify that passing NULL to napi_define_class() results in the correct
53+
// error.
54+
assert.deepStrictEqual(TestConstructor.TestDefineClass(), {
55+
envIsNull: 'pass',
56+
nameIsNull: 'pass',
57+
cbIsNull: 'pass',
58+
cbDataIsNull: 'pass',
59+
propertiesIsNull: 'pass',
60+
resultIsNull: 'pass'
61+
});

test/js-native-api/test_constructor/test_constructor.c

+154-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,140 @@
44
static double value_ = 1;
55
static double static_value_ = 10;
66

7+
static napi_value TestDefineClass(napi_env env,
8+
napi_callback_info info) {
9+
napi_status ret[7];
10+
napi_value result, return_value, prop_value;
11+
12+
napi_property_descriptor property_descriptor = {
13+
"TestDefineClass",
14+
NULL,
15+
TestDefineClass,
16+
NULL,
17+
NULL,
18+
NULL,
19+
napi_enumerable | napi_static,
20+
NULL};
21+
22+
ret[0] = napi_define_class(NULL,
23+
"TrackedFunction",
24+
NAPI_AUTO_LENGTH,
25+
TestDefineClass,
26+
NULL,
27+
1,
28+
&property_descriptor,
29+
&result);
30+
31+
ret[1] = napi_define_class(env,
32+
NULL,
33+
NAPI_AUTO_LENGTH,
34+
TestDefineClass,
35+
NULL,
36+
1,
37+
&property_descriptor,
38+
&result);
39+
40+
ret[2] = napi_define_class(env,
41+
"TrackedFunction",
42+
NAPI_AUTO_LENGTH,
43+
NULL,
44+
NULL,
45+
1,
46+
&property_descriptor,
47+
&result);
48+
49+
ret[3] = napi_define_class(env,
50+
"TrackedFunction",
51+
NAPI_AUTO_LENGTH,
52+
TestDefineClass,
53+
NULL,
54+
1,
55+
&property_descriptor,
56+
&result);
57+
58+
ret[4] = napi_define_class(env,
59+
"TrackedFunction",
60+
NAPI_AUTO_LENGTH,
61+
TestDefineClass,
62+
NULL,
63+
1,
64+
NULL,
65+
&result);
66+
67+
ret[5] = napi_define_class(env,
68+
"TrackedFunction",
69+
NAPI_AUTO_LENGTH,
70+
TestDefineClass,
71+
NULL,
72+
1,
73+
&property_descriptor,
74+
NULL);
75+
76+
NAPI_CALL(env, napi_create_object(env, &return_value));
77+
78+
NAPI_CALL(env, napi_create_string_utf8(env,
79+
(ret[0] == napi_invalid_arg ?
80+
"pass" : "fail"),
81+
NAPI_AUTO_LENGTH,
82+
&prop_value));
83+
NAPI_CALL(env, napi_set_named_property(env,
84+
return_value,
85+
"envIsNull",
86+
prop_value));
87+
88+
NAPI_CALL(env, napi_create_string_utf8(env,
89+
(ret[1] == napi_invalid_arg ?
90+
"pass" : "fail"),
91+
NAPI_AUTO_LENGTH,
92+
&prop_value));
93+
NAPI_CALL(env, napi_set_named_property(env,
94+
return_value,
95+
"nameIsNull",
96+
prop_value));
97+
98+
NAPI_CALL(env, napi_create_string_utf8(env,
99+
(ret[2] == napi_invalid_arg ?
100+
"pass" : "fail"),
101+
NAPI_AUTO_LENGTH,
102+
&prop_value));
103+
NAPI_CALL(env, napi_set_named_property(env,
104+
return_value,
105+
"cbIsNull",
106+
prop_value));
107+
108+
NAPI_CALL(env, napi_create_string_utf8(env,
109+
(ret[3] == napi_ok ?
110+
"pass" : "fail"),
111+
NAPI_AUTO_LENGTH,
112+
&prop_value));
113+
NAPI_CALL(env, napi_set_named_property(env,
114+
return_value,
115+
"cbDataIsNull",
116+
prop_value));
117+
118+
NAPI_CALL(env, napi_create_string_utf8(env,
119+
(ret[4] == napi_invalid_arg ?
120+
"pass" : "fail"),
121+
NAPI_AUTO_LENGTH,
122+
&prop_value));
123+
NAPI_CALL(env, napi_set_named_property(env,
124+
return_value,
125+
"propertiesIsNull",
126+
prop_value));
127+
128+
NAPI_CALL(env, napi_create_string_utf8(env,
129+
(ret[5] == napi_invalid_arg ?
130+
"pass" : "fail"),
131+
NAPI_AUTO_LENGTH,
132+
&prop_value));
133+
NAPI_CALL(env, napi_set_named_property(env,
134+
return_value,
135+
"resultIsNull",
136+
prop_value));
137+
138+
return return_value;
139+
}
140+
7141
static napi_value GetValue(napi_env env, napi_callback_info info) {
8142
size_t argc = 0;
9143
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, NULL, NULL, NULL));
@@ -74,17 +208,26 @@ napi_value Init(napi_env env, napi_value exports) {
74208
env, "MyObject_Extra", 8, NewExtra, NULL, 0, NULL, &cons));
75209

76210
napi_property_descriptor properties[] = {
77-
{ "echo", 0, Echo, 0, 0, 0, napi_enumerable, 0 },
78-
{ "readwriteValue", 0, 0, 0, 0, number, napi_enumerable | napi_writable, 0 },
79-
{ "readonlyValue", 0, 0, 0, 0, number, napi_enumerable, 0},
80-
{ "hiddenValue", 0, 0, 0, 0, number, napi_default, 0},
81-
{ "readwriteAccessor1", 0, 0, GetValue, SetValue, 0, napi_default, 0},
82-
{ "readwriteAccessor2", 0, 0, GetValue, SetValue, 0, napi_writable, 0},
83-
{ "readonlyAccessor1", 0, 0, GetValue, NULL, 0, napi_default, 0},
84-
{ "readonlyAccessor2", 0, 0, GetValue, NULL, 0, napi_writable, 0},
85-
{ "staticReadonlyAccessor1", 0, 0, GetStaticValue, NULL, 0,
86-
napi_default | napi_static, 0},
87-
{ "constructorName", 0, 0, 0, 0, cons, napi_enumerable | napi_static, 0 },
211+
{ "echo", NULL, Echo, NULL, NULL, NULL, napi_enumerable, NULL },
212+
{ "readwriteValue", NULL, NULL, NULL, NULL, number,
213+
napi_enumerable | napi_writable, NULL },
214+
{ "readonlyValue", NULL, NULL, NULL, NULL, number, napi_enumerable,
215+
NULL },
216+
{ "hiddenValue", NULL, NULL, NULL, NULL, number, napi_default, NULL },
217+
{ "readwriteAccessor1", NULL, NULL, GetValue, SetValue, NULL, napi_default,
218+
NULL },
219+
{ "readwriteAccessor2", NULL, NULL, GetValue, SetValue, NULL,
220+
napi_writable, NULL },
221+
{ "readonlyAccessor1", NULL, NULL, GetValue, NULL, NULL, napi_default,
222+
NULL },
223+
{ "readonlyAccessor2", NULL, NULL, GetValue, NULL, NULL, napi_writable,
224+
NULL },
225+
{ "staticReadonlyAccessor1", NULL, NULL, GetStaticValue, NULL, NULL,
226+
napi_default | napi_static, NULL},
227+
{ "constructorName", NULL, NULL, NULL, NULL, cons,
228+
napi_enumerable | napi_static, NULL },
229+
{ "TestDefineClass", NULL, TestDefineClass, NULL, NULL, NULL,
230+
napi_enumerable | napi_static, NULL },
88231
};
89232

90233
NAPI_CALL(env, napi_define_class(env, "MyObject", NAPI_AUTO_LENGTH, New,

0 commit comments

Comments
 (0)