2323
2424const binding = process . binding ( 'buffer' ) ;
2525const { compare : compare_ , compareOffset } = binding ;
26- const { isArrayBuffer, isSharedArrayBuffer, isUint8Array } =
27- process . binding ( 'util' ) ;
26+ const { isAnyArrayBuffer, isUint8Array } = process . binding ( 'util' ) ;
2827const bindingObj = { } ;
2928const internalUtil = require ( 'internal/util' ) ;
3029
@@ -116,16 +115,19 @@ function Buffer(arg, encodingOrOffset, length) {
116115 * Buffer.from(arrayBuffer[, byteOffset[, length]])
117116 **/
118117Buffer . from = function ( value , encodingOrOffset , length ) {
119- if ( typeof value === 'number ' )
120- throw new TypeError ( '" value" argument must not be a number' ) ;
118+ if ( typeof value === 'string ' )
119+ return fromString ( value , encodingOrOffset ) ;
121120
122- if ( isArrayBuffer ( value ) || isSharedArrayBuffer ( value ) )
121+ if ( isAnyArrayBuffer ( value ) )
123122 return fromArrayBuffer ( value , encodingOrOffset , length ) ;
124123
125- if ( typeof value === 'string' )
126- return fromString ( value , encodingOrOffset ) ;
124+ var b = fromObject ( value ) ;
125+ if ( b )
126+ return b ;
127127
128- return fromObject ( value ) ;
128+ if ( typeof value === 'number' )
129+ throw new TypeError ( '"value" argument must not be a number' ) ;
130+ throw new TypeError ( kFromErrorMsg ) ;
129131} ;
130132
131133Object . setPrototypeOf ( Buffer , Uint8Array ) ;
@@ -218,24 +220,27 @@ function allocate(size) {
218220
219221
220222function fromString ( string , encoding ) {
221- if ( typeof encoding !== 'string' || encoding === '' )
223+ var length ;
224+ if ( typeof encoding !== 'string' || encoding . length === 0 ) {
222225 encoding = 'utf8' ;
223-
224- if ( ! Buffer . isEncoding ( encoding ) )
225- throw new TypeError ( '"encoding" must be a valid string encoding' ) ;
226-
227- if ( string . length === 0 )
228- return new FastBuffer ( ) ;
229-
230- var length = byteLength ( string , encoding ) ;
226+ if ( string . length === 0 )
227+ return new FastBuffer ( ) ;
228+ length = binding . byteLengthUtf8 ( string ) ;
229+ } else {
230+ length = byteLength ( string , encoding , true ) ;
231+ if ( length === - 1 )
232+ throw new TypeError ( '"encoding" must be a valid string encoding' ) ;
233+ if ( string . length === 0 )
234+ return new FastBuffer ( ) ;
235+ }
231236
232237 if ( length >= ( Buffer . poolSize >>> 1 ) )
233238 return binding . createFromString ( string , encoding ) ;
234239
235240 if ( length > ( poolSize - poolOffset ) )
236241 createPool ( ) ;
237242 var b = new FastBuffer ( allocPool , poolOffset , length ) ;
238- var actual = b . write ( string , encoding ) ;
243+ const actual = b . write ( string , encoding ) ;
239244 if ( actual !== length ) {
240245 // byteLength() may overestimate. That's a rare case, though.
241246 b = new FastBuffer ( allocPool , poolOffset , actual ) ;
@@ -255,8 +260,14 @@ function fromArrayLike(obj) {
255260
256261function fromArrayBuffer ( obj , byteOffset , length ) {
257262 // convert byteOffset to integer
258- byteOffset = + byteOffset ;
259- byteOffset = byteOffset ? Math . trunc ( byteOffset ) : 0 ;
263+ if ( byteOffset === undefined ) {
264+ byteOffset = 0 ;
265+ } else {
266+ byteOffset = + byteOffset ;
267+ // check for NaN
268+ if ( byteOffset !== byteOffset )
269+ byteOffset = 0 ;
270+ }
260271
261272 const maxLength = obj . byteLength - byteOffset ;
262273
@@ -268,11 +279,17 @@ function fromArrayBuffer(obj, byteOffset, length) {
268279 } else {
269280 // convert length to non-negative integer
270281 length = + length ;
271- length = length ? Math . trunc ( length ) : 0 ;
272- length = length <= 0 ? 0 : Math . min ( length , Number . MAX_SAFE_INTEGER ) ;
273-
274- if ( length > maxLength )
275- throw new RangeError ( "'length' is out of bounds" ) ;
282+ // Check for NaN
283+ if ( length !== length ) {
284+ length = 0 ;
285+ } else if ( length > 0 ) {
286+ length = ( length < Number . MAX_SAFE_INTEGER ?
287+ length : Number . MAX_SAFE_INTEGER ) ;
288+ if ( length > maxLength )
289+ throw new RangeError ( "'length' is out of bounds" ) ;
290+ } else {
291+ length = 0 ;
292+ }
276293 }
277294
278295 return new FastBuffer ( obj , byteOffset , length ) ;
@@ -289,9 +306,8 @@ function fromObject(obj) {
289306 return b ;
290307 }
291308
292- if ( obj ) {
293- if ( obj . length !== undefined || isArrayBuffer ( obj . buffer ) ||
294- isSharedArrayBuffer ( obj . buffer ) ) {
309+ if ( obj != undefined ) {
310+ if ( obj . length !== undefined || isAnyArrayBuffer ( obj . buffer ) ) {
295311 if ( typeof obj . length !== 'number' || obj . length !== obj . length ) {
296312 return new FastBuffer ( ) ;
297313 }
@@ -302,8 +318,6 @@ function fromObject(obj) {
302318 return fromArrayLike ( obj . data ) ;
303319 }
304320 }
305-
306- throw new TypeError ( kFromErrorMsg ) ;
307321}
308322
309323
@@ -388,53 +402,63 @@ function base64ByteLength(str, bytes) {
388402
389403function byteLength ( string , encoding ) {
390404 if ( typeof string !== 'string' ) {
391- if ( ArrayBuffer . isView ( string ) || isArrayBuffer ( string ) ||
392- isSharedArrayBuffer ( string ) ) {
405+ if ( ArrayBuffer . isView ( string ) || isAnyArrayBuffer ( string ) ) {
393406 return string . byteLength ;
394407 }
395408
396409 throw new TypeError ( '"string" must be a string, Buffer, or ArrayBuffer' ) ;
397410 }
398411
399- var len = string . length ;
400- if ( len === 0 )
412+ const len = string . length ;
413+ const mustMatch = ( arguments . length > 2 && arguments [ 2 ] === true ) ;
414+ if ( ! mustMatch && len === 0 )
401415 return 0 ;
402416
403- // Use a for loop to avoid recursion
404- var loweredCase = false ;
405- for ( ; ; ) {
406- switch ( encoding ) {
407- case 'ascii' :
408- case 'latin1' :
409- case 'binary' :
410- return len ;
411-
412- case 'utf8' :
413- case 'utf-8' :
414- case undefined :
415- return binding . byteLengthUtf8 ( string ) ;
416-
417- case 'ucs2' :
418- case 'ucs-2' :
419- case 'utf16le' :
420- case 'utf-16le' :
417+ if ( ! encoding )
418+ return ( mustMatch ? - 1 : binding . byteLengthUtf8 ( string ) ) ;
419+
420+ encoding += '' ;
421+ switch ( encoding . length ) {
422+ case 4 :
423+ if ( encoding === 'utf8' ) return binding . byteLengthUtf8 ( string ) ;
424+ if ( encoding === 'ucs2' ) return len * 2 ;
425+ encoding = encoding . toLowerCase ( ) ;
426+ if ( encoding === 'utf8' ) return binding . byteLengthUtf8 ( string ) ;
427+ if ( encoding === 'ucs2' ) return len * 2 ;
428+ break ;
429+ case 5 :
430+ if ( encoding === 'utf-8' ) return binding . byteLengthUtf8 ( string ) ;
431+ if ( encoding === 'ascii' ) return len ;
432+ if ( encoding === 'ucs-2' ) return len * 2 ;
433+ encoding = encoding . toLowerCase ( ) ;
434+ if ( encoding === 'utf-8' ) return binding . byteLengthUtf8 ( string ) ;
435+ if ( encoding === 'ascii' ) return len ;
436+ if ( encoding === 'ucs-2' ) return len * 2 ;
437+ break ;
438+ case 7 :
439+ if ( encoding === 'utf16le' || encoding . toLowerCase ( ) === 'utf16le' )
421440 return len * 2 ;
422-
423- case 'hex' :
441+ break ;
442+ case 8 :
443+ if ( encoding === 'utf-16le' || encoding . toLowerCase ( ) === 'utf-16le' )
444+ return len * 2 ;
445+ break ;
446+ case 6 :
447+ if ( encoding === 'latin1' || encoding === 'binary' ) return len ;
448+ if ( encoding === 'base64' ) return base64ByteLength ( string , len ) ;
449+ encoding = encoding . toLowerCase ( ) ;
450+ if ( encoding === 'latin1' || encoding === 'binary' ) return len ;
451+ if ( encoding === 'base64' ) return base64ByteLength ( string , len ) ;
452+ break ;
453+ case 3 :
454+ if ( encoding === 'hex' || encoding . toLowerCase ( ) === 'hex' )
424455 return len >>> 1 ;
425-
426- case 'base64' :
427- return base64ByteLength ( string , len ) ;
428-
429- default :
430- // The C++ binding defaulted to UTF8, we should too.
431- if ( loweredCase )
432- return binding . byteLengthUtf8 ( string ) ;
433-
434- encoding = ( '' + encoding ) . toLowerCase ( ) ;
435- loweredCase = true ;
436- }
456+ break ;
437457 }
458+ if ( mustMatch )
459+ throw new TypeError ( 'Unknown encoding: ' + encoding ) ;
460+ else
461+ return binding . byteLengthUtf8 ( string ) ;
438462}
439463
440464Buffer . byteLength = byteLength ;
0 commit comments