Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

Commit 7b35642

Browse files
addaleaxdeepak1556
authored andcommitted
buffer: throw exception when creating from non-Node.js Context
Throw an exception instead of crashing when attempting to create `Buffer` objects from a Context that is not associated with a Node.js `Environment`. Possible alternatives for the future might be just returning a plain `Uint8Array`, or working on providing `Buffer` for all `Context`s. PR-URL: nodejs/node#23938 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]>
1 parent b2ed6c3 commit 7b35642

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

doc/api/errors.md

+13
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,19 @@ An attempt was made to register something that is not a function as an
613613
The type of an asynchronous resource was invalid. Note that users are also able
614614
to define their own types if using the public embedder API.
615615

616+
<a id="ERR_BUFFER_CONTEXT_NOT_AVAILABLE"></a>
617+
### ERR_BUFFER_CONTEXT_NOT_AVAILABLE
618+
619+
An attempt was made to create a Node.js `Buffer` instance from addon or embedder
620+
code, while in a JS engine Context that is not associated with a Node.js
621+
instance. The data passed to the `Buffer` method will have been released
622+
by the time the method returns.
623+
624+
When encountering this error, a possible alternative to creating a `Buffer`
625+
instance is to create a normal `Uint8Array`, which only differs in the
626+
prototype of the resulting object. `Uint8Array`s are generally accepted in all
627+
Node.js core APIs where `Buffer`s are; they are available in all Contexts.
628+
616629
<a id="ERR_BUFFER_OUT_OF_BOUNDS"></a>
617630
### ERR_BUFFER_OUT_OF_BOUNDS
618631

src/node_buffer.cc

+18-4
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,10 @@ MaybeLocal<Object> New(Isolate* isolate, size_t length) {
256256
EscapableHandleScope handle_scope(isolate);
257257
Local<Object> obj;
258258
Environment* env = Environment::GetCurrent(isolate);
259-
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
259+
if (env == nullptr) {
260+
THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate);
261+
return MaybeLocal<Object>();
262+
}
260263
if (Buffer::New(env, length).ToLocal(&obj))
261264
return handle_scope.Escape(obj);
262265
return Local<Object>();
@@ -287,7 +290,10 @@ MaybeLocal<Object> New(Environment* env, size_t length) {
287290
MaybeLocal<Object> Copy(Isolate* isolate, const char* data, size_t length) {
288291
EscapableHandleScope handle_scope(isolate);
289292
Environment* env = Environment::GetCurrent(isolate);
290-
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
293+
if (env == nullptr) {
294+
THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate);
295+
return MaybeLocal<Object>();
296+
}
291297
Local<Object> obj;
292298
if (Buffer::Copy(env, data, length).ToLocal(&obj))
293299
return handle_scope.Escape(obj);
@@ -325,7 +331,11 @@ MaybeLocal<Object> New(Isolate* isolate,
325331
void* hint) {
326332
EscapableHandleScope handle_scope(isolate);
327333
Environment* env = Environment::GetCurrent(isolate);
328-
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
334+
if (env == nullptr) {
335+
callback(data, hint);
336+
THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate);
337+
return MaybeLocal<Object>();
338+
}
329339
Local<Object> obj;
330340
if (Buffer::New(env, data, length, callback, hint).ToLocal(&obj))
331341
return handle_scope.Escape(obj);
@@ -365,7 +375,11 @@ MaybeLocal<Object> New(Environment* env,
365375
MaybeLocal<Object> New(Isolate* isolate, char* data, size_t length) {
366376
EscapableHandleScope handle_scope(isolate);
367377
Environment* env = Environment::GetCurrent(isolate);
368-
CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
378+
if (env == nullptr) {
379+
free(data);
380+
THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate);
381+
return MaybeLocal<Object>();
382+
}
369383
Local<Object> obj;
370384
if (Buffer::New(env, data, length, true).ToLocal(&obj))
371385
return handle_scope.Escape(obj);

src/node_errors.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace node {
1717
// a `Local<Value>` containing the TypeError with proper code and message
1818

1919
#define ERRORS_WITH_CODE(V) \
20+
V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, Error) \
2021
V(ERR_BUFFER_OUT_OF_BOUNDS, RangeError) \
2122
V(ERR_BUFFER_TOO_LARGE, Error) \
2223
V(ERR_CANNOT_TRANSFER_OBJECT, TypeError) \
@@ -55,6 +56,8 @@ namespace node {
5556
// Errors with predefined static messages
5657

5758
#define PREDEFINED_ERROR_MESSAGES(V) \
59+
V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, \
60+
"Buffer is not available for the current Context") \
5861
V(ERR_CANNOT_TRANSFER_OBJECT, "Cannot transfer object of unsupported type")\
5962
V(ERR_CLOSED_MESSAGE_PORT, "Cannot send data on closed MessagePort") \
6063
V(ERR_CONSTRUCT_CALL_REQUIRED, "Cannot call constructor without `new`") \
@@ -73,8 +76,11 @@ namespace node {
7376
inline v8::Local<v8::Value> code(v8::Isolate* isolate) { \
7477
return code(isolate, message); \
7578
} \
79+
inline void THROW_ ## code(v8::Isolate* isolate) { \
80+
isolate->ThrowException(code(isolate, message)); \
81+
} \
7682
inline void THROW_ ## code(Environment* env) { \
77-
env->isolate()->ThrowException(code(env->isolate(), message)); \
83+
THROW_ ## code(env->isolate()); \
7884
}
7985
PREDEFINED_ERROR_MESSAGES(V)
8086
#undef V

0 commit comments

Comments
 (0)