Skip to content

Commit ed65137

Browse files
Gabriel Schulhofaddaleax
Gabriel Schulhof
authored andcommitted
test: add n-api null checks for conversions
Add assertions that conversion and coercion N-APIs return appropriate error statuses when given `NULL`s for parameters they expect to not be `NULL`. For `napi_get_value_string_*` this also checks that it returns `napi_string_expected` when passed a `napi_value` not containing a string. PR-URL: #34142 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent cfc769b commit ed65137

File tree

5 files changed

+194
-1
lines changed

5 files changed

+194
-1
lines changed

Diff for: test/js-native-api/test_conversions/binding.gyp

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"target_name": "test_conversions",
55
"sources": [
66
"../entry_point.c",
7-
"test_conversions.c"
7+
"../common.c",
8+
"test_conversions.c",
9+
"test_null.c",
810
]
911
}
1012
]

Diff for: test/js-native-api/test_conversions/test.js

+78
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,81 @@ assert.strictEqual(test.toString({ toString: () => 'test' }), 'test');
138138
assert.strictEqual(test.toString([]), '');
139139
assert.strictEqual(test.toString([ 1, 2, 3 ]), '1,2,3');
140140
assert.throws(() => test.toString(testSym), TypeError);
141+
142+
assert.deepStrictEqual(test.testNull.getValueBool(), {
143+
envIsNull: 'Invalid argument',
144+
valueIsNull: 'Invalid argument',
145+
resultIsNull: 'Invalid argument',
146+
inputTypeCheck: 'A boolean was expected'
147+
});
148+
149+
assert.deepStrictEqual(test.testNull.getValueInt32(), {
150+
envIsNull: 'Invalid argument',
151+
valueIsNull: 'Invalid argument',
152+
resultIsNull: 'Invalid argument',
153+
inputTypeCheck: 'A number was expected'
154+
});
155+
156+
assert.deepStrictEqual(test.testNull.getValueUint32(), {
157+
envIsNull: 'Invalid argument',
158+
valueIsNull: 'Invalid argument',
159+
resultIsNull: 'Invalid argument',
160+
inputTypeCheck: 'A number was expected'
161+
});
162+
163+
assert.deepStrictEqual(test.testNull.getValueInt64(), {
164+
envIsNull: 'Invalid argument',
165+
valueIsNull: 'Invalid argument',
166+
resultIsNull: 'Invalid argument',
167+
inputTypeCheck: 'A number was expected'
168+
});
169+
170+
171+
assert.deepStrictEqual(test.testNull.getValueDouble(), {
172+
envIsNull: 'Invalid argument',
173+
valueIsNull: 'Invalid argument',
174+
resultIsNull: 'Invalid argument',
175+
inputTypeCheck: 'A number was expected'
176+
});
177+
178+
assert.deepStrictEqual(test.testNull.coerceToBool(), {
179+
envIsNull: 'Invalid argument',
180+
valueIsNull: 'Invalid argument',
181+
resultIsNull: 'Invalid argument',
182+
inputTypeCheck: 'napi_ok'
183+
});
184+
185+
assert.deepStrictEqual(test.testNull.coerceToObject(), {
186+
envIsNull: 'Invalid argument',
187+
valueIsNull: 'Invalid argument',
188+
resultIsNull: 'Invalid argument',
189+
inputTypeCheck: 'napi_ok'
190+
});
191+
192+
assert.deepStrictEqual(test.testNull.coerceToString(), {
193+
envIsNull: 'Invalid argument',
194+
valueIsNull: 'Invalid argument',
195+
resultIsNull: 'Invalid argument',
196+
inputTypeCheck: 'napi_ok'
197+
});
198+
199+
assert.deepStrictEqual(test.testNull.getValueStringUtf8(), {
200+
envIsNull: 'Invalid argument',
201+
valueIsNull: 'Invalid argument',
202+
wrongTypeIn: 'A string was expected',
203+
bufAndOutLengthIsNull: 'Invalid argument'
204+
});
205+
206+
assert.deepStrictEqual(test.testNull.getValueStringLatin1(), {
207+
envIsNull: 'Invalid argument',
208+
valueIsNull: 'Invalid argument',
209+
wrongTypeIn: 'A string was expected',
210+
bufAndOutLengthIsNull: 'Invalid argument'
211+
});
212+
213+
assert.deepStrictEqual(test.testNull.getValueStringUtf16(), {
214+
envIsNull: 'Invalid argument',
215+
valueIsNull: 'Invalid argument',
216+
wrongTypeIn: 'A string was expected',
217+
bufAndOutLengthIsNull: 'Invalid argument'
218+
});

Diff for: test/js-native-api/test_conversions/test_conversions.c

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <js_native_api.h>
22
#include "../common.h"
3+
#include "test_null.h"
34

