diff --git a/lib/fs.js b/lib/fs.js index 2a1fa8c5a3f..c1f24608de2 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -165,6 +165,21 @@ function validateFd(fd) { } } +function validateOffsetLengthRead(offset, length, bufferLength) { + let err; + + if (offset < 0 || offset >= bufferLength) { + err = new errors.RangeError('ERR_OUT_OF_RANGE', 'offset'); + } else if (length < 0 || offset + length > bufferLength) { + err = new errors.RangeError('ERR_OUT_OF_RANGE', 'length'); + } + + if (err !== undefined) { + Error.captureStackTrace(err, validateOffsetLengthRead); + throw err; + } +} + // Special case of `makeCallback()` that is specific to async `*stat()` calls as // an optimization, since the data passed back to the callback needs to be // transformed anyway. @@ -743,11 +758,7 @@ fs.read = function(fd, buffer, offset, length, position, callback) { }); } - if (offset < 0 || offset >= buffer.length) - throw new errors.RangeError('ERR_OUT_OF_RANGE', 'offset'); - - if (length < 0 || offset + length > buffer.length) - throw new errors.RangeError('ERR_OUT_OF_RANGE', 'length'); + validateOffsetLengthRead(offset, length, buffer.length); if (!isUint32(position)) position = -1; @@ -779,11 +790,7 @@ fs.readSync = function(fd, buffer, offset, length, position) { return 0; } - if (offset < 0 || offset >= buffer.length) - throw new errors.RangeError('ERR_OUT_OF_RANGE', 'offset'); - - if (length < 0 || offset + length > buffer.length) - throw new errors.RangeError('ERR_OUT_OF_RANGE', 'length'); + validateOffsetLengthRead(offset, length, buffer.length); if (!isUint32(position)) position = -1;