node-addon-api 1.7.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/napi.h CHANGED
@@ -5,6 +5,7 @@
5
5
  #include <functional>
6
6
  #include <initializer_list>
7
7
  #include <memory>
8
+ #include <mutex>
8
9
  #include <string>
9
10
  #include <vector>
10
11
 
@@ -111,11 +112,15 @@ namespace Napi {
111
112
  class Value;
112
113
  class Boolean;
113
114
  class Number;
114
- // currently experimental guard with version of NAPI_VERSION that it is
115
- // released in once it is no longer experimental
116
- #if (NAPI_VERSION > 2147483646)
115
+ // Currently experimental guard with the definition of NAPI_EXPERIMENTAL.
116
+ // Once it is no longer experimental guard with the NAPI_VERSION in which it is
117
+ // released instead.
118
+ #ifdef NAPI_EXPERIMENTAL
117
119
  class BigInt;
118
120
  #endif // NAPI_EXPERIMENTAL
121
+ #if (NAPI_VERSION > 4)
122
+ class Date;
123
+ #endif
119
124
  class String;
120
125
  class Object;
121
126
  class Array;
@@ -136,9 +141,10 @@ namespace Napi {
136
141
  typedef TypedArrayOf<uint32_t> Uint32Array; ///< Typed-array of unsigned 32-bit integers
137
142
  typedef TypedArrayOf<float> Float32Array; ///< Typed-array of 32-bit floating-point values
138
143
  typedef TypedArrayOf<double> Float64Array; ///< Typed-array of 64-bit floating-point values
139
- // currently experimental guard with version of NAPI_VERSION that it is
140
- // released in once it is no longer experimental
141
- #if (NAPI_VERSION > 2147483646)
144
+ // Currently experimental guard with the definition of NAPI_EXPERIMENTAL.
145
+ // Once it is no longer experimental guard with the NAPI_VERSION in which it is
146
+ // released instead.
147
+ #ifdef NAPI_EXPERIMENTAL
142
148
  typedef TypedArrayOf<int64_t> BigInt64Array; ///< Typed array of signed 64-bit integers
143
149
  typedef TypedArrayOf<uint64_t> BigUint64Array; ///< Typed array of unsigned 64-bit integers
144
150
  #endif // NAPI_EXPERIMENTAL
@@ -241,11 +247,15 @@ namespace Napi {
241
247
  bool IsNull() const; ///< Tests if a value is a null JavaScript value.
242
248
  bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean.
243
249
  bool IsNumber() const; ///< Tests if a value is a JavaScript number.
244
- // currently experimental guard with version of NAPI_VERSION that it is
245
- // released in once it is no longer experimental
246
- #if (NAPI_VERSION > 2147483646)
250
+ // Currently experimental guard with the definition of NAPI_EXPERIMENTAL.
251
+ // Once it is no longer experimental guard with the NAPI_VERSION in which it is
252
+ // released instead.
253
+ #ifdef NAPI_EXPERIMENTAL
247
254
  bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint.
248
255
  #endif // NAPI_EXPERIMENTAL
256
+ #if (NAPI_VERSION > 4)
257
+ bool IsDate() const; ///< Tests if a value is a JavaScript date.
258
+ #endif
249
259
  bool IsString() const; ///< Tests if a value is a JavaScript string.
250
260
  bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol.
251
261
  bool IsArray() const; ///< Tests if a value is a JavaScript array.
@@ -315,9 +325,10 @@ namespace Napi {
315
325
  double DoubleValue() const; ///< Converts a Number value to a 64-bit floating-point value.
316
326
  };
317
327
 
318
- // currently experimental guard with version of NAPI_VERSION that it is
319
- // released in once it is no longer experimental
320
- #if (NAPI_VERSION > 2147483646)
328
+ // Currently experimental guard with the definition of NAPI_EXPERIMENTAL.
329
+ // Once it is no longer experimental guard with the NAPI_VERSION in which it is
330
+ // released instead.
331
+ #ifdef NAPI_EXPERIMENTAL
321
332
  /// A JavaScript bigint value.
322
333
  class BigInt : public Value {
323
334
  public:
@@ -358,6 +369,24 @@ namespace Napi {
358
369
  };
359
370
  #endif // NAPI_EXPERIMENTAL
360
371
 
372
+ #if (NAPI_VERSION > 4)
373
+ /// A JavaScript date value.
374
+ class Date : public Value {
375
+ public:
376
+ /// Creates a new Date value from a double primitive.
377
+ static Date New(
378
+ napi_env env, ///< N-API environment
379
+ double value ///< Number value
380
+ );
381
+
382
+ Date(); ///< Creates a new _empty_ Date instance.
383
+ Date(napi_env env, napi_value value); ///< Wraps a N-API value primitive.
384
+ operator double() const; ///< Converts a Date value to double primitive
385
+
386
+ double ValueOf() const; ///< Converts a Date value to a double primitive.
387
+ };
388
+ #endif
389
+
361
390
  /// A JavaScript string or symbol value (that can be used as a property name).
362
391
  class Name : public Value {
363
392
  public:
@@ -685,6 +714,14 @@ namespace Napi {
685
714
  bool InstanceOf(
686
715
  const Function& constructor ///< Constructor function
687
716
  ) const;
717
+
718
+ template <typename Finalizer, typename T>
719
+ inline void AddFinalizer(Finalizer finalizeCallback, T* data);
720
+
721
+ template <typename Finalizer, typename T, typename Hint>
722
+ inline void AddFinalizer(Finalizer finalizeCallback,
723
+ T* data,
724
+ Hint* finalizeHint);
688
725
  };
689
726
 
690
727
  template <typename T>
@@ -819,9 +856,10 @@ namespace Napi {
819
856
  : std::is_same<T, uint32_t>::value ? napi_uint32_array
820
857
  : std::is_same<T, float>::value ? napi_float32_array
821
858
  : std::is_same<T, double>::value ? napi_float64_array
822
- // currently experimental guard with version of NAPI_VERSION that it is
823
- // released in once it is no longer experimental
824
- #if (NAPI_VERSION > 2147483646)
859
+ // Currently experimental guard with the definition of NAPI_EXPERIMENTAL.
860
+ // Once it is no longer experimental guard with the NAPI_VERSION in which it is
861
+ // released instead.
862
+ #ifdef NAPI_EXPERIMENTAL
825
863
  : std::is_same<T, int64_t>::value ? napi_bigint64_array
826
864
  : std::is_same<T, uint64_t>::value ? napi_biguint64_array
827
865
  #endif // NAPI_EXPERIMENTAL
@@ -1570,6 +1608,7 @@ namespace Napi {
1570
1608
  class ObjectWrap : public Reference<Object> {
1571
1609
  public:
1572
1610
  ObjectWrap(const CallbackInfo& callbackInfo);
1611
+ virtual ~ObjectWrap();
1573
1612
 
1574
1613
  static T* Unwrap(Object wrapper);
1575
1614
 
@@ -1657,6 +1696,7 @@ namespace Napi {
1657
1696
  static PropertyDescriptor InstanceValue(Symbol name,
1658
1697
  Napi::Value value,
1659
1698
  napi_property_attributes attributes = napi_default);
1699
+ virtual void Finalize(Napi::Env env);
1660
1700
 
1661
1701
  private:
1662
1702
  static napi_value ConstructorCallbackWrapper(napi_env env, napi_callback_info info);
@@ -1695,6 +1735,8 @@ namespace Napi {
1695
1735
  StaticAccessorCallbackData;
1696
1736
  typedef AccessorCallbackData<InstanceGetterCallback, InstanceSetterCallback>
1697
1737
  InstanceAccessorCallbackData;
1738
+
1739
+ bool _construction_failed = true;
1698
1740
  };
1699
1741
 
1700
1742
  class HandleScope {
@@ -1703,6 +1745,10 @@ namespace Napi {
1703
1745
  explicit HandleScope(Napi::Env env);
1704
1746
  ~HandleScope();
1705
1747
 
1748
+ // Disallow copying to prevent double close of napi_handle_scope
1749
+ HandleScope(HandleScope const &) = delete;
1750
+ void operator=(HandleScope const &) = delete;
1751
+
1706
1752
  operator napi_handle_scope() const;
1707
1753
 
1708
1754
  Napi::Env Env() const;
@@ -1718,6 +1764,10 @@ namespace Napi {
1718
1764
  explicit EscapableHandleScope(Napi::Env env);
1719
1765
  ~EscapableHandleScope();
1720
1766
 
1767
+ // Disallow copying to prevent double close of napi_escapable_handle_scope
1768
+ EscapableHandleScope(EscapableHandleScope const &) = delete;
1769
+ void operator=(EscapableHandleScope const &) = delete;
1770
+
1721
1771
  operator napi_escapable_handle_scope() const;
1722
1772
 
1723
1773
  Napi::Env Env() const;
@@ -1735,6 +1785,10 @@ namespace Napi {
1735
1785
  CallbackScope(napi_env env, napi_async_context context);
1736
1786
  virtual ~CallbackScope();
1737
1787
 
1788
+ // Disallow copying to prevent double close of napi_callback_scope
1789
+ CallbackScope(CallbackScope const &) = delete;
1790
+ void operator=(CallbackScope const &) = delete;
1791
+
1738
1792
  operator napi_callback_scope() const;
1739
1793
 
1740
1794
  Napi::Env Env() const;
@@ -1758,6 +1812,8 @@ namespace Napi {
1758
1812
 
1759
1813
  operator napi_async_context() const;
1760
1814
 
1815
+ Napi::Env Env() const;
1816
+
1761
1817
  private:
1762
1818
  napi_env _env;
1763
1819
  napi_async_context _context;
@@ -1960,8 +2016,7 @@ namespace Napi {
1960
2016
  ThreadSafeFunction();
1961
2017
  ThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
1962
2018
 
1963
- ThreadSafeFunction(ThreadSafeFunction&& other);
1964
- ThreadSafeFunction& operator=(ThreadSafeFunction&& other);
2019
+ operator napi_threadsafe_function() const;
1965
2020
 
1966
2021
  // This API may be called from any thread.
1967
2022
  napi_status BlockingCall() const;
@@ -1985,6 +2040,12 @@ namespace Napi {
1985
2040
  template <typename DataType, typename Callback>
1986
2041
  napi_status NonBlockingCall(DataType* data, Callback callback) const;
1987
2042
 
2043
+ // This API may only be called from the main thread.
2044
+ void Ref(napi_env env) const;
2045
+
2046
+ // This API may only be called from the main thread.
2047
+ void Unref(napi_env env) const;
2048
+
1988
2049
  // This API may be called from any thread.
1989
2050
  napi_status Acquire() const;
1990
2051
 
@@ -2028,7 +2089,66 @@ namespace Napi {
2028
2089
  void* context,
2029
2090
  void* data);
2030
2091
 
2031
- std::unique_ptr<napi_threadsafe_function> _tsfn;
2092
+ napi_threadsafe_function _tsfn;
2093
+ };
2094
+
2095
+ template<class T>
2096
+ class AsyncProgressWorker : public AsyncWorker {
2097
+ public:
2098
+ virtual ~AsyncProgressWorker();
2099
+
2100
+ class ExecutionProgress {
2101
+ friend class AsyncProgressWorker;
2102
+ public:
2103
+ void Signal() const;
2104
+ void Send(const T* data, size_t count) const;
2105
+ private:
2106
+ explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {}
2107
+ AsyncProgressWorker* const _worker;
2108
+ };
2109
+
2110
+ protected:
2111
+ explicit AsyncProgressWorker(const Function& callback);
2112
+ explicit AsyncProgressWorker(const Function& callback,
2113
+ const char* resource_name);
2114
+ explicit AsyncProgressWorker(const Function& callback,
2115
+ const char* resource_name,
2116
+ const Object& resource);
2117
+ explicit AsyncProgressWorker(const Object& receiver,
2118
+ const Function& callback);
2119
+ explicit AsyncProgressWorker(const Object& receiver,
2120
+ const Function& callback,
2121
+ const char* resource_name);
2122
+ explicit AsyncProgressWorker(const Object& receiver,
2123
+ const Function& callback,
2124
+ const char* resource_name,
2125
+ const Object& resource);
2126
+
2127
+ // Optional callback of Napi::ThreadSafeFunction only available after NAPI_VERSION 4.
2128
+ // Refs: https://github.com/nodejs/node/pull/27791
2129
+ #if NAPI_VERSION > 4
2130
+ explicit AsyncProgressWorker(Napi::Env env);
2131
+ explicit AsyncProgressWorker(Napi::Env env,
2132
+ const char* resource_name);
2133
+ explicit AsyncProgressWorker(Napi::Env env,
2134
+ const char* resource_name,
2135
+ const Object& resource);
2136
+ #endif
2137
+
2138
+ virtual void Execute(const ExecutionProgress& progress) = 0;
2139
+ virtual void OnProgress(const T* data, size_t count) = 0;
2140
+
2141
+ private:
2142
+ static void WorkProgress_(Napi::Env env, Napi::Function jsCallback, void* data);
2143
+
2144
+ void Execute() override;
2145
+ void Signal() const;
2146
+ void SendProgress_(const T* data, size_t count);
2147
+
2148
+ std::mutex _mutex;
2149
+ T* _asyncdata;
2150
+ size_t _asyncsize;
2151
+ ThreadSafeFunction _tsfn;
2032
2152
  };
2033
2153
  #endif
2034
2154
 
package/package.json CHANGED
@@ -3,50 +3,206 @@
3
3
  "url": "https://github.com/nodejs/node-addon-api/issues"
4
4
  },
5
5
  "contributors": [
6
- "Abhishek Kumar Singh (https://github.com/abhi11210646)",
7
- "Alba Mendez (https://github.com/jmendeth)",
8
- "Andrew Petersen (https://github.com/kirbysayshi)",
9
- "Anisha Rohra (https://github.com/anisha-rohra)",
10
- "Anna Henningsen (https://github.com/addaleax)",
11
- "Arnaud Botella (https://github.com/BotellaA)",
12
- "Arunesh Chandra (https://github.com/aruneshchandra)",
13
- "Ben Berman (https://github.com/rivertam)",
14
- "Benjamin Byholm (https://github.com/kkoopa)",
15
- "Bill Gallafent (https://github.com/gallafent)",
16
- "Bruce A. MacNaughton (https://github.com/bmacnaughton)",
17
- "Cory Mickelson (https://github.com/corymickelson)",
18
- "David Halls (https://github.com/davedoesdev)",
19
- "Dongjin Na (https://github.com/nadongguri)",
20
- "Eric Bickle (https://github.com/ebickle)",
21
- "Gabriel Schulhof (https://github.com/gabrielschulhof)",
22
- "Gus Caplan (https://github.com/devsnek)",
23
- "Hitesh Kanwathirtha (https://github.com/digitalinfinity)",
24
- "Jake Barnes (https://github.com/DuBistKomisch)",
25
- "Jake Yoon (https://github.com/yjaeseok)",
26
- "Jason Ginchereau (https://github.com/jasongin)",
27
- "Jim Schlight (https://github.com/jschlight)",
28
- "Jinho Bang (https://github.com/romandev)",
29
- "joshgarde (https://github.com/joshgarde)",
30
- "Kevin Eady (https://github.com/KevinEady)",
31
- "Konstantin Tarkus (https://github.com/koistya)",
32
- "Kyle Farnung (https://github.com/kfarnung)",
33
- "Luciano Martorella (https://github.com/lmartorella)",
34
- "Matteo Collina (https://github.com/mcollina)",
35
- "Michael Dawson (https://github.com/mhdawson)",
36
- "Michele Campus (https://github.com/kYroL01)",
37
- "Mikhail Cheshkov (https://github.com/mcheshkov)",
38
- "Nicola Del Gobbo (https://github.com/NickNaso)",
39
- "Nick Soggin (https://github.com/iSkore)",
40
- "Philipp Renoth (https://github.com/DaAitch)",
41
- "Rolf Timmermans (https://github.com/rolftimmermans)",
42
- "Ross Weir (https://github.com/ross-weir)",
43
- "Ryuichi Okumura (https://github.com/okuryu)",
44
- "Sampson Gao (https://github.com/sampsongao)",
45
- "Sam Roberts (https://github.com/sam-github)",
46
- "Taylor Woll (https://github.com/boingoing)",
47
- "Thomas Gentilhomme (https://github.com/fraxken)",
48
- "Tux3 (https://github.com/tux3)",
49
- "Yohei Kishimoto (https://github.com/morokosi)"
6
+ {
7
+ "name": "Abhishek Kumar Singh",
8
+ "url": "https://github.com/abhi11210646"
9
+ },
10
+ {
11
+ "name": "Alba Mendez",
12
+ "url": "https://github.com/jmendeth"
13
+ },
14
+ {
15
+ "name": "Andrew Petersen",
16
+ "url": "https://github.com/kirbysayshi"
17
+ },
18
+ {
19
+ "name": "Anisha Rohra",
20
+ "url": "https://github.com/anisha-rohra"
21
+ },
22
+ {
23
+ "name": "Anna Henningsen",
24
+ "url": "https://github.com/addaleax"
25
+ },
26
+ {
27
+ "name": "Arnaud Botella",
28
+ "url": "https://github.com/BotellaA"
29
+ },
30
+ {
31
+ "name": "Arunesh Chandra",
32
+ "url": "https://github.com/aruneshchandra"
33
+ },
34
+ {
35
+ "name": "Ben Berman",
36
+ "url": "https://github.com/rivertam"
37
+ },
38
+ {
39
+ "name": "Benjamin Byholm",
40
+ "url": "https://github.com/kkoopa"
41
+ },
42
+ {
43
+ "name": "Bill Gallafent",
44
+ "url": "https://github.com/gallafent"
45
+ },
46
+ {
47
+ "name": "Bruce A. MacNaughton",
48
+ "url": "https://github.com/bmacnaughton"
49
+ },
50
+ {
51
+ "name": "Cory Mickelson",
52
+ "url": "https://github.com/corymickelson"
53
+ },
54
+ {
55
+ "name": "David Halls",
56
+ "url": "https://github.com/davedoesdev"
57
+ },
58
+ {
59
+ "name": "Dongjin Na",
60
+ "url": "https://github.com/nadongguri"
61
+ },
62
+ {
63
+ "name": "Eric Bickle",
64
+ "url": "https://github.com/ebickle"
65
+ },
66
+ {
67
+ "name": "Gabriel Schulhof",
68
+ "url": "https://github.com/gabrielschulhof"
69
+ },
70
+ {
71
+ "name": "Gus Caplan",
72
+ "url": "https://github.com/devsnek"
73
+ },
74
+ {
75
+ "name": "Hitesh Kanwathirtha",
76
+ "url": "https://github.com/digitalinfinity"
77
+ },
78
+ {
79
+ "name": "Jake Barnes",
80
+ "url": "https://github.com/DuBistKomisch"
81
+ },
82
+ {
83
+ "name": "Jake Yoon",
84
+ "url": "https://github.com/yjaeseok"
85
+ },
86
+ {
87
+ "name": "Jason Ginchereau",
88
+ "url": "https://github.com/jasongin"
89
+ },
90
+ {
91
+ "name": "Jim Schlight",
92
+ "url": "https://github.com/jschlight"
93
+ },
94
+ {
95
+ "name": "Jinho Bang",
96
+ "url": "https://github.com/romandev"
97
+ },
98
+ {
99
+ "name": "joshgarde",
100
+ "url": "https://github.com/joshgarde"
101
+ },
102
+ {
103
+ "name": "Kevin Eady",
104
+ "url": "https://github.com/KevinEady"
105
+ },
106
+ {
107
+ "name": "Konstantin Tarkus",
108
+ "url": "https://github.com/koistya"
109
+ },
110
+ {
111
+ "name": "Kyle Farnung",
112
+ "url": "https://github.com/kfarnung"
113
+ },
114
+ {
115
+ "name": "legendecas",
116
+ "url": "https://github.com/legendecas"
117
+ },
118
+ {
119
+ "name": "Luciano Martorella",
120
+ "url": "https://github.com/lmartorella"
121
+ },
122
+ {
123
+ "name": "Mathias Küsel",
124
+ "url": "https://github.com/mathiask88"
125
+ },
126
+ {
127
+ "name": "Matteo Collina",
128
+ "url": "https://github.com/mcollina"
129
+ },
130
+ {
131
+ "name": "Michael Dawson",
132
+ "url": "https://github.com/mhdawson"
133
+ },
134
+ {
135
+ "name": "Michael Price",
136
+ "url": "https://github.com/mikepricedev"
137
+ },
138
+ {
139
+ "name": "Michele Campus",
140
+ "url": "https://github.com/kYroL01"
141
+ },
142
+ {
143
+ "name": "Mikhail Cheshkov",
144
+ "url": "https://github.com/mcheshkov"
145
+ },
146
+ {
147
+ "name": "Nicola Del Gobbo",
148
+ "url": "https://github.com/NickNaso"
149
+ },
150
+ {
151
+ "name": "Nick Soggin",
152
+ "url": "https://github.com/iSkore"
153
+ },
154
+ {
155
+ "name": "Nurbol Alpysbayev",
156
+ "url": "https://github.com/anurbol"
157
+ },
158
+ {
159
+ "name": "Philipp Renoth",
160
+ "url": "https://github.com/DaAitch"
161
+ },
162
+ {
163
+ "name": "Rolf Timmermans",
164
+ "url": "https://github.com/rolftimmermans"
165
+ },
166
+ {
167
+ "name": "Ross Weir",
168
+ "url": "https://github.com/ross-weir"
169
+ },
170
+ {
171
+ "name": "Ryuichi Okumura",
172
+ "url": "https://github.com/okuryu"
173
+ },
174
+ {
175
+ "name": "Sampson Gao",
176
+ "url": "https://github.com/sampsongao"
177
+ },
178
+ {
179
+ "name": "Sam Roberts",
180
+ "url": "https://github.com/sam-github"
181
+ },
182
+ {
183
+ "name": "Taylor Woll",
184
+ "url": "https://github.com/boingoing"
185
+ },
186
+ {
187
+ "name": "Thomas Gentilhomme",
188
+ "url": "https://github.com/fraxken"
189
+ },
190
+ {
191
+ "name": "Tim Rach",
192
+ "url": "https://github.com/timrach"
193
+ },
194
+ {
195
+ "name": "Tobias Nießen",
196
+ "url": "https://github.com/tniessen"
197
+ },
198
+ {
199
+ "name": "Tux3",
200
+ "url": "https://github.com/tux3"
201
+ },
202
+ {
203
+ "name": "Yohei Kishimoto",
204
+ "url": "https://github.com/morokosi"
205
+ }
50
206
  ],
51
207
  "dependencies": {},
52
208
  "description": "Node.js API (N-API)",
@@ -55,7 +211,17 @@
55
211
  },
56
212
  "directories": {},
57
213
  "homepage": "https://github.com/nodejs/node-addon-api",
58
- "keywords": ["n-api", "napi", "addon", "native", "bindings", "c", "c++", "nan", "node-addon-api"],
214
+ "keywords": [
215
+ "n-api",
216
+ "napi",
217
+ "addon",
218
+ "native",
219
+ "bindings",
220
+ "c",
221
+ "c++",
222
+ "nan",
223
+ "node-addon-api"
224
+ ],
59
225
  "license": "MIT",
60
226
  "main": "index.js",
61
227
  "name": "node-addon-api",
@@ -74,5 +240,5 @@
74
240
  "dev:incremental": "node test",
75
241
  "doc": "doxygen doc/Doxyfile"
76
242
  },
77
- "version": "1.7.1"
243
+ "version": "2.0.2"
78
244
  }
package/src/node_api.cc CHANGED
@@ -2238,7 +2238,7 @@ napi_status napi_get_value_string_latin1(napi_env env,
2238
2238
  if (!buf) {
2239
2239
  CHECK_ARG(env, result);
2240
2240
  *result = val.As<v8::String>()->Length();
2241
- } else {
2241
+ } else if (bufsize != 0) {
2242
2242
  int copied = val.As<v8::String>()->WriteOneByte(
2243
2243
  reinterpret_cast<uint8_t*>(buf), 0, bufsize - 1,
2244
2244
  v8::String::NO_NULL_TERMINATION);
@@ -2247,6 +2247,8 @@ napi_status napi_get_value_string_latin1(napi_env env,
2247
2247
  if (result != nullptr) {
2248
2248
  *result = copied;
2249
2249
  }
2250
+ } else if (result != nullptr) {
2251
+ *result = 0;
2250
2252
  }
2251
2253
 
2252
2254
  return napi_clear_last_error(env);
@@ -2274,7 +2276,7 @@ napi_status napi_get_value_string_utf8(napi_env env,
2274
2276
  if (!buf) {
2275
2277
  CHECK_ARG(env, result);
2276
2278
  *result = val.As<v8::String>()->Utf8Length();
2277
- } else {
2279
+ } else if (bufsize != 0) {
2278
2280
  int copied = val.As<v8::String>()->WriteUtf8(
2279
2281
  buf, bufsize - 1, nullptr, v8::String::REPLACE_INVALID_UTF8 |
2280
2282
  v8::String::NO_NULL_TERMINATION);
@@ -2283,6 +2285,8 @@ napi_status napi_get_value_string_utf8(napi_env env,
2283
2285
  if (result != nullptr) {
2284
2286
  *result = copied;
2285
2287
  }
2288
+ } else if (result != nullptr) {
2289
+ *result = 0;
2286
2290
  }
2287
2291
 
2288
2292
  return napi_clear_last_error(env);
@@ -2311,7 +2315,7 @@ napi_status napi_get_value_string_utf16(napi_env env,
2311
2315
  CHECK_ARG(env, result);
2312
2316
  // V8 assumes UTF-16 length is the same as the number of characters.
2313
2317
  *result = val.As<v8::String>()->Length();
2314
- } else {
2318
+ } else if (bufsize != 0) {
2315
2319
  int copied = val.As<v8::String>()->Write(
2316
2320
  reinterpret_cast<uint16_t*>(buf), 0, bufsize - 1,
2317
2321
  v8::String::NO_NULL_TERMINATION);
@@ -2320,6 +2324,8 @@ napi_status napi_get_value_string_utf16(napi_env env,
2320
2324
  if (result != nullptr) {
2321
2325
  *result = copied;
2322
2326
  }
2327
+ } else if (result != nullptr) {
2328
+ *result = 0;
2323
2329
  }
2324
2330
 
2325
2331
  return napi_clear_last_error(env);