@@ -2013,31 +2013,55 @@ function ReadStream(path, options) {
20132013 this . bytesRead = 0 ;
20142014 this . closed = false ;
20152015
2016- if ( this . start !== undefined ) {
2017- if ( typeof this . start !== 'number' || Number . isNaN ( this . start ) ) {
2018- throw new ERR_INVALID_ARG_TYPE ( 'start' , 'number' , this . start ) ;
2019- }
2020- if ( this . end === undefined ) {
2021- this . end = Infinity ;
2022- } else if ( typeof this . end !== 'number' || Number . isNaN ( this . end ) ) {
2023- throw new ERR_INVALID_ARG_TYPE ( 'end' , 'number' , this . end ) ;
2024- }
2016+ // Case 0: If either start or end is undefined, set them to defaults
2017+ // (0, Infinity) respectively.
2018+ this . start = this . start === undefined ? 0 : this . start ;
2019+ this . end = this . end === undefined ? Infinity : this . end ;
20252020
2026- if ( this . start > this . end ) {
2027- const errVal = `{start: ${ this . start } , end: ${ this . end } }` ;
2028- throw new ERR_OUT_OF_RANGE ( 'start' , '<= "end"' , errVal ) ;
2029- }
2021+ // Case 1: If the type of either start or end is not number, throw
2022+ // ERR_INVALID_ARG_TYPE (TypeError).
2023+ if ( typeof this . start !== 'number' ) {
2024+ throw new ERR_INVALID_ARG_TYPE ( 'start' , 'number' , this . start ) ;
2025+ }
2026+ if ( typeof this . end !== 'number' ) {
2027+ throw new ERR_INVALID_ARG_TYPE ( 'end' , 'number' , this . end ) ;
2028+ }
20302029
2031- this . pos = this . start ;
2030+ // Case 2: If either start or end is NaN, throw ERR_OUT_OF_RANGE (RangeError).
2031+ if ( Number . isNaN ( this . start ) ) {
2032+ throw new ERR_OUT_OF_RANGE ( 'start' , 'not NaN' , this . start ) ;
2033+ }
2034+ if ( Number . isNaN ( this . end ) ) {
2035+ throw new ERR_OUT_OF_RANGE ( 'end' , 'not NaN' , this . end ) ;
20322036 }
20332037
2034- // Backwards compatibility: Make sure `end` is a number regardless of `start`.
2035- // TODO(addaleax): Make the above typecheck not depend on `start` instead.
2036- // (That is a semver-major change).
2037- if ( typeof this . end !== 'number' )
2038- this . end = Infinity ;
2039- else if ( Number . isNaN ( this . end ) )
2040- throw new ERR_INVALID_ARG_TYPE ( 'end' , 'number' , this . end ) ;
2038+ // Case 3: If either start or end is negative, throw ERR_OUT_OF_RANGE
2039+ // (RangeError).
2040+ if ( this . start < 0 ) {
2041+ throw new ERR_OUT_OF_RANGE ( 'start' , 'positive' , this . start ) ;
2042+ }
2043+ if ( this . end < 0 ) {
2044+ throw new ERR_OUT_OF_RANGE ( 'end' , 'positive' , this . end ) ;
2045+ }
2046+
2047+ // Case 4: If either start or end is fractional, round them to the nearest
2048+ // whole number. (Not integer as negatives not allowed)
2049+ if ( ! Number . isInteger ( this . start ) ) {
2050+ this . start = Math . round ( this . start ) ;
2051+ }
2052+ if ( ! Number . isInteger ( this . end ) ) {
2053+ this . end = Math . round ( this . end ) ;
2054+ }
2055+
2056+ // Case 5: If start and end are both whole numbers, work perfectly.
2057+
2058+ // Case 6: If start is greater than end, throw ERR_OUT_OF_RANGE (RangeError)
2059+ if ( this . start > this . end ) {
2060+ const errVal = `{start: ${ this . start } , end: ${ this . end } }` ;
2061+ throw new ERR_OUT_OF_RANGE ( 'start' , '<= "end"' , errVal ) ;
2062+ }
2063+
2064+ this . pos = this . start ;
20412065
20422066 if ( typeof this . fd !== 'number' )
20432067 this . open ( ) ;
0 commit comments