23
23
24
24
const binding = process . binding ( 'buffer' ) ;
25
25
const { compare : compare_ , compareOffset } = binding ;
26
- const { isArrayBuffer, isSharedArrayBuffer, isUint8Array } =
27
- process . binding ( 'util' ) ;
26
+ const { isAnyArrayBuffer, isUint8Array } = process . binding ( 'util' ) ;
28
27
const bindingObj = { } ;
29
28
const internalUtil = require ( 'internal/util' ) ;
30
29
@@ -116,16 +115,19 @@ function Buffer(arg, encodingOrOffset, length) {
116
115
* Buffer.from(arrayBuffer[, byteOffset[, length]])
117
116
**/
118
117
Buffer . 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 ) ;
121
120
122
- if ( isArrayBuffer ( value ) || isSharedArrayBuffer ( value ) )
121
+ if ( isAnyArrayBuffer ( value ) )
123
122
return fromArrayBuffer ( value , encodingOrOffset , length ) ;
124
123
125
- if ( typeof value === 'string' )
126
- return fromString ( value , encodingOrOffset ) ;
124
+ var b = fromObject ( value ) ;
125
+ if ( b )
126
+ return b ;
127
127
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 ) ;
129
131
} ;
130
132
131
133
Object . setPrototypeOf ( Buffer , Uint8Array ) ;
@@ -218,24 +220,27 @@ function allocate(size) {
218
220
219
221
220
222
function fromString ( string , encoding ) {
221
- if ( typeof encoding !== 'string' || encoding === '' )
223
+ var length ;
224
+ if ( typeof encoding !== 'string' || encoding . length === 0 ) {
222
225
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
+ }
231
236
232
237
if ( length >= ( Buffer . poolSize >>> 1 ) )
233
238
return binding . createFromString ( string , encoding ) ;
234
239
235
240
if ( length > ( poolSize - poolOffset ) )
236
241
createPool ( ) ;
237
242
var b = new FastBuffer ( allocPool , poolOffset , length ) ;
238
- var actual = b . write ( string , encoding ) ;
243
+ const actual = b . write ( string , encoding ) ;
239
244
if ( actual !== length ) {
240
245
// byteLength() may overestimate. That's a rare case, though.
241
246
b = new FastBuffer ( allocPool , poolOffset , actual ) ;
@@ -255,8 +260,14 @@ function fromArrayLike(obj) {
255
260
256
261
function fromArrayBuffer ( obj , byteOffset , length ) {
257
262
// 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
+ }
260
271
261
272
const maxLength = obj . byteLength - byteOffset ;
262
273
@@ -268,11 +279,17 @@ function fromArrayBuffer(obj, byteOffset, length) {
268
279
} else {
269
280
// convert length to non-negative integer
270
281
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
+ }
276
293
}
277
294
278
295
return new FastBuffer ( obj , byteOffset , length ) ;
@@ -289,9 +306,8 @@ function fromObject(obj) {
289
306
return b ;
290
307
}
291
308
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 ) ) {
295
311
if ( typeof obj . length !== 'number' || obj . length !== obj . length ) {
296
312
return new FastBuffer ( ) ;
297
313
}
@@ -302,8 +318,6 @@ function fromObject(obj) {
302
318
return fromArrayLike ( obj . data ) ;
303
319
}
304
320
}
305
-
306
- throw new TypeError ( kFromErrorMsg ) ;
307
321
}
308
322
309
323
@@ -388,53 +402,63 @@ function base64ByteLength(str, bytes) {
388
402
389
403
function byteLength ( string , encoding ) {
390
404
if ( typeof string !== 'string' ) {
391
- if ( ArrayBuffer . isView ( string ) || isArrayBuffer ( string ) ||
392
- isSharedArrayBuffer ( string ) ) {
405
+ if ( ArrayBuffer . isView ( string ) || isAnyArrayBuffer ( string ) ) {
393
406
return string . byteLength ;
394
407
}
395
408
396
409
throw new TypeError ( '"string" must be a string, Buffer, or ArrayBuffer' ) ;
397
410
}
398
411
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 )
401
415
return 0 ;
402
416
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' )
421
440
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' )
424
455
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 ;
437
457
}
458
+ if ( mustMatch )
459
+ throw new TypeError ( 'Unknown encoding: ' + encoding ) ;
460
+ else
461
+ return binding . byteLengthUtf8 ( string ) ;
438
462
}
439
463
440
464
Buffer . byteLength = byteLength ;
0 commit comments