1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23 24const { 25 Array, 26 ArrayFrom, 27 ArrayIsArray, 28 ArrayPrototypeForEach, 29 ArrayPrototypeIndexOf, 30 MathFloor, 31 MathMin, 32 MathTrunc, 33 NumberIsNaN, 34 NumberMAX_SAFE_INTEGER, 35 NumberMIN_SAFE_INTEGER, 36 ObjectCreate, 37 ObjectDefineProperties, 38 ObjectDefineProperty, 39 ObjectSetPrototypeOf, 40 RegExpPrototypeSymbolReplace, 41 StringPrototypeCharCodeAt, 42 StringPrototypeSlice, 43 StringPrototypeToLowerCase, 44 StringPrototypeTrim, 45 SymbolSpecies, 46 SymbolToPrimitive, 47 TypedArrayPrototypeGetBuffer, 48 TypedArrayPrototypeGetByteLength, 49 TypedArrayPrototypeGetByteOffset, 50 TypedArrayPrototypeFill, 51 TypedArrayPrototypeGetLength, 52 TypedArrayPrototypeSet, 53 TypedArrayPrototypeSlice, 54 Uint8Array, 55 Uint8ArrayPrototype, 56} = primordials; 57 58const { 59 byteLengthUtf8, 60 compare: _compare, 61 compareOffset, 62 createFromString, 63 fill: bindingFill, 64 isAscii: bindingIsAscii, 65 isUtf8: bindingIsUtf8, 66 indexOfBuffer, 67 indexOfNumber, 68 indexOfString, 69 swap16: _swap16, 70 swap32: _swap32, 71 swap64: _swap64, 72 kMaxLength, 73 kStringMaxLength, 74} = internalBinding('buffer'); 75const { 76 constants: { 77 ALL_PROPERTIES, 78 ONLY_ENUMERABLE, 79 }, 80 getOwnNonIndexProperties, 81} = internalBinding('util'); 82const { 83 customInspectSymbol, 84 isInsideNodeModules, 85 lazyDOMException, 86 normalizeEncoding, 87 kIsEncodingSymbol, 88 defineLazyProperties, 89} = require('internal/util'); 90const { 91 isAnyArrayBuffer, 92 isArrayBufferView, 93 isUint8Array, 94 isTypedArray, 95} = require('internal/util/types'); 96const { 97 inspect: utilInspect, 98} = require('internal/util/inspect'); 99const { encodings } = internalBinding('string_decoder'); 100 101const { 102 codes: { 103 ERR_BUFFER_OUT_OF_BOUNDS, 104 ERR_INVALID_ARG_TYPE, 105 ERR_INVALID_ARG_VALUE, 106 ERR_INVALID_BUFFER_SIZE, 107 ERR_OUT_OF_RANGE, 108 ERR_MISSING_ARGS, 109 ERR_UNKNOWN_ENCODING, 110 }, 111 genericNodeError, 112 hideStackFrames, 113} = require('internal/errors'); 114const { 115 validateArray, 116 validateBuffer, 117 validateNumber, 118 validateInteger, 119 validateString, 120} = require('internal/validators'); 121// Provide validateInteger() but with kMaxLength as the default maximum value. 122const validateOffset = (value, name, min = 0, max = kMaxLength) => 123 validateInteger(value, name, min, max); 124 125const { 126 FastBuffer, 127 markAsUntransferable, 128 addBufferPrototypeMethods, 129 createUnsafeBuffer, 130} = require('internal/buffer'); 131 132FastBuffer.prototype.constructor = Buffer; 133Buffer.prototype = FastBuffer.prototype; 134addBufferPrototypeMethods(Buffer.prototype); 135 136const constants = ObjectDefineProperties({}, { 137 MAX_LENGTH: { 138 __proto__: null, 139 value: kMaxLength, 140 writable: false, 141 enumerable: true, 142 }, 143 MAX_STRING_LENGTH: { 144 __proto__: null, 145 value: kStringMaxLength, 146 writable: false, 147 enumerable: true, 148 }, 149}); 150 151Buffer.poolSize = 8 * 1024; 152let poolSize, poolOffset, allocPool; 153 154const encodingsMap = ObjectCreate(null); 155for (let i = 0; i < encodings.length; ++i) 156 encodingsMap[encodings[i]] = i; 157 158function createPool() { 159 poolSize = Buffer.poolSize; 160 allocPool = createUnsafeBuffer(poolSize).buffer; 161 markAsUntransferable(allocPool); 162 poolOffset = 0; 163} 164createPool(); 165 166function alignPool() { 167 // Ensure aligned slices 168 if (poolOffset & 0x7) { 169 poolOffset |= 0x7; 170 poolOffset++; 171 } 172} 173 174let bufferWarningAlreadyEmitted = false; 175let nodeModulesCheckCounter = 0; 176const bufferWarning = 'Buffer() is deprecated due to security and usability ' + 177 'issues. Please use the Buffer.alloc(), ' + 178 'Buffer.allocUnsafe(), or Buffer.from() methods instead.'; 179 180function showFlaggedDeprecation() { 181 if (bufferWarningAlreadyEmitted || 182 ++nodeModulesCheckCounter > 10000 || 183 (!require('internal/options').getOptionValue('--pending-deprecation') && 184 isInsideNodeModules())) { 185 // We don't emit a warning, because we either: 186 // - Already did so, or 187 // - Already checked too many times whether a call is coming 188 // from node_modules and want to stop slowing down things, or 189 // - We aren't running with `--pending-deprecation` enabled, 190 // and the code is inside `node_modules`. 191 return; 192 } 193 194 process.emitWarning(bufferWarning, 'DeprecationWarning', 'DEP0005'); 195 bufferWarningAlreadyEmitted = true; 196} 197 198function toInteger(n, defaultVal) { 199 n = +n; 200 if (!NumberIsNaN(n) && 201 n >= NumberMIN_SAFE_INTEGER && 202 n <= NumberMAX_SAFE_INTEGER) { 203 return ((n % 1) === 0 ? n : MathFloor(n)); 204 } 205 return defaultVal; 206} 207 208function _copy(source, target, targetStart, sourceStart, sourceEnd) { 209 if (!isUint8Array(source)) 210 throw new ERR_INVALID_ARG_TYPE('source', ['Buffer', 'Uint8Array'], source); 211 if (!isUint8Array(target)) 212 throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target); 213 214 if (targetStart === undefined) { 215 targetStart = 0; 216 } else { 217 targetStart = toInteger(targetStart, 0); 218 if (targetStart < 0) 219 throw new ERR_OUT_OF_RANGE('targetStart', '>= 0', targetStart); 220 } 221 222 if (sourceStart === undefined) { 223 sourceStart = 0; 224 } else { 225 sourceStart = toInteger(sourceStart, 0); 226 if (sourceStart < 0 || sourceStart > source.length) 227 throw new ERR_OUT_OF_RANGE('sourceStart', `>= 0 && <= ${source.length}`, sourceStart); 228 } 229 230 if (sourceEnd === undefined) { 231 sourceEnd = source.length; 232 } else { 233 sourceEnd = toInteger(sourceEnd, 0); 234 if (sourceEnd < 0) 235 throw new ERR_OUT_OF_RANGE('sourceEnd', '>= 0', sourceEnd); 236 } 237 238 if (targetStart >= target.length || sourceStart >= sourceEnd) 239 return 0; 240 241 return _copyActual(source, target, targetStart, sourceStart, sourceEnd); 242} 243 244function _copyActual(source, target, targetStart, sourceStart, sourceEnd) { 245 if (sourceEnd - sourceStart > target.length - targetStart) 246 sourceEnd = sourceStart + target.length - targetStart; 247 248 let nb = sourceEnd - sourceStart; 249 const sourceLen = source.length - sourceStart; 250 if (nb > sourceLen) 251 nb = sourceLen; 252 253 if (sourceStart !== 0 || sourceEnd < source.length) 254 source = new Uint8Array(source.buffer, source.byteOffset + sourceStart, nb); 255 256 TypedArrayPrototypeSet(target, source, targetStart); 257 258 return nb; 259} 260 261/** 262 * The Buffer() constructor is deprecated in documentation and should not be 263 * used moving forward. Rather, developers should use one of the three new 264 * factory APIs: Buffer.from(), Buffer.allocUnsafe() or Buffer.alloc() based on 265 * their specific needs. There is no runtime deprecation because of the extent 266 * to which the Buffer constructor is used in the ecosystem currently -- a 267 * runtime deprecation would introduce too much breakage at this time. It's not 268 * likely that the Buffer constructors would ever actually be removed. 269 * Deprecation Code: DEP0005 270 */ 271function Buffer(arg, encodingOrOffset, length) { 272 showFlaggedDeprecation(); 273 // Common case. 274 if (typeof arg === 'number') { 275 if (typeof encodingOrOffset === 'string') { 276 throw new ERR_INVALID_ARG_TYPE('string', 'string', arg); 277 } 278 return Buffer.alloc(arg); 279 } 280 return Buffer.from(arg, encodingOrOffset, length); 281} 282 283ObjectDefineProperty(Buffer, SymbolSpecies, { 284 __proto__: null, 285 enumerable: false, 286 configurable: true, 287 get() { return FastBuffer; }, 288}); 289 290/** 291 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError 292 * if value is a number. 293 * Buffer.from(str[, encoding]) 294 * Buffer.from(array) 295 * Buffer.from(buffer) 296 * Buffer.from(arrayBuffer[, byteOffset[, length]]) 297 */ 298Buffer.from = function from(value, encodingOrOffset, length) { 299 if (typeof value === 'string') 300 return fromString(value, encodingOrOffset); 301 302 if (typeof value === 'object' && value !== null) { 303 if (isAnyArrayBuffer(value)) 304 return fromArrayBuffer(value, encodingOrOffset, length); 305 306 const valueOf = value.valueOf && value.valueOf(); 307 if (valueOf != null && 308 valueOf !== value && 309 (typeof valueOf === 'string' || typeof valueOf === 'object')) { 310 return from(valueOf, encodingOrOffset, length); 311 } 312 313 const b = fromObject(value); 314 if (b) 315 return b; 316 317 if (typeof value[SymbolToPrimitive] === 'function') { 318 const primitive = value[SymbolToPrimitive]('string'); 319 if (typeof primitive === 'string') { 320 return fromString(primitive, encodingOrOffset); 321 } 322 } 323 } 324 325 throw new ERR_INVALID_ARG_TYPE( 326 'first argument', 327 ['string', 'Buffer', 'ArrayBuffer', 'Array', 'Array-like Object'], 328 value, 329 ); 330}; 331 332/** 333 * Creates the Buffer as a copy of the underlying ArrayBuffer of the view 334 * rather than the contents of the view. 335 * @param {TypedArray} view 336 * @param {number} [offset] 337 * @param {number} [length] 338 * @returns {Buffer} 339 */ 340Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) { 341 if (!isTypedArray(view)) { 342 throw new ERR_INVALID_ARG_TYPE('view', [ 'TypedArray' ], view); 343 } 344 345 const viewLength = TypedArrayPrototypeGetLength(view); 346 if (viewLength === 0) { 347 return Buffer.alloc(0); 348 } 349 350 if (offset !== undefined || length !== undefined) { 351 if (offset !== undefined) { 352 validateInteger(offset, 'offset', 0); 353 if (offset >= viewLength) return Buffer.alloc(0); 354 } else { 355 offset = 0; 356 } 357 let end; 358 if (length !== undefined) { 359 validateInteger(length, 'length', 0); 360 end = offset + length; 361 } else { 362 end = viewLength; 363 } 364 365 view = TypedArrayPrototypeSlice(view, offset, end); 366 } 367 368 return fromArrayLike(new Uint8Array( 369 TypedArrayPrototypeGetBuffer(view), 370 TypedArrayPrototypeGetByteOffset(view), 371 TypedArrayPrototypeGetByteLength(view))); 372}; 373 374// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated 375// Buffer() constructor. Must use arrow function syntax to avoid automatically 376// adding a `prototype` property and making the function a constructor. 377// 378// Refs: https://tc39.github.io/ecma262/#sec-%typedarray%.of 379// Refs: https://esdiscuss.org/topic/isconstructor#content-11 380const of = (...items) => { 381 const newObj = createUnsafeBuffer(items.length); 382 for (let k = 0; k < items.length; k++) 383 newObj[k] = items[k]; 384 return newObj; 385}; 386Buffer.of = of; 387 388ObjectSetPrototypeOf(Buffer, Uint8Array); 389 390// The 'assertSize' method will remove itself from the callstack when an error 391// occurs. This is done simply to keep the internal details of the 392// implementation from bleeding out to users. 393const assertSize = hideStackFrames((size) => { 394 validateNumber(size, 'size'); 395 if (!(size >= 0 && size <= kMaxLength)) { 396 throw new ERR_INVALID_ARG_VALUE.RangeError('size', size); 397 } 398}); 399 400/** 401 * Creates a new filled Buffer instance. 402 * alloc(size[, fill[, encoding]]) 403 */ 404Buffer.alloc = function alloc(size, fill, encoding) { 405 assertSize(size); 406 if (fill !== undefined && fill !== 0 && size > 0) { 407 const buf = createUnsafeBuffer(size); 408 return _fill(buf, fill, 0, buf.length, encoding); 409 } 410 return new FastBuffer(size); 411}; 412 413/** 414 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer 415 * instance. If `--zero-fill-buffers` is set, will zero-fill the buffer. 416 */ 417Buffer.allocUnsafe = function allocUnsafe(size) { 418 assertSize(size); 419 return allocate(size); 420}; 421 422/** 423 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled 424 * Buffer instance that is not allocated off the pre-initialized pool. 425 * If `--zero-fill-buffers` is set, will zero-fill the buffer. 426 */ 427Buffer.allocUnsafeSlow = function allocUnsafeSlow(size) { 428 assertSize(size); 429 return createUnsafeBuffer(size); 430}; 431 432// If --zero-fill-buffers command line argument is set, a zero-filled 433// buffer is returned. 434function SlowBuffer(length) { 435 assertSize(length); 436 return createUnsafeBuffer(length); 437} 438 439ObjectSetPrototypeOf(SlowBuffer.prototype, Uint8ArrayPrototype); 440ObjectSetPrototypeOf(SlowBuffer, Uint8Array); 441 442function allocate(size) { 443 if (size <= 0) { 444 return new FastBuffer(); 445 } 446 if (size < (Buffer.poolSize >>> 1)) { 447 if (size > (poolSize - poolOffset)) 448 createPool(); 449 const b = new FastBuffer(allocPool, poolOffset, size); 450 poolOffset += size; 451 alignPool(); 452 return b; 453 } 454 return createUnsafeBuffer(size); 455} 456 457function fromStringFast(string, ops) { 458 const length = ops.byteLength(string); 459 460 if (length >= (Buffer.poolSize >>> 1)) 461 return createFromString(string, ops.encodingVal); 462 463 if (length > (poolSize - poolOffset)) 464 createPool(); 465 let b = new FastBuffer(allocPool, poolOffset, length); 466 const actual = ops.write(b, string, 0, length); 467 if (actual !== length) { 468 // byteLength() may overestimate. That's a rare case, though. 469 b = new FastBuffer(allocPool, poolOffset, actual); 470 } 471 poolOffset += actual; 472 alignPool(); 473 return b; 474} 475 476function fromString(string, encoding) { 477 let ops; 478 if (typeof encoding !== 'string' || encoding.length === 0) { 479 if (string.length === 0) 480 return new FastBuffer(); 481 ops = encodingOps.utf8; 482 encoding = undefined; 483 } else { 484 ops = getEncodingOps(encoding); 485 if (ops === undefined) 486 throw new ERR_UNKNOWN_ENCODING(encoding); 487 if (string.length === 0) 488 return new FastBuffer(); 489 } 490 return fromStringFast(string, ops); 491} 492 493function fromArrayBuffer(obj, byteOffset, length) { 494 // Convert byteOffset to integer 495 if (byteOffset === undefined) { 496 byteOffset = 0; 497 } else { 498 byteOffset = +byteOffset; 499 if (NumberIsNaN(byteOffset)) 500 byteOffset = 0; 501 } 502 503 const maxLength = obj.byteLength - byteOffset; 504 505 if (maxLength < 0) 506 throw new ERR_BUFFER_OUT_OF_BOUNDS('offset'); 507 508 if (length === undefined) { 509 length = maxLength; 510 } else { 511 // Convert length to non-negative integer. 512 length = +length; 513 if (length > 0) { 514 if (length > maxLength) 515 throw new ERR_BUFFER_OUT_OF_BOUNDS('length'); 516 } else { 517 length = 0; 518 } 519 } 520 521 return new FastBuffer(obj, byteOffset, length); 522} 523 524function fromArrayLike(obj) { 525 if (obj.length <= 0) 526 return new FastBuffer(); 527 if (obj.length < (Buffer.poolSize >>> 1)) { 528 if (obj.length > (poolSize - poolOffset)) 529 createPool(); 530 const b = new FastBuffer(allocPool, poolOffset, obj.length); 531 TypedArrayPrototypeSet(b, obj, 0); 532 poolOffset += obj.length; 533 alignPool(); 534 return b; 535 } 536 return new FastBuffer(obj); 537} 538 539function fromObject(obj) { 540 if (obj.length !== undefined || isAnyArrayBuffer(obj.buffer)) { 541 if (typeof obj.length !== 'number') { 542 return new FastBuffer(); 543 } 544 return fromArrayLike(obj); 545 } 546 547 if (obj.type === 'Buffer' && ArrayIsArray(obj.data)) { 548 return fromArrayLike(obj.data); 549 } 550} 551 552// Static methods 553 554Buffer.isBuffer = function isBuffer(b) { 555 return b instanceof Buffer; 556}; 557 558Buffer.compare = function compare(buf1, buf2) { 559 if (!isUint8Array(buf1)) { 560 throw new ERR_INVALID_ARG_TYPE('buf1', ['Buffer', 'Uint8Array'], buf1); 561 } 562 563 if (!isUint8Array(buf2)) { 564 throw new ERR_INVALID_ARG_TYPE('buf2', ['Buffer', 'Uint8Array'], buf2); 565 } 566 567 if (buf1 === buf2) { 568 return 0; 569 } 570 571 return _compare(buf1, buf2); 572}; 573 574Buffer.isEncoding = function isEncoding(encoding) { 575 return typeof encoding === 'string' && encoding.length !== 0 && 576 normalizeEncoding(encoding) !== undefined; 577}; 578Buffer[kIsEncodingSymbol] = Buffer.isEncoding; 579 580Buffer.concat = function concat(list, length) { 581 validateArray(list, 'list'); 582 583 if (list.length === 0) 584 return new FastBuffer(); 585 586 if (length === undefined) { 587 length = 0; 588 for (let i = 0; i < list.length; i++) { 589 if (list[i].length) { 590 length += list[i].length; 591 } 592 } 593 } else { 594 validateOffset(length, 'length'); 595 } 596 597 const buffer = Buffer.allocUnsafe(length); 598 let pos = 0; 599 for (let i = 0; i < list.length; i++) { 600 const buf = list[i]; 601 if (!isUint8Array(buf)) { 602 // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE. 603 // Instead, find the proper error code for this. 604 throw new ERR_INVALID_ARG_TYPE( 605 `list[${i}]`, ['Buffer', 'Uint8Array'], list[i]); 606 } 607 pos += _copyActual(buf, buffer, pos, 0, buf.length); 608 } 609 610 // Note: `length` is always equal to `buffer.length` at this point 611 if (pos < length) { 612 // Zero-fill the remaining bytes if the specified `length` was more than 613 // the actual total length, i.e. if we have some remaining allocated bytes 614 // there were not initialized. 615 TypedArrayPrototypeFill(buffer, 0, pos, length); 616 } 617 618 return buffer; 619}; 620 621function base64ByteLength(str, bytes) { 622 // Handle padding 623 if (StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) 624 bytes--; 625 if (bytes > 1 && StringPrototypeCharCodeAt(str, bytes - 1) === 0x3D) 626 bytes--; 627 628 // Base64 ratio: 3/4 629 return (bytes * 3) >>> 2; 630} 631 632const encodingOps = { 633 utf8: { 634 encoding: 'utf8', 635 encodingVal: encodingsMap.utf8, 636 byteLength: byteLengthUtf8, 637 write: (buf, string, offset, len) => buf.utf8Write(string, offset, len), 638 slice: (buf, start, end) => buf.utf8Slice(start, end), 639 indexOf: (buf, val, byteOffset, dir) => 640 indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir), 641 }, 642 ucs2: { 643 encoding: 'ucs2', 644 encodingVal: encodingsMap.utf16le, 645 byteLength: (string) => string.length * 2, 646 write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len), 647 slice: (buf, start, end) => buf.ucs2Slice(start, end), 648 indexOf: (buf, val, byteOffset, dir) => 649 indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir), 650 }, 651 utf16le: { 652 encoding: 'utf16le', 653 encodingVal: encodingsMap.utf16le, 654 byteLength: (string) => string.length * 2, 655 write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len), 656 slice: (buf, start, end) => buf.ucs2Slice(start, end), 657 indexOf: (buf, val, byteOffset, dir) => 658 indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir), 659 }, 660 latin1: { 661 encoding: 'latin1', 662 encodingVal: encodingsMap.latin1, 663 byteLength: (string) => string.length, 664 write: (buf, string, offset, len) => buf.latin1Write(string, offset, len), 665 slice: (buf, start, end) => buf.latin1Slice(start, end), 666 indexOf: (buf, val, byteOffset, dir) => 667 indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir), 668 }, 669 ascii: { 670 encoding: 'ascii', 671 encodingVal: encodingsMap.ascii, 672 byteLength: (string) => string.length, 673 write: (buf, string, offset, len) => buf.asciiWrite(string, offset, len), 674 slice: (buf, start, end) => buf.asciiSlice(start, end), 675 indexOf: (buf, val, byteOffset, dir) => 676 indexOfBuffer(buf, 677 fromStringFast(val, encodingOps.ascii), 678 byteOffset, 679 encodingsMap.ascii, 680 dir), 681 }, 682 base64: { 683 encoding: 'base64', 684 encodingVal: encodingsMap.base64, 685 byteLength: (string) => base64ByteLength(string, string.length), 686 write: (buf, string, offset, len) => buf.base64Write(string, offset, len), 687 slice: (buf, start, end) => buf.base64Slice(start, end), 688 indexOf: (buf, val, byteOffset, dir) => 689 indexOfBuffer(buf, 690 fromStringFast(val, encodingOps.base64), 691 byteOffset, 692 encodingsMap.base64, 693 dir), 694 }, 695 base64url: { 696 encoding: 'base64url', 697 encodingVal: encodingsMap.base64url, 698 byteLength: (string) => base64ByteLength(string, string.length), 699 write: (buf, string, offset, len) => 700 buf.base64urlWrite(string, offset, len), 701 slice: (buf, start, end) => buf.base64urlSlice(start, end), 702 indexOf: (buf, val, byteOffset, dir) => 703 indexOfBuffer(buf, 704 fromStringFast(val, encodingOps.base64url), 705 byteOffset, 706 encodingsMap.base64url, 707 dir), 708 }, 709 hex: { 710 encoding: 'hex', 711 encodingVal: encodingsMap.hex, 712 byteLength: (string) => string.length >>> 1, 713 write: (buf, string, offset, len) => buf.hexWrite(string, offset, len), 714 slice: (buf, start, end) => buf.hexSlice(start, end), 715 indexOf: (buf, val, byteOffset, dir) => 716 indexOfBuffer(buf, 717 fromStringFast(val, encodingOps.hex), 718 byteOffset, 719 encodingsMap.hex, 720 dir), 721 }, 722}; 723function getEncodingOps(encoding) { 724 encoding += ''; 725 switch (encoding.length) { 726 case 4: 727 if (encoding === 'utf8') return encodingOps.utf8; 728 if (encoding === 'ucs2') return encodingOps.ucs2; 729 encoding = StringPrototypeToLowerCase(encoding); 730 if (encoding === 'utf8') return encodingOps.utf8; 731 if (encoding === 'ucs2') return encodingOps.ucs2; 732 break; 733 case 5: 734 if (encoding === 'utf-8') return encodingOps.utf8; 735 if (encoding === 'ascii') return encodingOps.ascii; 736 if (encoding === 'ucs-2') return encodingOps.ucs2; 737 encoding = StringPrototypeToLowerCase(encoding); 738 if (encoding === 'utf-8') return encodingOps.utf8; 739 if (encoding === 'ascii') return encodingOps.ascii; 740 if (encoding === 'ucs-2') return encodingOps.ucs2; 741 break; 742 case 7: 743 if (encoding === 'utf16le' || 744 StringPrototypeToLowerCase(encoding) === 'utf16le') 745 return encodingOps.utf16le; 746 break; 747 case 8: 748 if (encoding === 'utf-16le' || 749 StringPrototypeToLowerCase(encoding) === 'utf-16le') 750 return encodingOps.utf16le; 751 break; 752 case 6: 753 if (encoding === 'latin1' || encoding === 'binary') 754 return encodingOps.latin1; 755 if (encoding === 'base64') return encodingOps.base64; 756 encoding = StringPrototypeToLowerCase(encoding); 757 if (encoding === 'latin1' || encoding === 'binary') 758 return encodingOps.latin1; 759 if (encoding === 'base64') return encodingOps.base64; 760 break; 761 case 3: 762 if (encoding === 'hex' || StringPrototypeToLowerCase(encoding) === 'hex') 763 return encodingOps.hex; 764 break; 765 case 9: 766 if (encoding === 'base64url' || 767 StringPrototypeToLowerCase(encoding) === 'base64url') 768 return encodingOps.base64url; 769 break; 770 } 771} 772 773function byteLength(string, encoding) { 774 if (typeof string !== 'string') { 775 if (isArrayBufferView(string) || isAnyArrayBuffer(string)) { 776 return string.byteLength; 777 } 778 779 throw new ERR_INVALID_ARG_TYPE( 780 'string', ['string', 'Buffer', 'ArrayBuffer'], string, 781 ); 782 } 783 784 const len = string.length; 785 if (len === 0) 786 return 0; 787 788 if (encoding) { 789 const ops = getEncodingOps(encoding); 790 if (ops) { 791 return ops.byteLength(string); 792 } 793 } 794 return byteLengthUtf8(string); 795} 796 797Buffer.byteLength = byteLength; 798 799// For backwards compatibility. 800ObjectDefineProperty(Buffer.prototype, 'parent', { 801 __proto__: null, 802 enumerable: true, 803 get() { 804 if (!(this instanceof Buffer)) 805 return undefined; 806 return this.buffer; 807 }, 808}); 809ObjectDefineProperty(Buffer.prototype, 'offset', { 810 __proto__: null, 811 enumerable: true, 812 get() { 813 if (!(this instanceof Buffer)) 814 return undefined; 815 return this.byteOffset; 816 }, 817}); 818 819Buffer.prototype.copy = 820 function copy(target, targetStart, sourceStart, sourceEnd) { 821 return _copy(this, target, targetStart, sourceStart, sourceEnd); 822 }; 823 824// No need to verify that "buf.length <= MAX_UINT32" since it's a read-only 825// property of a typed array. 826// This behaves neither like String nor Uint8Array in that we set start/end 827// to their upper/lower bounds if the value passed is out of range. 828Buffer.prototype.toString = function toString(encoding, start, end) { 829 if (arguments.length === 0) { 830 return this.utf8Slice(0, this.length); 831 } 832 833 const len = this.length; 834 835 if (start <= 0) 836 start = 0; 837 else if (start >= len) 838 return ''; 839 else 840 start |= 0; 841 842 if (end === undefined || end > len) 843 end = len; 844 else 845 end |= 0; 846 847 if (end <= start) 848 return ''; 849 850 if (encoding === undefined) 851 return this.utf8Slice(start, end); 852 853 const ops = getEncodingOps(encoding); 854 if (ops === undefined) 855 throw new ERR_UNKNOWN_ENCODING(encoding); 856 857 return ops.slice(this, start, end); 858}; 859 860Buffer.prototype.equals = function equals(otherBuffer) { 861 if (!isUint8Array(otherBuffer)) { 862 throw new ERR_INVALID_ARG_TYPE( 863 'otherBuffer', ['Buffer', 'Uint8Array'], otherBuffer); 864 } 865 866 if (this === otherBuffer) 867 return true; 868 869 if (this.byteLength !== otherBuffer.byteLength) 870 return false; 871 872 return this.byteLength === 0 || _compare(this, otherBuffer) === 0; 873}; 874 875let INSPECT_MAX_BYTES = 50; 876// Override how buffers are presented by util.inspect(). 877Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) { 878 const max = INSPECT_MAX_BYTES; 879 const actualMax = MathMin(max, this.length); 880 const remaining = this.length - max; 881 let str = StringPrototypeTrim(RegExpPrototypeSymbolReplace( 882 /(.{2})/g, this.hexSlice(0, actualMax), '$1 ')); 883 if (remaining > 0) 884 str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`; 885 // Inspect special properties as well, if possible. 886 if (ctx) { 887 let extras = false; 888 const filter = ctx.showHidden ? ALL_PROPERTIES : ONLY_ENUMERABLE; 889 const obj = ObjectCreate(null); 890 ArrayPrototypeForEach(getOwnNonIndexProperties(this, filter), 891 (key) => { 892 extras = true; 893 obj[key] = this[key]; 894 }); 895 if (extras) { 896 if (this.length !== 0) 897 str += ', '; 898 // '[Object: null prototype] {'.length === 26 899 // This is guarded with a test. 900 str += StringPrototypeSlice(utilInspect(obj, { 901 ...ctx, 902 breakLength: Infinity, 903 compact: true, 904 }), 27, -2); 905 } 906 } 907 return `<${this.constructor.name} ${str}>`; 908}; 909Buffer.prototype.inspect = Buffer.prototype[customInspectSymbol]; 910 911Buffer.prototype.compare = function compare(target, 912 targetStart, 913 targetEnd, 914 sourceStart, 915 sourceEnd) { 916 if (!isUint8Array(target)) { 917 throw new ERR_INVALID_ARG_TYPE('target', ['Buffer', 'Uint8Array'], target); 918 } 919 if (arguments.length === 1) 920 return _compare(this, target); 921 922 if (targetStart === undefined) 923 targetStart = 0; 924 else 925 validateOffset(targetStart, 'targetStart'); 926 927 if (targetEnd === undefined) 928 targetEnd = target.length; 929 else 930 validateOffset(targetEnd, 'targetEnd', 0, target.length); 931 932 if (sourceStart === undefined) 933 sourceStart = 0; 934 else 935 validateOffset(sourceStart, 'sourceStart'); 936 937 if (sourceEnd === undefined) 938 sourceEnd = this.length; 939 else 940 validateOffset(sourceEnd, 'sourceEnd', 0, this.length); 941 942 if (sourceStart >= sourceEnd) 943 return (targetStart >= targetEnd ? 0 : -1); 944 if (targetStart >= targetEnd) 945 return 1; 946 947 return compareOffset(this, target, targetStart, sourceStart, targetEnd, 948 sourceEnd); 949}; 950 951// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, 952// OR the last index of `val` in `buffer` at offset <= `byteOffset`. 953// 954// Arguments: 955// - buffer - a Buffer to search 956// - val - a string, Buffer, or number 957// - byteOffset - an index into `buffer`; will be clamped to an int32 958// - encoding - an optional encoding, relevant if val is a string 959// - dir - true for indexOf, false for lastIndexOf 960function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) { 961 validateBuffer(buffer); 962 963 if (typeof byteOffset === 'string') { 964 encoding = byteOffset; 965 byteOffset = undefined; 966 } else if (byteOffset > 0x7fffffff) { 967 byteOffset = 0x7fffffff; 968 } else if (byteOffset < -0x80000000) { 969 byteOffset = -0x80000000; 970 } 971 // Coerce to Number. Values like null and [] become 0. 972 byteOffset = +byteOffset; 973 // If the offset is undefined, "foo", {}, coerces to NaN, search whole buffer. 974 if (NumberIsNaN(byteOffset)) { 975 byteOffset = dir ? 0 : (buffer.length || buffer.byteLength); 976 } 977 dir = !!dir; // Cast to bool. 978 979 if (typeof val === 'number') 980 return indexOfNumber(buffer, val >>> 0, byteOffset, dir); 981 982 let ops; 983 if (encoding === undefined) 984 ops = encodingOps.utf8; 985 else 986 ops = getEncodingOps(encoding); 987 988 if (typeof val === 'string') { 989 if (ops === undefined) 990 throw new ERR_UNKNOWN_ENCODING(encoding); 991 return ops.indexOf(buffer, val, byteOffset, dir); 992 } 993 994 if (isUint8Array(val)) { 995 const encodingVal = 996 (ops === undefined ? encodingsMap.utf8 : ops.encodingVal); 997 return indexOfBuffer(buffer, val, byteOffset, encodingVal, dir); 998 } 999 1000 throw new ERR_INVALID_ARG_TYPE( 1001 'value', ['number', 'string', 'Buffer', 'Uint8Array'], val, 1002 ); 1003} 1004 1005Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) { 1006 return bidirectionalIndexOf(this, val, byteOffset, encoding, true); 1007}; 1008 1009Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) { 1010 return bidirectionalIndexOf(this, val, byteOffset, encoding, false); 1011}; 1012 1013Buffer.prototype.includes = function includes(val, byteOffset, encoding) { 1014 return this.indexOf(val, byteOffset, encoding) !== -1; 1015}; 1016 1017// Usage: 1018// buffer.fill(number[, offset[, end]]) 1019// buffer.fill(buffer[, offset[, end]]) 1020// buffer.fill(string[, offset[, end]][, encoding]) 1021Buffer.prototype.fill = function fill(value, offset, end, encoding) { 1022 return _fill(this, value, offset, end, encoding); 1023}; 1024 1025function _fill(buf, value, offset, end, encoding) { 1026 if (typeof value === 'string') { 1027 if (offset === undefined || typeof offset === 'string') { 1028 encoding = offset; 1029 offset = 0; 1030 end = buf.length; 1031 } else if (typeof end === 'string') { 1032 encoding = end; 1033 end = buf.length; 1034 } 1035 1036 const normalizedEncoding = normalizeEncoding(encoding); 1037 if (normalizedEncoding === undefined) { 1038 validateString(encoding, 'encoding'); 1039 throw new ERR_UNKNOWN_ENCODING(encoding); 1040 } 1041 1042 if (value.length === 0) { 1043 // If value === '' default to zero. 1044 value = 0; 1045 } else if (value.length === 1) { 1046 // Fast path: If `value` fits into a single byte, use that numeric value. 1047 if (normalizedEncoding === 'utf8') { 1048 const code = StringPrototypeCharCodeAt(value, 0); 1049 if (code < 128) { 1050 value = code; 1051 } 1052 } else if (normalizedEncoding === 'latin1') { 1053 value = StringPrototypeCharCodeAt(value, 0); 1054 } 1055 } 1056 } else { 1057 encoding = undefined; 1058 } 1059 1060 if (offset === undefined) { 1061 offset = 0; 1062 end = buf.length; 1063 } else { 1064 validateOffset(offset, 'offset'); 1065 // Invalid ranges are not set to a default, so can range check early. 1066 if (end === undefined) { 1067 end = buf.length; 1068 } else { 1069 validateOffset(end, 'end', 0, buf.length); 1070 } 1071 if (offset >= end) 1072 return buf; 1073 } 1074 1075 1076 if (typeof value === 'number') { 1077 // OOB check 1078 const byteLen = TypedArrayPrototypeGetByteLength(buf); 1079 const fillLength = end - offset; 1080 if (offset > end || fillLength + offset > byteLen) 1081 throw new ERR_BUFFER_OUT_OF_BOUNDS(); 1082 1083 TypedArrayPrototypeFill(buf, value, offset, end); 1084 } else { 1085 const res = bindingFill(buf, value, offset, end, encoding); 1086 if (res < 0) { 1087 if (res === -1) 1088 throw new ERR_INVALID_ARG_VALUE('value', value); 1089 throw new ERR_BUFFER_OUT_OF_BOUNDS(); 1090 } 1091 } 1092 1093 return buf; 1094} 1095 1096Buffer.prototype.write = function write(string, offset, length, encoding) { 1097 // Buffer#write(string); 1098 if (offset === undefined) { 1099 return this.utf8Write(string, 0, this.length); 1100 } 1101 // Buffer#write(string, encoding) 1102 if (length === undefined && typeof offset === 'string') { 1103 encoding = offset; 1104 length = this.length; 1105 offset = 0; 1106 1107 // Buffer#write(string, offset[, length][, encoding]) 1108 } else { 1109 validateOffset(offset, 'offset', 0, this.length); 1110 1111 const remaining = this.length - offset; 1112 1113 if (length === undefined) { 1114 length = remaining; 1115 } else if (typeof length === 'string') { 1116 encoding = length; 1117 length = remaining; 1118 } else { 1119 validateOffset(length, 'length', 0, this.length); 1120 if (length > remaining) 1121 length = remaining; 1122 } 1123 } 1124 1125 if (!encoding) 1126 return this.utf8Write(string, offset, length); 1127 1128 const ops = getEncodingOps(encoding); 1129 if (ops === undefined) 1130 throw new ERR_UNKNOWN_ENCODING(encoding); 1131 return ops.write(this, string, offset, length); 1132}; 1133 1134Buffer.prototype.toJSON = function toJSON() { 1135 if (this.length > 0) { 1136 const data = new Array(this.length); 1137 for (let i = 0; i < this.length; ++i) 1138 data[i] = this[i]; 1139 return { type: 'Buffer', data }; 1140 } 1141 return { type: 'Buffer', data: [] }; 1142}; 1143 1144function adjustOffset(offset, length) { 1145 // Use Math.trunc() to convert offset to an integer value that can be larger 1146 // than an Int32. Hence, don't use offset | 0 or similar techniques. 1147 offset = MathTrunc(offset); 1148 if (offset === 0) { 1149 return 0; 1150 } 1151 if (offset < 0) { 1152 offset += length; 1153 return offset > 0 ? offset : 0; 1154 } 1155 if (offset < length) { 1156 return offset; 1157 } 1158 return NumberIsNaN(offset) ? 0 : length; 1159} 1160 1161Buffer.prototype.subarray = function subarray(start, end) { 1162 const srcLength = this.length; 1163 start = adjustOffset(start, srcLength); 1164 end = end !== undefined ? adjustOffset(end, srcLength) : srcLength; 1165 const newLength = end > start ? end - start : 0; 1166 return new FastBuffer(this.buffer, this.byteOffset + start, newLength); 1167}; 1168 1169Buffer.prototype.slice = function slice(start, end) { 1170 return this.subarray(start, end); 1171}; 1172 1173function swap(b, n, m) { 1174 const i = b[n]; 1175 b[n] = b[m]; 1176 b[m] = i; 1177} 1178 1179Buffer.prototype.swap16 = function swap16() { 1180 // For Buffer.length < 128, it's generally faster to 1181 // do the swap in javascript. For larger buffers, 1182 // dropping down to the native code is faster. 1183 const len = this.length; 1184 if (len % 2 !== 0) 1185 throw new ERR_INVALID_BUFFER_SIZE('16-bits'); 1186 if (len < 128) { 1187 for (let i = 0; i < len; i += 2) 1188 swap(this, i, i + 1); 1189 return this; 1190 } 1191 return _swap16(this); 1192}; 1193 1194Buffer.prototype.swap32 = function swap32() { 1195 // For Buffer.length < 192, it's generally faster to 1196 // do the swap in javascript. For larger buffers, 1197 // dropping down to the native code is faster. 1198 const len = this.length; 1199 if (len % 4 !== 0) 1200 throw new ERR_INVALID_BUFFER_SIZE('32-bits'); 1201 if (len < 192) { 1202 for (let i = 0; i < len; i += 4) { 1203 swap(this, i, i + 3); 1204 swap(this, i + 1, i + 2); 1205 } 1206 return this; 1207 } 1208 return _swap32(this); 1209}; 1210 1211Buffer.prototype.swap64 = function swap64() { 1212 // For Buffer.length < 192, it's generally faster to 1213 // do the swap in javascript. For larger buffers, 1214 // dropping down to the native code is faster. 1215 const len = this.length; 1216 if (len % 8 !== 0) 1217 throw new ERR_INVALID_BUFFER_SIZE('64-bits'); 1218 if (len < 192) { 1219 for (let i = 0; i < len; i += 8) { 1220 swap(this, i, i + 7); 1221 swap(this, i + 1, i + 6); 1222 swap(this, i + 2, i + 5); 1223 swap(this, i + 3, i + 4); 1224 } 1225 return this; 1226 } 1227 return _swap64(this); 1228}; 1229 1230Buffer.prototype.toLocaleString = Buffer.prototype.toString; 1231 1232let transcode; 1233if (internalBinding('config').hasIntl) { 1234 const { 1235 icuErrName, 1236 transcode: _transcode, 1237 } = internalBinding('icu'); 1238 1239 // Transcodes the Buffer from one encoding to another, returning a new 1240 // Buffer instance. 1241 transcode = function transcode(source, fromEncoding, toEncoding) { 1242 if (!isUint8Array(source)) { 1243 throw new ERR_INVALID_ARG_TYPE('source', 1244 ['Buffer', 'Uint8Array'], source); 1245 } 1246 if (source.length === 0) return Buffer.alloc(0); 1247 1248 fromEncoding = normalizeEncoding(fromEncoding) || fromEncoding; 1249 toEncoding = normalizeEncoding(toEncoding) || toEncoding; 1250 const result = _transcode(source, fromEncoding, toEncoding); 1251 if (typeof result !== 'number') 1252 return result; 1253 1254 const code = icuErrName(result); 1255 const err = genericNodeError( 1256 `Unable to transcode Buffer [${code}]`, 1257 { code: code, errno: result }, 1258 ); 1259 throw err; 1260 }; 1261} 1262 1263function btoa(input) { 1264 // The implementation here has not been performance optimized in any way and 1265 // should not be. 1266 // Refs: https://github.com/nodejs/node/pull/38433#issuecomment-828426932 1267 if (arguments.length === 0) { 1268 throw new ERR_MISSING_ARGS('input'); 1269 } 1270 input = `${input}`; 1271 for (let n = 0; n < input.length; n++) { 1272 if (input[n].charCodeAt(0) > 0xff) 1273 throw lazyDOMException('Invalid character', 'InvalidCharacterError'); 1274 } 1275 const buf = Buffer.from(input, 'latin1'); 1276 return buf.toString('base64'); 1277} 1278 1279// Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode 1280const kForgivingBase64AllowedChars = [ 1281 // ASCII whitespace 1282 // Refs: https://infra.spec.whatwg.org/#ascii-whitespace 1283 0x09, 0x0A, 0x0C, 0x0D, 0x20, 1284 1285 // Uppercase letters 1286 ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('A') + i), 1287 1288 // Lowercase letters 1289 ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('a') + i), 1290 1291 // Decimal digits 1292 ...ArrayFrom({ length: 10 }, (_, i) => StringPrototypeCharCodeAt('0') + i), 1293 1294 0x2B, // + 1295 0x2F, // / 1296 0x3D, // = 1297]; 1298const kEqualSignIndex = ArrayPrototypeIndexOf(kForgivingBase64AllowedChars, 1299 0x3D); 1300 1301function atob(input) { 1302 // The implementation here has not been performance optimized in any way and 1303 // should not be. 1304 // Refs: https://github.com/nodejs/node/pull/38433#issuecomment-828426932 1305 if (arguments.length === 0) { 1306 throw new ERR_MISSING_ARGS('input'); 1307 } 1308 1309 input = `${input}`; 1310 let nonAsciiWhitespaceCharCount = 0; 1311 let equalCharCount = 0; 1312 1313 for (let n = 0; n < input.length; n++) { 1314 const index = ArrayPrototypeIndexOf( 1315 kForgivingBase64AllowedChars, 1316 StringPrototypeCharCodeAt(input, n)); 1317 1318 if (index > 4) { 1319 // The first 5 elements of `kForgivingBase64AllowedChars` are 1320 // ASCII whitespace char codes. 1321 nonAsciiWhitespaceCharCount++; 1322 1323 if (index === kEqualSignIndex) { 1324 equalCharCount++; 1325 } else if (equalCharCount) { 1326 // The `=` char is only allowed at the end. 1327 throw lazyDOMException('Invalid character', 'InvalidCharacterError'); 1328 } 1329 1330 if (equalCharCount > 2) { 1331 // Only one more `=` is permitted after the first equal sign. 1332 throw lazyDOMException('Invalid character', 'InvalidCharacterError'); 1333 } 1334 } else if (index === -1) { 1335 throw lazyDOMException('Invalid character', 'InvalidCharacterError'); 1336 } 1337 } 1338 1339 let reminder = nonAsciiWhitespaceCharCount % 4; 1340 1341 // See #2, #3, #4 - https://infra.spec.whatwg.org/#forgiving-base64 1342 if (!reminder) { 1343 // Remove all trailing `=` characters and get the new reminder. 1344 reminder = (nonAsciiWhitespaceCharCount - equalCharCount) % 4; 1345 } else if (equalCharCount) { 1346 // `=` should not in the input if there's a reminder. 1347 throw lazyDOMException('Invalid character', 'InvalidCharacterError'); 1348 } 1349 1350 // See #3 - https://infra.spec.whatwg.org/#forgiving-base64 1351 if (reminder === 1) { 1352 throw lazyDOMException( 1353 'The string to be decoded is not correctly encoded.', 1354 'InvalidCharacterError'); 1355 } 1356 1357 return Buffer.from(input, 'base64').toString('latin1'); 1358} 1359 1360function isUtf8(input) { 1361 if (isTypedArray(input) || isAnyArrayBuffer(input)) { 1362 return bindingIsUtf8(input); 1363 } 1364 1365 throw new ERR_INVALID_ARG_TYPE('input', ['TypedArray', 'Buffer'], input); 1366} 1367 1368function isAscii(input) { 1369 if (isTypedArray(input) || isAnyArrayBuffer(input)) { 1370 return bindingIsAscii(input); 1371 } 1372 1373 throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input); 1374} 1375 1376module.exports = { 1377 Buffer, 1378 SlowBuffer, 1379 transcode, 1380 isUtf8, 1381 isAscii, 1382 1383 // Legacy 1384 kMaxLength, 1385 kStringMaxLength, 1386 btoa, 1387 atob, 1388}; 1389 1390ObjectDefineProperties(module.exports, { 1391 constants: { 1392 __proto__: null, 1393 configurable: false, 1394 enumerable: true, 1395 value: constants, 1396 }, 1397 INSPECT_MAX_BYTES: { 1398 __proto__: null, 1399 configurable: true, 1400 enumerable: true, 1401 get() { return INSPECT_MAX_BYTES; }, 1402 set(val) { INSPECT_MAX_BYTES = val; }, 1403 }, 1404}); 1405 1406defineLazyProperties( 1407 module.exports, 1408 'internal/blob', 1409 ['Blob', 'resolveObjectURL'], 1410); 1411defineLazyProperties( 1412 module.exports, 1413 'internal/file', 1414 ['File'], 1415); 1416