@@ -110,20 +110,29 @@ typedef void(*uv_fs_callback_t)(uv_fs_t*);
110
110
// The FileHandle object wraps a file descriptor and will close it on garbage
111
111
// collection if necessary. If that happens, a process warning will be
112
112
// emitted (or a fatal exception will occur if the fd cannot be closed.)
113
- FileHandle::FileHandle (Environment* env, int fd, Local<Object> obj)
114
- : AsyncWrap(env,
115
- obj.IsEmpty() ? env->fd_constructor_template ()
116
- ->NewInstance(env->context ()).ToLocalChecked() : obj,
117
- AsyncWrap::PROVIDER_FILEHANDLE),
113
+ FileHandle::FileHandle (Environment* env, Local<Object> obj, int fd)
114
+ : AsyncWrap(env, obj, AsyncWrap::PROVIDER_FILEHANDLE),
118
115
StreamBase (env),
119
116
fd_(fd) {
120
117
MakeWeak ();
118
+ }
119
+
120
+ FileHandle* FileHandle::New (Environment* env, int fd, Local<Object> obj) {
121
+ if (obj.IsEmpty () && !env->fd_constructor_template ()
122
+ ->NewInstance (env->context ())
123
+ .ToLocal (&obj)) {
124
+ return nullptr ;
125
+ }
121
126
v8::PropertyAttribute attr =
122
127
static_cast <v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
123
- object ()->DefineOwnProperty (env->context (),
124
- FIXED_ONE_BYTE_STRING (env->isolate (), " fd" ),
125
- Integer::New (env->isolate (), fd),
126
- attr).FromJust ();
128
+ if (obj->DefineOwnProperty (env->context (),
129
+ env->fd_string (),
130
+ Integer::New (env->isolate (), fd),
131
+ attr)
132
+ .IsNothing ()) {
133
+ return nullptr ;
134
+ }
135
+ return new FileHandle (env, obj, fd);
127
136
}
128
137
129
138
void FileHandle::New (const FunctionCallbackInfo<Value>& args) {
@@ -132,7 +141,8 @@ void FileHandle::New(const FunctionCallbackInfo<Value>& args) {
132
141
CHECK (args[0 ]->IsInt32 ());
133
142
134
143
FileHandle* handle =
135
- new FileHandle (env, args[0 ].As <Int32>()->Value (), args.This ());
144
+ FileHandle::New (env, args[0 ].As <Int32>()->Value (), args.This ());
145
+ if (handle == nullptr ) return ;
136
146
if (args[1 ]->IsNumber ())
137
147
handle->read_offset_ = args[1 ]->IntegerValue (env->context ()).FromJust ();
138
148
if (args[2 ]->IsNumber ())
@@ -232,7 +242,14 @@ inline MaybeLocal<Promise> FileHandle::ClosePromise() {
232
242
CHECK (!reading_);
233
243
if (!closed_ && !closing_) {
234
244
closing_ = true ;
235
- CloseReq* req = new CloseReq (env (), promise, object ());
245
+ Local<Object> close_req_obj;
246
+ if (!env ()
247
+ ->fdclose_constructor_template ()
248
+ ->NewInstance (env ()->context ())
249
+ .ToLocal (&close_req_obj)) {
250
+ return MaybeLocal<Promise>();
251
+ }
252
+ CloseReq* req = new CloseReq (env (), close_req_obj, promise, object ());
236
253
auto AfterClose = uv_fs_callback_t {[](uv_fs_t * req) {
237
254
std::unique_ptr<CloseReq> close (CloseReq::from_req (req));
238
255
CHECK_NOT_NULL (close );
@@ -260,7 +277,9 @@ inline MaybeLocal<Promise> FileHandle::ClosePromise() {
260
277
void FileHandle::Close (const FunctionCallbackInfo<Value>& args) {
261
278
FileHandle* fd;
262
279
ASSIGN_OR_RETURN_UNWRAP (&fd, args.Holder ());
263
- args.GetReturnValue ().Set (fd->ClosePromise ().ToLocalChecked ());
280
+ Local<Promise> ret;
281
+ if (!fd->ClosePromise ().ToLocal (&ret)) return ;
282
+ args.GetReturnValue ().Set (ret);
264
283
}
265
284
266
285
@@ -318,8 +337,13 @@ int FileHandle::ReadStart() {
318
337
read_wrap->AsyncReset ();
319
338
read_wrap->file_handle_ = this ;
320
339
} else {
321
- Local<Object> wrap_obj = env ()->filehandlereadwrap_template ()
322
- ->NewInstance (env ()->context ()).ToLocalChecked ();
340
+ Local<Object> wrap_obj;
341
+ if (!env ()
342
+ ->filehandlereadwrap_template ()
343
+ ->NewInstance (env ()->context ())
344
+ .ToLocal (&wrap_obj)) {
345
+ return UV_EBUSY;
346
+ }
323
347
read_wrap.reset (new FileHandleReadWrap (this , wrap_obj));
324
348
}
325
349
}
@@ -520,7 +544,8 @@ void AfterOpenFileHandle(uv_fs_t* req) {
520
544
FSReqAfterScope after (req_wrap, req);
521
545
522
546
if (after.Proceed ()) {
523
- FileHandle* fd = new FileHandle (req_wrap->env (), req->result );
547
+ FileHandle* fd = FileHandle::New (req_wrap->env (), req->result );
548
+ if (fd == nullptr ) return ;
524
549
req_wrap->Resolve (fd->object ());
525
550
}
526
551
}
@@ -724,15 +749,18 @@ inline int SyncCall(Environment* env, Local<Value> ctx, FSReqWrapSync* req_wrap,
724
749
return err;
725
750
}
726
751
752
+ // TODO(addaleax): Currently, callers check the return value and assume
753
+ // that nullptr indicates a synchronous call, rather than a failure.
754
+ // Failure conditions should be disambiguated and handled appropriately.
727
755
inline FSReqBase* GetReqWrap (Environment* env, Local<Value> value,
728
756
bool use_bigint = false ) {
729
757
if (value->IsObject ()) {
730
758
return Unwrap<FSReqBase>(value.As <Object>());
731
759
} else if (value->StrictEquals (env->fs_use_promises_symbol ())) {
732
760
if (use_bigint) {
733
- return new FSReqPromise<uint64_t , BigUint64Array>(env, use_bigint);
761
+ return FSReqPromise<uint64_t , BigUint64Array>:: New (env, use_bigint);
734
762
} else {
735
- return new FSReqPromise<double , Float64Array>(env, use_bigint);
763
+ return FSReqPromise<double , Float64Array>:: New (env, use_bigint);
736
764
}
737
765
}
738
766
return nullptr ;
@@ -1562,8 +1590,8 @@ static void OpenFileHandle(const FunctionCallbackInfo<Value>& args) {
1562
1590
if (result < 0 ) {
1563
1591
return ; // syscall failed, no need to continue, error info is in ctx
1564
1592
}
1565
- HandleScope scope (isolate );
1566
- FileHandle* fd = new FileHandle (env, result) ;
1593
+ FileHandle* fd = FileHandle::New (env, result );
1594
+ if ( fd == nullptr ) return ;
1567
1595
args.GetReturnValue ().Set (fd->object ());
1568
1596
}
1569
1597
}
0 commit comments