@@ -636,12 +636,22 @@ fs.readFileSync = function(path, options) {
636636} ;
637637
638638fs . close = function ( fd , callback ) {
639- var req = new FSReqWrap ( ) ;
639+ if ( ! Number . isInteger ( fd ) )
640+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
641+ if ( fd < 0 || fd > 0xFFFFFFFF )
642+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
643+
644+ const req = new FSReqWrap ( ) ;
640645 req . oncomplete = makeCallback ( callback ) ;
641646 binding . close ( fd , req ) ;
642647} ;
643648
644649fs . closeSync = function ( fd ) {
650+ if ( ! Number . isInteger ( fd ) )
651+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
652+ if ( fd < 0 || fd > 0xFFFFFFFF )
653+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
654+
645655 return binding . close ( fd ) ;
646656} ;
647657
@@ -681,18 +691,38 @@ fs.openSync = function(path, flags, mode) {
681691} ;
682692
683693fs . read = function ( fd , buffer , offset , length , position , callback ) {
694+ if ( ! Number . isInteger ( fd ) )
695+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
696+ if ( fd < 0 || fd > 0xFFFFFFFF )
697+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
698+ if ( ! isUint8Array ( buffer ) )
699+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'buffer' ,
700+ [ 'Buffer' , 'Uint8Array' ] ) ;
701+
702+ offset |= 0 ;
703+ length |= 0 ;
704+
684705 if ( length === 0 ) {
685706 return process . nextTick ( function ( ) {
686707 callback && callback ( null , 0 , buffer ) ;
687708 } ) ;
688709 }
689710
711+ if ( offset < 0 || offset >= buffer . length )
712+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'offset' ) ;
713+
714+ if ( length < 0 || offset + length > buffer . length )
715+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'length' ) ;
716+
717+ if ( ! Number . isInteger ( position ) )
718+ position = - 1 ;
719+
690720 function wrapper ( err , bytesRead ) {
691721 // Retain a reference to buffer so that it can't be GC'ed too soon.
692722 callback && callback ( err , bytesRead || 0 , buffer ) ;
693723 }
694724
695- var req = new FSReqWrap ( ) ;
725+ const req = new FSReqWrap ( ) ;
696726 req . oncomplete = wrapper ;
697727
698728 binding . read ( fd , buffer , offset , length , position , req ) ;
@@ -702,10 +732,30 @@ Object.defineProperty(fs.read, internalUtil.customPromisifyArgs,
702732 { value : [ 'bytesRead' , 'buffer' ] , enumerable : false } ) ;
703733
704734fs . readSync = function ( fd , buffer , offset , length , position ) {
735+ if ( ! Number . isInteger ( fd ) )
736+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
737+ if ( fd < 0 || fd > 0xFFFFFFFF )
738+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
739+ if ( ! isUint8Array ( buffer ) )
740+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'buffer' ,
741+ [ 'Buffer' , 'Uint8Array' ] ) ;
742+
743+ offset |= 0 ;
744+ length |= 0 ;
745+
705746 if ( length === 0 ) {
706747 return 0 ;
707748 }
708749
750+ if ( offset < 0 || offset >= buffer . length )
751+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'offset' ) ;
752+
753+ if ( length < 0 || offset + length > buffer . length )
754+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'length' ) ;
755+
756+ if ( ! Number . isInteger ( position ) )
757+ position = - 1 ;
758+
709759 return binding . read ( fd , buffer , offset , length , position ) ;
710760} ;
711761
@@ -854,7 +904,14 @@ fs.ftruncate = function(fd, len, callback) {
854904 } else if ( len === undefined ) {
855905 len = 0 ;
856906 }
857- var req = new FSReqWrap ( ) ;
907+ if ( ! Number . isInteger ( fd ) )
908+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
909+ if ( fd < 0 || fd > 0xFFFFFFFF )
910+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
911+ if ( ! Number . isInteger ( len ) )
912+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'len' , 'number' ) ;
913+ len = Math . max ( 0 , len ) ;
914+ const req = new FSReqWrap ( ) ;
858915 req . oncomplete = makeCallback ( callback ) ;
859916 binding . ftruncate ( fd , len , req ) ;
860917} ;
@@ -863,6 +920,13 @@ fs.ftruncateSync = function(fd, len) {
863920 if ( len === undefined ) {
864921 len = 0 ;
865922 }
923+ if ( ! Number . isInteger ( fd ) )
924+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
925+ if ( fd < 0 || fd > 0xFFFFFFFF )
926+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
927+ if ( ! Number . isInteger ( len ) )
928+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'len' , 'number' ) ;
929+ len = Math . max ( 0 , len ) ;
866930 return binding . ftruncate ( fd , len ) ;
867931} ;
868932
@@ -883,22 +947,38 @@ fs.rmdirSync = function(path) {
883947} ;
884948
885949fs . fdatasync = function ( fd , callback ) {
886- var req = new FSReqWrap ( ) ;
950+ if ( ! Number . isInteger ( fd ) )
951+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
952+ if ( fd < 0 || fd > 0xFFFFFFFF )
953+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
954+ const req = new FSReqWrap ( ) ;
887955 req . oncomplete = makeCallback ( callback ) ;
888956 binding . fdatasync ( fd , req ) ;
889957} ;
890958
891959fs . fdatasyncSync = function ( fd ) {
960+ if ( ! Number . isInteger ( fd ) )
961+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
962+ if ( fd < 0 || fd > 0xFFFFFFFF )
963+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
892964 return binding . fdatasync ( fd ) ;
893965} ;
894966
895967fs . fsync = function ( fd , callback ) {
896- var req = new FSReqWrap ( ) ;
968+ if ( ! Number . isInteger ( fd ) )
969+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
970+ if ( fd < 0 || fd > 0xFFFFFFFF )
971+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
972+ const req = new FSReqWrap ( ) ;
897973 req . oncomplete = makeCallback ( callback ) ;
898974 binding . fsync ( fd , req ) ;
899975} ;
900976
901977fs . fsyncSync = function ( fd ) {
978+ if ( ! Number . isInteger ( fd ) )
979+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
980+ if ( fd < 0 || fd > 0xFFFFFFFF )
981+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
902982 return binding . fsync ( fd ) ;
903983} ;
904984
@@ -941,7 +1021,11 @@ fs.readdirSync = function(path, options) {
9411021} ;
9421022
9431023fs . fstat = function ( fd , callback ) {
944- var req = new FSReqWrap ( ) ;
1024+ if ( ! Number . isInteger ( fd ) )
1025+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1026+ if ( fd < 0 || fd > 0xFFFFFFFF )
1027+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
1028+ const req = new FSReqWrap ( ) ;
9451029 req . oncomplete = makeStatsCallback ( callback ) ;
9461030 binding . fstat ( fd , req ) ;
9471031} ;
@@ -967,6 +1051,10 @@ fs.stat = function(path, callback) {
9671051} ;
9681052
9691053fs . fstatSync = function ( fd ) {
1054+ if ( ! Number . isInteger ( fd ) )
1055+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1056+ if ( fd < 0 || fd > 0xFFFFFFFF )
1057+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
9701058 binding . fstat ( fd ) ;
9711059 return statsFromValues ( ) ;
9721060} ;
@@ -1098,13 +1186,32 @@ fs.unlinkSync = function(path) {
10981186} ;
10991187
11001188fs . fchmod = function ( fd , mode , callback ) {
1101- var req = new FSReqWrap ( ) ;
1189+ mode = modeNum ( mode ) ;
1190+ if ( ! Number . isInteger ( fd ) )
1191+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1192+ if ( fd < 0 || fd > 0xFFFFFFFF )
1193+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
1194+ if ( ! Number . isInteger ( mode ) )
1195+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'mode' , 'number' ) ;
1196+ if ( mode < 0 || mode > 0o777 )
1197+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'mode' ) ;
1198+
1199+ const req = new FSReqWrap ( ) ;
11021200 req . oncomplete = makeCallback ( callback ) ;
1103- binding . fchmod ( fd , modeNum ( mode ) , req ) ;
1201+ binding . fchmod ( fd , mode , req ) ;
11041202} ;
11051203
11061204fs . fchmodSync = function ( fd , mode ) {
1107- return binding . fchmod ( fd , modeNum ( mode ) ) ;
1205+ mode = modeNum ( mode ) ;
1206+ if ( ! Number . isInteger ( fd ) )
1207+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1208+ if ( fd < 0 || fd > 0xFFFFFFFF )
1209+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
1210+ if ( ! Number . isInteger ( mode ) )
1211+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'mode' , 'number' ) ;
1212+ if ( mode < 0 || mode > 0o777 )
1213+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'mode' ) ;
1214+ return binding . fchmod ( fd , mode ) ;
11081215} ;
11091216
11101217if ( constants . O_SYMLINK !== undefined ) {
@@ -1182,12 +1289,38 @@ if (constants.O_SYMLINK !== undefined) {
11821289}
11831290
11841291fs . fchown = function ( fd , uid , gid , callback ) {
1185- var req = new FSReqWrap ( ) ;
1292+ if ( ! Number . isInteger ( fd ) )
1293+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1294+ if ( fd < 0 || fd > 0xFFFFFFFF )
1295+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
1296+ if ( ! Number . isInteger ( uid ) )
1297+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'uid' , 'number' ) ;
1298+ if ( uid < 0 )
1299+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'uid' ) ;
1300+ if ( ! Number . isInteger ( gid ) )
1301+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'gid' , 'number' ) ;
1302+ if ( gid < 0 )
1303+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'gid' ) ;
1304+
1305+ const req = new FSReqWrap ( ) ;
11861306 req . oncomplete = makeCallback ( callback ) ;
11871307 binding . fchown ( fd , uid , gid , req ) ;
11881308} ;
11891309
11901310fs . fchownSync = function ( fd , uid , gid ) {
1311+ if ( ! Number . isInteger ( fd ) )
1312+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1313+ if ( fd < 0 || fd > 0xFFFFFFFF )
1314+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
1315+ if ( ! Number . isInteger ( uid ) )
1316+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'uid' , 'number' ) ;
1317+ if ( uid < 0 )
1318+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'uid' ) ;
1319+ if ( ! Number . isInteger ( gid ) )
1320+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'gid' , 'number' ) ;
1321+ if ( gid < 0 )
1322+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'gid' ) ;
1323+
11911324 return binding . fchown ( fd , uid , gid ) ;
11921325} ;
11931326
@@ -1208,7 +1341,7 @@ fs.chownSync = function(path, uid, gid) {
12081341} ;
12091342
12101343// converts Date or number to a fractional UNIX timestamp
1211- function toUnixTimestamp ( time ) {
1344+ function toUnixTimestamp ( time , name = 'time' ) {
12121345 // eslint-disable-next-line eqeqeq
12131346 if ( typeof time === 'string' && + time == time ) {
12141347 return + time ;
@@ -1223,10 +1356,10 @@ function toUnixTimestamp(time) {
12231356 // convert to 123.456 UNIX timestamp
12241357 return time . getTime ( ) / 1000 ;
12251358 }
1226- throw new errors . Error ( 'ERR_INVALID_ARG_TYPE' ,
1227- 'time' ,
1228- [ 'Date' , 'Time in seconds' ] ,
1229- time ) ;
1359+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' ,
1360+ name ,
1361+ [ 'Date' , 'Time in seconds' ] ,
1362+ time ) ;
12301363}
12311364
12321365// exported for unit tests, not for public consumption
@@ -1254,16 +1387,24 @@ fs.utimesSync = function(path, atime, mtime) {
12541387} ;
12551388
12561389fs . futimes = function ( fd , atime , mtime , callback ) {
1257- atime = toUnixTimestamp ( atime ) ;
1258- mtime = toUnixTimestamp ( mtime ) ;
1259- var req = new FSReqWrap ( ) ;
1390+ if ( ! Number . isInteger ( fd ) )
1391+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1392+ if ( fd < 0 || fd > 0xFFFFFFFF )
1393+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
1394+ atime = toUnixTimestamp ( atime , 'atime' ) ;
1395+ mtime = toUnixTimestamp ( mtime , 'mtime' ) ;
1396+ const req = new FSReqWrap ( ) ;
12601397 req . oncomplete = makeCallback ( callback ) ;
12611398 binding . futimes ( fd , atime , mtime , req ) ;
12621399} ;
12631400
12641401fs . futimesSync = function ( fd , atime , mtime ) {
1265- atime = toUnixTimestamp ( atime ) ;
1266- mtime = toUnixTimestamp ( mtime ) ;
1402+ if ( ! Number . isInteger ( fd ) )
1403+ throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'fd' , 'number' ) ;
1404+ if ( fd < 0 || fd > 0xFFFFFFFF )
1405+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'fd' ) ;
1406+ atime = toUnixTimestamp ( atime , 'atime' ) ;
1407+ mtime = toUnixTimestamp ( mtime , 'mtime' ) ;
12671408 binding . futimes ( fd , atime , mtime ) ;
12681409} ;
12691410
0 commit comments