45
static napi_value AsBool(napi_env env, napi_callback_info info) {
56
size_t argc = 1;
@@ -149,6 +150,8 @@ napi_value Init(napi_env env, napi_value exports) {
149150
NAPI_CALL(env, napi_define_properties(
150151
env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
151152

153+
init_test_null(env, exports);
154+
152155
return exports;
153156
}
154157
EXTERN_C_END

Diff for: test/js-native-api/test_conversions/test_null.c

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include <js_native_api.h>
2+
3+
#include "../common.h"
4+
#include "test_null.h"
5+
6+
#define GEN_NULL_CHECK_BINDING(binding_name, output_type, api) \
7+
static napi_value binding_name(napi_env env, napi_callback_info info) { \
8+
napi_value return_value; \
9+
output_type result; \
10+
NAPI_CALL(env, napi_create_object(env, &return_value)); \
11+
add_returned_status(env, \
12+
"envIsNull", \
13+
return_value, \
14+
"Invalid argument", \
15+
napi_invalid_arg, \
16+
api(NULL, return_value, &result)); \
17+
api(env, NULL, &result); \
18+
add_last_status(env, "valueIsNull", return_value); \
19+
api(env, return_value, NULL); \
20+
add_last_status(env, "resultIsNull", return_value); \
21+
api(env, return_value, &result); \
22+
add_last_status(env, "inputTypeCheck", return_value); \
23+
return return_value; \
24+
}
25+
26+
GEN_NULL_CHECK_BINDING(GetValueBool, bool, napi_get_value_bool)
27+
GEN_NULL_CHECK_BINDING(GetValueInt32, int32_t, napi_get_value_int32)
28+
GEN_NULL_CHECK_BINDING(GetValueUint32, uint32_t, napi_get_value_uint32)
29+
GEN_NULL_CHECK_BINDING(GetValueInt64, int64_t, napi_get_value_int64)
30+
GEN_NULL_CHECK_BINDING(GetValueDouble, double, napi_get_value_double)
31+
GEN_NULL_CHECK_BINDING(CoerceToBool, napi_value, napi_coerce_to_bool)
32+
GEN_NULL_CHECK_BINDING(CoerceToObject, napi_value, napi_coerce_to_object)
33+
GEN_NULL_CHECK_BINDING(CoerceToString, napi_value, napi_coerce_to_string)
34+
35+
#define GEN_NULL_CHECK_STRING_BINDING(binding_name, arg_type, api) \
36+
static napi_value binding_name(napi_env env, napi_callback_info info) { \
37+
napi_value return_value; \
38+
NAPI_CALL(env, napi_create_object(env, &return_value)); \
39+
arg_type buf1[4]; \
40+
size_t length1 = 3; \
41+
add_returned_status(env, \
42+
"envIsNull", \
43+
return_value, \
44+
"Invalid argument", \
45+
napi_invalid_arg, \
46+
api(NULL, return_value, buf1, length1, &length1)); \
47+
arg_type buf2[4]; \
48+
size_t length2 = 3; \
49+
api(env, NULL, buf2, length2, &length2); \
50+
add_last_status(env, "valueIsNull", return_value); \
51+
api(env, return_value, NULL, 3, NULL); \
52+
add_last_status(env, "wrongTypeIn", return_value); \
53+
napi_value string; \
54+
NAPI_CALL(env, \
55+
napi_create_string_utf8(env, \
56+
"Something", \
57+
NAPI_AUTO_LENGTH, \
58+
&string)); \
59+
api(env, string, NULL, 3, NULL); \
60+
add_last_status(env, "bufAndOutLengthIsNull", return_value); \
61+
return return_value; \
62+
}
63+
64+
GEN_NULL_CHECK_STRING_BINDING(GetValueStringUtf8,
65+
char,
66+
napi_get_value_string_utf8)
67+
GEN_NULL_CHECK_STRING_BINDING(GetValueStringLatin1,
68+
char,
69+
napi_get_value_string_latin1)
70+
GEN_NULL_CHECK_STRING_BINDING(GetValueStringUtf16,
71+
char16_t,
72+
napi_get_value_string_utf16)
73+
74+
void init_test_null(napi_env env, napi_value exports) {
75+
napi_value test_null;
76+
77+
const napi_property_descriptor test_null_props[] = {
78+
DECLARE_NAPI_PROPERTY("getValueBool", GetValueBool),
79+
DECLARE_NAPI_PROPERTY("getValueInt32", GetValueInt32),
80+
DECLARE_NAPI_PROPERTY("getValueUint32", GetValueUint32),
81+
DECLARE_NAPI_PROPERTY("getValueInt64", GetValueInt64),
82+
DECLARE_NAPI_PROPERTY("getValueDouble", GetValueDouble),
83+
DECLARE_NAPI_PROPERTY("coerceToBool", CoerceToBool),
84+
DECLARE_NAPI_PROPERTY("coerceToObject", CoerceToObject),
85+
DECLARE_NAPI_PROPERTY("coerceToString", CoerceToString),
86+
DECLARE_NAPI_PROPERTY("getValueStringUtf8", GetValueStringUtf8),
87+
DECLARE_NAPI_PROPERTY("getValueStringLatin1", GetValueStringLatin1),
88+
DECLARE_NAPI_PROPERTY("getValueStringUtf16", GetValueStringUtf16),
89+
};
90+
91+
NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &test_null));
92+
NAPI_CALL_RETURN_VOID(env, napi_define_properties(
93+
env, test_null, sizeof(test_null_props) / sizeof(*test_null_props),
94+
test_null_props));
95+
96+
const napi_property_descriptor test_null_set = {
97+
"testNull", NULL, NULL, NULL, NULL, test_null, napi_enumerable, NULL
98+
};
99+
100+
NAPI_CALL_RETURN_VOID(env,
101+
napi_define_properties(env, exports, 1, &test_null_set));
102+
}

Diff for: test/js-native-api/test_conversions/test_null.h

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef TEST_JS_NATIVE_API_TEST_CONVERSIONS_TEST_NULL_H_
2+
#define TEST_JS_NATIVE_API_TEST_CONVERSIONS_TEST_NULL_H_
3+
4+
#include <js_native_api.h>
5+
6+
void init_test_null(napi_env env, napi_value exports);
7+
8+
#endif // TEST_JS_NATIVE_API_TEST_CONVERSIONS_TEST_NULL_H_

0 commit comments

Comments
 (0)