28
28
// See https://github.com/libuv/libuv/pull/1501.
29
29
const kIoMaxLength = 2 ** 31 - 1 ;
30
30
31
+ // When using FSReqCallback, make sure to create the object only *after* all
32
+ // parameter validation has happened, so that the objects are not kept in memory
33
+ // in case they are created but never used due to an exception.
34
+
31
35
const {
32
36
Map,
33
37
MathMax,
@@ -198,8 +202,10 @@ function access(path, mode, callback) {
198
202
199
203
path = getValidatedPath ( path ) ;
200
204
mode = getValidMode ( mode , 'access' ) ;
205
+ callback = makeCallback ( callback ) ;
206
+
201
207
const req = new FSReqCallback ( ) ;
202
- req . oncomplete = makeCallback ( callback ) ;
208
+ req . oncomplete = callback ;
203
209
binding . access ( pathModule . toNamespacedPath ( path ) , mode , req ) ;
204
210
}
205
211
@@ -307,19 +313,19 @@ function readFile(path, options, callback) {
307
313
const context = new ReadFileContext ( callback , options . encoding ) ;
308
314
context . isUserFd = isFd ( path ) ; // File descriptor ownership
309
315
310
- const req = new FSReqCallback ( ) ;
311
- req . context = context ;
312
- req . oncomplete = readFileAfterOpen ;
313
-
314
316
if ( context . isUserFd ) {
315
- process . nextTick ( function tick ( ) {
316
- req . oncomplete ( null , path ) ;
317
- } ) ;
317
+ process . nextTick ( function tick ( context ) {
318
+ readFileAfterOpen . call ( { context } , null , path ) ;
319
+ } , context ) ;
318
320
return ;
319
321
}
320
322
321
- path = getValidatedPath ( path ) ;
322
323
const flagsNumber = stringToFlags ( options . flags ) ;
324
+ path = getValidatedPath ( path ) ;
325
+
326
+ const req = new FSReqCallback ( ) ;
327
+ req . context = context ;
328
+ req . oncomplete = readFileAfterOpen ;
323
329
binding . open ( pathModule . toNamespacedPath ( path ) ,
324
330
flagsNumber ,
325
331
0o666 ,
@@ -416,8 +422,10 @@ function readFileSync(path, options) {
416
422
417
423
function close ( fd , callback ) {
418
424
validateInt32 ( fd , 'fd' , 0 ) ;
425
+ callback = makeCallback ( callback ) ;
426
+
419
427
const req = new FSReqCallback ( ) ;
420
- req . oncomplete = makeCallback ( callback ) ;
428
+ req . oncomplete = callback ;
421
429
binding . close ( fd , req ) ;
422
430
}
423
431
@@ -590,12 +598,11 @@ function readv(fd, buffers, position, callback) {
590
598
591
599
validateInt32 ( fd , 'fd' , /* min */ 0 ) ;
592
600
validateBufferArray ( buffers ) ;
601
+ callback = maybeCallback ( callback || position ) ;
593
602
594
603
const req = new FSReqCallback ( ) ;
595
604
req . oncomplete = wrapper ;
596
605
597
- callback = maybeCallback ( callback || position ) ;
598
-
599
606
if ( typeof position !== 'number' )
600
607
position = null ;
601
608
@@ -712,12 +719,11 @@ function writev(fd, buffers, position, callback) {
712
719
713
720
validateInt32 ( fd , 'fd' , 0 ) ;
714
721
validateBufferArray ( buffers ) ;
722
+ callback = maybeCallback ( callback || position ) ;
715
723
716
724
const req = new FSReqCallback ( ) ;
717
725
req . oncomplete = wrapper ;
718
726
719
- callback = maybeCallback ( callback || position ) ;
720
-
721
727
if ( typeof position !== 'number' )
722
728
position = null ;
723
729
@@ -819,8 +825,10 @@ function ftruncate(fd, len = 0, callback) {
819
825
validateInt32 ( fd , 'fd' , 0 ) ;
820
826
validateInteger ( len , 'len' ) ;
821
827
len = MathMax ( 0 , len ) ;
828
+ callback = makeCallback ( callback ) ;
829
+
822
830
const req = new FSReqCallback ( ) ;
823
- req . oncomplete = makeCallback ( callback ) ;
831
+ req . oncomplete = callback ;
824
832
binding . ftruncate ( fd , len , req ) ;
825
833
}
826
834
@@ -989,8 +997,10 @@ function fstat(fd, options = { bigint: false }, callback) {
989
997
options = { } ;
990
998
}
991
999
validateInt32 ( fd , 'fd' , 0 ) ;
1000
+ callback = makeStatsCallback ( callback ) ;
1001
+
992
1002
const req = new FSReqCallback ( options . bigint ) ;
993
- req . oncomplete = makeStatsCallback ( callback ) ;
1003
+ req . oncomplete = callback ;
994
1004
binding . fstat ( fd , options . bigint , req ) ;
995
1005
}
996
1006
@@ -1001,6 +1011,7 @@ function lstat(path, options = { bigint: false }, callback) {
1001
1011
}
1002
1012
callback = makeStatsCallback ( callback ) ;
1003
1013
path = getValidatedPath ( path ) ;
1014
+
1004
1015
const req = new FSReqCallback ( options . bigint ) ;
1005
1016
req . oncomplete = callback ;
1006
1017
binding . lstat ( pathModule . toNamespacedPath ( path ) , options . bigint , req ) ;
@@ -1013,6 +1024,7 @@ function stat(path, options = { bigint: false }, callback) {
1013
1024
}
1014
1025
callback = makeStatsCallback ( callback ) ;
1015
1026
path = getValidatedPath ( path ) ;
1027
+
1016
1028
const req = new FSReqCallback ( options . bigint ) ;
1017
1029
req . oncomplete = callback ;
1018
1030
binding . stat ( pathModule . toNamespacedPath ( path ) , options . bigint , req ) ;
@@ -1070,9 +1082,6 @@ function symlink(target, path, type_, callback_) {
1070
1082
target = getValidatedPath ( target , 'target' ) ;
1071
1083
path = getValidatedPath ( path ) ;
1072
1084
1073
- const req = new FSReqCallback ( ) ;
1074
- req . oncomplete = callback ;
1075
-
1076
1085
if ( isWindows && type === null ) {
1077
1086
let absoluteTarget ;
1078
1087
try {
@@ -1087,18 +1096,25 @@ function symlink(target, path, type_, callback_) {
1087
1096
stat ( absoluteTarget , ( err , stat ) => {
1088
1097
const resolvedType = ! err && stat . isDirectory ( ) ? 'dir' : 'file' ;
1089
1098
const resolvedFlags = stringToSymlinkType ( resolvedType ) ;
1090
- binding . symlink ( preprocessSymlinkDestination ( target ,
1091
- resolvedType ,
1092
- path ) ,
1099
+ const destination = preprocessSymlinkDestination ( target ,
1100
+ resolvedType ,
1101
+ path ) ;
1102
+
1103
+ const req = new FSReqCallback ( ) ;
1104
+ req . oncomplete = callback ;
1105
+ binding . symlink ( destination ,
1093
1106
pathModule . toNamespacedPath ( path ) , resolvedFlags , req ) ;
1094
1107
} ) ;
1095
1108
return ;
1096
1109
}
1097
1110
}
1098
1111
1112
+ const destination = preprocessSymlinkDestination ( target , type , path ) ;
1113
+
1099
1114
const flags = stringToSymlinkType ( type ) ;
1100
- binding . symlink ( preprocessSymlinkDestination ( target , type , path ) ,
1101
- pathModule . toNamespacedPath ( path ) , flags , req ) ;
1115
+ const req = new FSReqCallback ( ) ;
1116
+ req . oncomplete = callback ;
1117
+ binding . symlink ( destination , pathModule . toNamespacedPath ( path ) , flags , req ) ;
1102
1118
}
1103
1119
1104
1120
function symlinkSync ( target , path , type ) {
@@ -1255,9 +1271,10 @@ function fchown(fd, uid, gid, callback) {
1255
1271
validateInt32 ( fd , 'fd' , 0 ) ;
1256
1272
validateInteger ( uid , 'uid' , - 1 , kMaxUserId ) ;
1257
1273
validateInteger ( gid , 'gid' , - 1 , kMaxUserId ) ;
1274
+ callback = makeCallback ( callback ) ;
1258
1275
1259
1276
const req = new FSReqCallback ( ) ;
1260
- req . oncomplete = makeCallback ( callback ) ;
1277
+ req . oncomplete = callback ;
1261
1278
binding . fchown ( fd , uid , gid , req ) ;
1262
1279
}
1263
1280
@@ -1316,8 +1333,10 @@ function futimes(fd, atime, mtime, callback) {
1316
1333
validateInt32 ( fd , 'fd' , 0 ) ;
1317
1334
atime = toUnixTimestamp ( atime , 'atime' ) ;
1318
1335
mtime = toUnixTimestamp ( mtime , 'mtime' ) ;
1336
+ callback = makeCallback ( callback ) ;
1337
+
1319
1338
const req = new FSReqCallback ( ) ;
1320
- req . oncomplete = makeCallback ( callback ) ;
1339
+ req . oncomplete = callback ;
1321
1340
binding . futimes ( fd , atime , mtime , req ) ;
1322
1341
}
1323
1342
@@ -1920,8 +1939,10 @@ function copyFile(src, dest, mode, callback) {
1920
1939
src = pathModule . _makeLong ( src ) ;
1921
1940
dest = pathModule . _makeLong ( dest ) ;
1922
1941
mode = getValidMode ( mode , 'copyFile' ) ;
1942
+ callback = makeCallback ( callback ) ;
1943
+
1923
1944
const req = new FSReqCallback ( ) ;
1924
- req . oncomplete = makeCallback ( callback ) ;
1945
+ req . oncomplete = callback ;
1925
1946
binding . copyFile ( src , dest , mode , req ) ;
1926
1947
}
1927
1948
0 commit comments