diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..642b8c27 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: feross +tidelift: npm/buffer diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..817f3a70 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: Tests + +on: + push: + branches: + - main + pull_request: + +jobs: + unit: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # see https://nodejs.org/en/about/releases/ + node-version: [16.x, 18.x, 20.x] + + steps: + - uses: actions/checkout@main + - uses: actions/setup-node@main + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test + + standard: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@main + - uses: actions/setup-node@main + with: + # don't use lts/* to prevent hitting rate-limit + node-version: 20.x + - run: npm install + - run: npm run standard diff --git a/.npmignore b/.npmignore index 2aa460a8..eae8087f 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,5 @@ .airtap.yml +.github/ bin/ perf/ +test/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8c95fe19..00000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: node_js -node_js: -- lts/* -sudo: false -addons: - sauce_connect: true - hosts: - - airtap.local -env: - global: - - secure: AUsK+8fYSpwIMHcVt8Mu9SpG9RPHp4XDAwCQfpU3d5U65q8OVVC6C+XjvnNmEd2PoEJRHem8ZXEyRVfGM1sttKZLZP70TEKZOpOiRQnZiTQCAJ92TfGsDj/F4LoWSjUZUpfeg9b3iSp8G5dVw3+q9QZPIu6eykASK6bfcg//Cyg= - - secure: eQBKJWu7XbhAN4ZvOOhMenC0IPpoYj+wZVVzzsLwUppfJqlrHV0CUW8rJdvZNiaGhYhoyHTnAcynpTE5kZfg3XjevOvF8PGY5wUYCki9BI+rp+pvVPZE/DNUAQpFR2gd2nxMJ4kYv7GVb6i/DfuqJa0h8IuY4zcMuKWwbQd3Az8= diff --git a/AUTHORS.md b/AUTHORS.md index aa7240dc..3f4918c7 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -44,5 +44,31 @@ - adventure-yunfei (adventure030@gmail.com) - Emil Bay (github@tixz.dk) - Sam Sudar (sudar.sam@gmail.com) +- Volker Mische (volker.mische@gmail.com) +- David Walton (support@geekstocks.com) +- Сковорода Никита Андреевич (chalkerx@gmail.com) +- greenkeeper[bot] (greenkeeper[bot]@users.noreply.github.com) +- ukstv (sergey.ukustov@machinomy.com) +- Renée Kooi (renee@kooi.me) +- ranbochen (ranbochen@qq.com) +- Vladimir Borovik (bobahbdb@gmail.com) +- greenkeeper[bot] (23040076+greenkeeper[bot]@users.noreply.github.com) +- kumavis (aaron@kumavis.me) +- Sergey Ukustov (sergey.ukustov@machinomy.com) +- Fei Liu (liu.feiwood@gmail.com) +- Blaine Bublitz (blaine.bublitz@gmail.com) +- clement (clement@seald.io) +- Koushik Dutta (koushd@gmail.com) +- Jordan Harband (ljharb@gmail.com) +- Niklas Mischkulnig (mischnic@users.noreply.github.com) +- Nikolai Vavilov (vvnicholas@gmail.com) +- Fedor Nezhivoi (gyzerok@users.noreply.github.com) +- shuse2 (shus.toda@gmail.com) +- Peter Newman (peternewman@users.noreply.github.com) +- mathmakgakpak (44949126+mathmakgakpak@users.noreply.github.com) +- jkkang (jkkang@smartauth.kr) +- Deklan Webster (deklanw@gmail.com) +- Martin Heidegger (martin.heidegger@gmail.com) +- junderw (junderwood@bitcoinbank.co.jp) #### Generated by bin/update-authors.sh. diff --git a/README.md b/README.md index a2d9f87c..62b7d5d6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] +# buffer [![ci][ci-image]][ci-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] -[travis-image]: https://img.shields.io/travis/feross/buffer/master.svg -[travis-url]: https://travis-ci.org/feross/buffer +[ci-image]: https://img.shields.io/github/workflow/status/feross/buffer/ci/master +[ci-url]: https://github.com/feross/buffer/actions [npm-image]: https://img.shields.io/npm/v/buffer.svg [npm-url]: https://npmjs.org/package/buffer [downloads-image]: https://img.shields.io/npm/dm/buffer.svg @@ -9,7 +9,7 @@ [standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg [standard-url]: https://standardjs.com -#### The buffer module from [node.js](https://nodejs.org/), for the browser. +#### The buffer module from [node.js](https://nodejs.org), for the browser. [![saucelabs][saucelabs-image]][saucelabs-url] @@ -28,13 +28,12 @@ instance methods, and class methods that are supported. - Manipulate binary data like a boss, in all browsers! - Super fast. Backed by Typed Arrays (`Uint8Array`/`ArrayBuffer`, not `Object`) - Extremely small bundle size (**6.75KB minified + gzipped**, 51.9KB with comments) -- Excellent browser support (Chrome, Firefox, Edge, Safari 9+, IE 11, iOS 9+, Android, etc.) -- Preserves Node API exactly, with one minor difference (see below) +- Excellent browser support (Chrome, Firefox, Edge, Safari 11+, iOS 11+, Android, etc.) +- Preserves Node API exactly - Square-bracket `buf[4]` notation works! - Does not modify any browser prototypes or put anything on `window` - Comprehensive test suite (including all buffer tests from node.js core) - ## install To use this module directly (without browserify), install it: @@ -46,8 +45,7 @@ npm install buffer This module was previously called **native-buffer-browserify**, but please use **buffer** from now on. -A standalone bundle is available [here](https://wzrd.in/standalone/buffer), for non-browserify users. - +If you do not use a bundler, you can use the [standalone script](https://bundle.run/buffer). ## usage @@ -149,8 +147,8 @@ Alternatively, use the [`to-arraybuffer`](https://www.npmjs.com/package/to-array See perf tests in `/perf`. -`BrowserBuffer` is the browser `buffer` module (this repo). `Uint8Array` is included as a -sanity check (since `BrowserBuffer` uses `Uint8Array` under the hood, `Uint8Array` will +`BrowserBuffer` is the browser `buffer` module (this repo). `Uint8Array` is included as an +additional check (since `BrowserBuffer` uses `Uint8Array` under the hood, `Uint8Array` will always be at least a bit faster). Finally, `NodeBuffer` is the node.js buffer module, which is included to compare against. @@ -378,8 +376,8 @@ Then, to run tests in Node.js, run: To test locally in a browser, you can run: - npm run test-browser-es5-local # For ES5 browsers that don't support ES6 - npm run test-browser-es6-local # For ES6 compliant browsers + npm run test-browser-old-local # For ES5 browsers that don't support ES6 + npm run test-browser-new-local # For ES6 compliant browsers This will print out a URL that you can then open in a browser to run the tests, using [airtap](https://www.npmjs.com/package/airtap). @@ -403,6 +401,9 @@ To test that the code conforms to the style, `npm install` and run: This was originally forked from [buffer-browserify](https://github.com/toots/buffer-browserify). +## Security Policies and Procedures + +The `buffer` team and community take all security bugs in `buffer` seriously. Please see our [security policies and procedures](https://github.com/feross/security) document to learn how to report issues. ## license diff --git a/bin/airtap-es6.yml b/bin/airtap-new.yml similarity index 65% rename from bin/airtap-es6.yml rename to bin/airtap-new.yml index f24be1a6..d33ab0ac 100644 --- a/bin/airtap-es6.yml +++ b/bin/airtap-new.yml @@ -5,11 +5,9 @@ browsers: version: -1..latest - name: firefox version: -1..latest - - name: safari - version: 10..latest + # - name: safari + # version: 14..latest - name: microsoftedge version: -1..latest - - name: iphone - version: - - 10.3 - - latest + # - name: iphone + # version: latest diff --git a/bin/airtap-es5.yml b/bin/airtap-old.yml similarity index 57% rename from bin/airtap-es5.yml rename to bin/airtap-old.yml index aabfd65f..be7dbccb 100644 --- a/bin/airtap-es5.yml +++ b/bin/airtap-old.yml @@ -1,9 +1,7 @@ sauce_connect: true loopback: airtap.local browsers: - - name: ie - version: latest - name: safari - version: 9 + version: 11..13 - name: iphone - version: 9.3 + version: 11.3 diff --git a/bin/download-node-tests.js b/bin/download-node-tests.js index c05a98e6..e0d4fd9a 100755 --- a/bin/download-node-tests.js +++ b/bin/download-node-tests.js @@ -1,22 +1,22 @@ #!/usr/bin/env node -var concat = require('concat-stream') -var cp = require('child_process') -var fs = require('fs') -var hyperquest = require('hyperquest') -var path = require('path') -var split = require('split') -var through = require('through2') - -var url = 'https://api.github.com/repos/nodejs/node/contents' -var dirs = [ +const concat = require('concat-stream') +const cp = require('child_process') +const fs = require('fs') +const hyperquest = require('hyperquest') +const path = require('path') +const split = require('split') +const through = require('through2') + +const url = 'https://api.github.com/repos/nodejs/node/contents' +const dirs = [ '/test/parallel', '/test/pummel' ] cp.execSync('rm -rf node/test-*.js', { cwd: path.join(__dirname, '../test') }) -var httpOpts = { +const httpOpts = { headers: { 'User-Agent': null // auth if github rate-limits you... @@ -25,7 +25,7 @@ var httpOpts = { } dirs.forEach(function (dir) { - var req = hyperquest(url + dir, httpOpts) + const req = hyperquest(url + dir, httpOpts) req.pipe(concat(function (data) { if (req.response.statusCode !== 200) { throw new Error(url + dir + ': ' + data.toString()) @@ -57,7 +57,7 @@ function downloadBufferTests (dir, files) { console.log(file.download_url) - var out = path.join(__dirname, '../test/node', file.name) + const out = path.join(__dirname, '../test/node', file.name) hyperquest(file.download_url, httpOpts) .pipe(split()) .pipe(testfixer(file.name)) @@ -69,14 +69,14 @@ function downloadBufferTests (dir, files) { } function testfixer (filename) { - var firstline = true + let firstline = true return through(function (line, enc, cb) { line = line.toString() if (firstline) { // require buffer explicitly - var preamble = 'var Buffer = require(\'../../\').Buffer;' + const preamble = 'var Buffer = require(\'../../\').Buffer;' if (/use strict/.test(line)) line += '\n' + preamble else line += preamble + '\n' + line firstline = false diff --git a/bin/test.js b/bin/test.js index fca40457..ec557b2c 100644 --- a/bin/test.js +++ b/bin/test.js @@ -1,40 +1,34 @@ #!/usr/bin/env node -var cp = require('child_process') -var fs = require('fs') -var path = require('path') +const cp = require('child_process') +const fs = require('fs') +const path = require('path') -var shouldRunBrowserTests = !process.env.TRAVIS_PULL_REQUEST || - process.env.TRAVIS_PULL_REQUEST === 'false' - -var node = cp.spawn('npm', ['run', 'test-node'], { stdio: 'inherit' }) +const node = cp.spawn('npm', ['run', 'test-node'], { stdio: 'inherit' }) node.on('close', function (code) { - if (code === 0 && shouldRunBrowserTests) { - runBrowserTests() - } else { - process.exit(code) - } + if (code !== 0) return process.exit(code) + runBrowserTests() }) function runBrowserTests () { - var airtapYmlPath = path.join(__dirname, '..', '.airtap.yml') + const airtapYmlPath = path.join(__dirname, '..', '.airtap.yml') writeES5AirtapYml() - cp.spawn('npm', ['run', 'test-browser-es5'], { stdio: 'inherit' }) + cp.spawn('npm', ['run', 'test-browser-old'], { stdio: 'inherit' }) .on('close', function (code) { if (code !== 0) process.exit(code) writeES6AirtapYml() - cp.spawn('npm', ['run', 'test-browser-es6'], { stdio: 'inherit' }) + cp.spawn('npm', ['run', 'test-browser-new'], { stdio: 'inherit' }) .on('close', function (code) { process.exit(code) }) }) function writeES5AirtapYml () { - fs.writeFileSync(airtapYmlPath, fs.readFileSync(path.join(__dirname, 'airtap-es5.yml'))) + fs.writeFileSync(airtapYmlPath, fs.readFileSync(path.join(__dirname, 'airtap-old.yml'))) } function writeES6AirtapYml () { - fs.writeFileSync(airtapYmlPath, fs.readFileSync(path.join(__dirname, 'airtap-es6.yml'))) + fs.writeFileSync(airtapYmlPath, fs.readFileSync(path.join(__dirname, 'airtap-new.yml'))) } } diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 00000000..c276e4de --- /dev/null +++ b/index.d.ts @@ -0,0 +1,195 @@ +export class Buffer extends Uint8Array { + length: number + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): { type: 'Buffer', data: any[] }; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Uint8Array, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + subarray(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset?: number, noAssert?: boolean): number; + readUInt16BE(offset?: number, noAssert?: boolean): number; + readUInt32LE(offset?: number, noAssert?: boolean): number; + readUInt32BE(offset?: number, noAssert?: boolean): number; + readBigUInt64LE(offset?: number): BigInt; + readBigUInt64BE(offset?: number): BigInt; + readInt8(offset?: number, noAssert?: boolean): number; + readInt16LE(offset?: number, noAssert?: boolean): number; + readInt16BE(offset?: number, noAssert?: boolean): number; + readInt32LE(offset?: number, noAssert?: boolean): number; + readInt32BE(offset?: number, noAssert?: boolean): number; + readBigInt64LE(offset?: number): BigInt; + readBigInt64BE(offset?: number): BigInt; + readFloatLE(offset?: number, noAssert?: boolean): number; + readFloatBE(offset?: number, noAssert?: boolean): number; + readDoubleLE(offset?: number, noAssert?: boolean): number; + readDoubleBE(offset?: number, noAssert?: boolean): number; + reverse(): this; + swap16(): Buffer; + swap32(): Buffer; + swap64(): Buffer; + writeUInt8(value: number, offset?: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset?: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset?: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset?: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset?: number, noAssert?: boolean): number; + writeBigUInt64LE(value: BigInt, offset?: number): number; + writeBigUInt64BE(value: BigInt, offset?: number): number; + writeInt8(value: number, offset?: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset?: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset?: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset?: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset?: number, noAssert?: boolean): number; + writeBigInt64LE(value: BigInt, offset?: number): number; + writeBigInt64BE(value: BigInt, offset?: number): number; + writeFloatLE(value: number, offset?: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset?: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset?: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset?: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): this; + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; + + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ + constructor (str: string, encoding?: string); + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ + constructor (size: number); + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + constructor (array: Uint8Array); + /** + * Produces a Buffer backed by the same allocated memory as + * the given {ArrayBuffer}. + * + * + * @param arrayBuffer The ArrayBuffer with which to share memory. + */ + constructor (arrayBuffer: ArrayBuffer); + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + constructor (array: any[]); + /** + * Copies the passed {buffer} data onto a new {Buffer} instance. + * + * @param buffer The buffer to copy. + */ + constructor (buffer: Buffer); + prototype: Buffer; + /** + * Allocates a new Buffer using an {array} of octets. + * + * @param array + */ + static from(array: any[]): Buffer; + /** + * When passed a reference to the .buffer property of a TypedArray instance, + * the newly created Buffer will share the same allocated memory as the TypedArray. + * The optional {byteOffset} and {length} arguments specify a memory range + * within the {arrayBuffer} that will be shared by the Buffer. + * + * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() + * @param byteOffset + * @param length + */ + static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + /** + * Copies the passed {buffer} data onto a new Buffer instance. + * + * @param buffer + */ + static from(buffer: Buffer | Uint8Array): Buffer; + /** + * Creates a new Buffer containing the given JavaScript string {str}. + * If provided, the {encoding} parameter identifies the character encoding. + * If not provided, {encoding} defaults to 'utf8'. + * + * @param str + */ + static from(str: string, encoding?: string): Buffer; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + static isBuffer(obj: any): obj is Buffer; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + static isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ + static byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ + static concat(list: Uint8Array[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + static compare(buf1: Uint8Array, buf2: Uint8Array): number; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + * @param fill if specified, buffer will be initialized by calling buf.fill(fill). + * If parameter is omitted, buffer will be filled with zeros. + * @param encoding encoding used for call to buf.fill while initializing + */ + static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + static allocUnsafe(size: number): Buffer; + /** + * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + static allocUnsafeSlow(size: number): Buffer; +} diff --git a/index.js b/index.js index 476a79d6..2731dea6 100644 --- a/index.js +++ b/index.js @@ -8,16 +8,36 @@ 'use strict' -var base64 = require('base64-js') -var ieee754 = require('ieee754') +const base64 = require('base64-js') +const ieee754 = require('ieee754') +const customInspectSymbol = + (typeof Symbol === 'function' && typeof Symbol['for'] === 'function') // eslint-disable-line dot-notation + ? Symbol['for']('nodejs.util.inspect.custom') // eslint-disable-line dot-notation + : null exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 -var K_MAX_LENGTH = 0x7fffffff +const K_MAX_LENGTH = 0x7fffffff exports.kMaxLength = K_MAX_LENGTH +/** + * Not used internally, but exported to maintain api compatability + * Uses 32-bit implementation value from Node defined in String:kMaxLength + * + * @see https://github.com/nodejs/node/blob/main/deps/v8/include/v8-primitive.h#L126 + * @see https://github.com/nodejs/node/blob/main/src/node_buffer.cc#L1298 + * @see https://github.com/nodejs/node/blob/main/lib/buffer.js#L142 + */ +const K_STRING_MAX_LENGTH = (1 << 28) - 16 +exports.kStringMaxLength = K_STRING_MAX_LENGTH + +exports.constants = { + MAX_LENGTH: K_MAX_LENGTH, + MAX_STRING_LENGTH: K_STRING_MAX_LENGTH +} + /** * If `Buffer.TYPED_ARRAY_SUPPORT`: * === true Use Uint8Array implementation (fastest) @@ -43,10 +63,12 @@ if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && } function typedArraySupport () { - // Can typed array instances can be augmented? + // Can typed array instances be augmented? try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} + const arr = new Uint8Array(1) + const proto = { foo: function () { return 42 } } + Object.setPrototypeOf(proto, Uint8Array.prototype) + Object.setPrototypeOf(arr, proto) return arr.foo() === 42 } catch (e) { return false @@ -74,8 +96,8 @@ function createBuffer (length) { throw new RangeError('The value "' + length + '" is invalid for option "size"') } // Return an augmented `Uint8Array` instance - var buf = new Uint8Array(length) - buf.__proto__ = Buffer.prototype + const buf = new Uint8Array(length) + Object.setPrototypeOf(buf, Buffer.prototype) return buf } @@ -102,17 +124,6 @@ function Buffer (arg, encodingOrOffset, length) { return from(arg, encodingOrOffset, length) } -// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 -if (typeof Symbol !== 'undefined' && Symbol.species != null && - Buffer[Symbol.species] === Buffer) { - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true, - enumerable: false, - writable: false - }) -} - Buffer.poolSize = 8192 // not used by this implementation function from (value, encodingOrOffset, length) { @@ -121,11 +132,11 @@ function from (value, encodingOrOffset, length) { } if (ArrayBuffer.isView(value)) { - return fromArrayLike(value) + return fromArrayView(value) } if (value == null) { - throw TypeError( + throw new TypeError( 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + 'or Array-like Object. Received type ' + (typeof value) ) @@ -136,25 +147,29 @@ function from (value, encodingOrOffset, length) { return fromArrayBuffer(value, encodingOrOffset, length) } + if (typeof SharedArrayBuffer !== 'undefined' && + (isInstance(value, SharedArrayBuffer) || + (value && isInstance(value.buffer, SharedArrayBuffer)))) { + return fromArrayBuffer(value, encodingOrOffset, length) + } + if (typeof value === 'number') { throw new TypeError( 'The "value" argument must not be of type number. Received type number' ) } - var valueOf = value.valueOf && value.valueOf() + const valueOf = value.valueOf && value.valueOf() if (valueOf != null && valueOf !== value) { return Buffer.from(valueOf, encodingOrOffset, length) } - var b = fromObject(value) + const b = fromObject(value) if (b) return b if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null && typeof value[Symbol.toPrimitive] === 'function') { - return Buffer.from( - value[Symbol.toPrimitive]('string'), encodingOrOffset, length - ) + return Buffer.from(value[Symbol.toPrimitive]('string'), encodingOrOffset, length) } throw new TypeError( @@ -177,8 +192,8 @@ Buffer.from = function (value, encodingOrOffset, length) { // Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: // https://github.com/feross/buffer/pull/148 -Buffer.prototype.__proto__ = Uint8Array.prototype -Buffer.__proto__ = Uint8Array +Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype) +Object.setPrototypeOf(Buffer, Uint8Array) function assertSize (size) { if (typeof size !== 'number') { @@ -196,7 +211,7 @@ function alloc (size, fill, encoding) { if (fill !== undefined) { // Only pay attention to encoding if it's a string. This // prevents accidentally sending in a number that would - // be interpretted as a start offset. + // be interpreted as a start offset. return typeof encoding === 'string' ? createBuffer(size).fill(fill, encoding) : createBuffer(size).fill(fill) @@ -239,10 +254,10 @@ function fromString (string, encoding) { throw new TypeError('Unknown encoding: ' + encoding) } - var length = byteLength(string, encoding) | 0 - var buf = createBuffer(length) + const length = byteLength(string, encoding) | 0 + let buf = createBuffer(length) - var actual = buf.write(string, encoding) + const actual = buf.write(string, encoding) if (actual !== length) { // Writing a hex string, for example, that contains invalid characters will @@ -255,14 +270,22 @@ function fromString (string, encoding) { } function fromArrayLike (array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - var buf = createBuffer(length) - for (var i = 0; i < length; i += 1) { + const length = array.length < 0 ? 0 : checked(array.length) | 0 + const buf = createBuffer(length) + for (let i = 0; i < length; i += 1) { buf[i] = array[i] & 255 } return buf } +function fromArrayView (arrayView) { + if (isInstance(arrayView, Uint8Array)) { + const copy = new Uint8Array(arrayView) + return fromArrayBuffer(copy.buffer, copy.byteOffset, copy.byteLength) + } + return fromArrayLike(arrayView) +} + function fromArrayBuffer (array, byteOffset, length) { if (byteOffset < 0 || array.byteLength < byteOffset) { throw new RangeError('"offset" is outside of buffer bounds') @@ -272,7 +295,7 @@ function fromArrayBuffer (array, byteOffset, length) { throw new RangeError('"length" is outside of buffer bounds') } - var buf + let buf if (byteOffset === undefined && length === undefined) { buf = new Uint8Array(array) } else if (length === undefined) { @@ -282,14 +305,15 @@ function fromArrayBuffer (array, byteOffset, length) { } // Return an augmented `Uint8Array` instance - buf.__proto__ = Buffer.prototype + Object.setPrototypeOf(buf, Buffer.prototype) + return buf } function fromObject (obj) { if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - var buf = createBuffer(len) + const len = checked(obj.length) | 0 + const buf = createBuffer(len) if (buf.length === 0) { return buf @@ -344,10 +368,10 @@ Buffer.compare = function compare (a, b) { if (a === b) return 0 - var x = a.length - var y = b.length + let x = a.length + let y = b.length - for (var i = 0, len = Math.min(x, y); i < len; ++i) { + for (let i = 0, len = Math.min(x, y); i < len; ++i) { if (a[i] !== b[i]) { x = a[i] y = b[i] @@ -389,7 +413,7 @@ Buffer.concat = function concat (list, length) { return Buffer.alloc(0) } - var i + let i if (length === undefined) { length = 0 for (i = 0; i < list.length; ++i) { @@ -397,18 +421,28 @@ Buffer.concat = function concat (list, length) { } } - var buffer = Buffer.allocUnsafe(length) - var pos = 0 + const buffer = Buffer.allocUnsafe(length) + let pos = 0 for (i = 0; i < list.length; ++i) { - var buf = list[i] + let buf = list[i] if (isInstance(buf, Uint8Array)) { - buf = Buffer.from(buf) - } - if (!Buffer.isBuffer(buf)) { - throw new TypeError('The "list" argument must be one of type ' + - 'Array, Buffer, or Uint8Array') + if (pos + buf.length > buffer.length) { + if (!Buffer.isBuffer(buf)) { + buf = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength) + } + buf.copy(buffer, pos) + } else { + Uint8Array.prototype.set.call( + buffer, + buf, + pos + ) + } + } else if (!Buffer.isBuffer(buf)) { + throw new TypeError('The "list" argument must be one of type Array, Buffer, or Uint8Array') + } else { + buf.copy(buffer, pos) } - buf.copy(buffer, pos) pos += buf.length } return buffer @@ -428,12 +462,12 @@ function byteLength (string, encoding) { ) } - var len = string.length - var mustMatch = (arguments.length > 2 && arguments[2] === true) + const len = string.length + const mustMatch = (arguments.length > 2 && arguments[2] === true) if (!mustMatch && len === 0) return 0 // Use a for loop to avoid recursion - var loweredCase = false + let loweredCase = false for (;;) { switch (encoding) { case 'ascii': @@ -464,7 +498,7 @@ function byteLength (string, encoding) { Buffer.byteLength = byteLength function slowToString (encoding, start, end) { - var loweredCase = false + let loweredCase = false // No need to verify that "this.length <= MAX_UINT32" since it's a read-only // property of a typed array. @@ -490,7 +524,7 @@ function slowToString (encoding, start, end) { return '' } - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + // Force coercion to uint32. This will also coerce falsey/NaN values to 0. end >>>= 0 start >>>= 0 @@ -542,28 +576,28 @@ function slowToString (encoding, start, end) { Buffer.prototype._isBuffer = true function swap (b, n, m) { - var i = b[n] + const i = b[n] b[n] = b[m] b[m] = i } Buffer.prototype.swap16 = function swap16 () { - var len = this.length + const len = this.length if (len % 2 !== 0) { throw new RangeError('Buffer size must be a multiple of 16-bits') } - for (var i = 0; i < len; i += 2) { + for (let i = 0; i < len; i += 2) { swap(this, i, i + 1) } return this } Buffer.prototype.swap32 = function swap32 () { - var len = this.length + const len = this.length if (len % 4 !== 0) { throw new RangeError('Buffer size must be a multiple of 32-bits') } - for (var i = 0; i < len; i += 4) { + for (let i = 0; i < len; i += 4) { swap(this, i, i + 3) swap(this, i + 1, i + 2) } @@ -571,11 +605,11 @@ Buffer.prototype.swap32 = function swap32 () { } Buffer.prototype.swap64 = function swap64 () { - var len = this.length + const len = this.length if (len % 8 !== 0) { throw new RangeError('Buffer size must be a multiple of 64-bits') } - for (var i = 0; i < len; i += 8) { + for (let i = 0; i < len; i += 8) { swap(this, i, i + 7) swap(this, i + 1, i + 6) swap(this, i + 2, i + 5) @@ -585,7 +619,7 @@ Buffer.prototype.swap64 = function swap64 () { } Buffer.prototype.toString = function toString () { - var length = this.length + const length = this.length if (length === 0) return '' if (arguments.length === 0) return utf8Slice(this, 0, length) return slowToString.apply(this, arguments) @@ -600,12 +634,15 @@ Buffer.prototype.equals = function equals (b) { } Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES + let str = '' + const max = exports.INSPECT_MAX_BYTES str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim() if (this.length > max) str += ' ... ' return '' } +if (customInspectSymbol) { + Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect +} Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { if (isInstance(target, Uint8Array)) { @@ -652,14 +689,14 @@ Buffer.prototype.compare = function compare (target, start, end, thisStart, this if (this === target) return 0 - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) + let x = thisEnd - thisStart + let y = end - start + const len = Math.min(x, y) - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) + const thisCopy = this.slice(thisStart, thisEnd) + const targetCopy = target.slice(start, end) - for (var i = 0; i < len; ++i) { + for (let i = 0; i < len; ++i) { if (thisCopy[i] !== targetCopy[i]) { x = thisCopy[i] y = targetCopy[i] @@ -742,7 +779,7 @@ function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) } } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + return arrayIndexOf(buffer, [val], byteOffset, encoding, dir) } throw new TypeError('The "value" argument must be one of type ' + @@ -750,9 +787,9 @@ function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { } function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length + let indexSize = 1 + let arrLength = arr.length + let valLength = val.length if (encoding !== undefined) { encoding = String(encoding).toLowerCase() @@ -776,9 +813,9 @@ function arrayIndexOf (arr, val, byteOffset, encoding, dir) { } } - var i + let i if (dir) { - var foundIndex = -1 + let foundIndex = -1 for (i = byteOffset; i < arrLength; i++) { if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { if (foundIndex === -1) foundIndex = i @@ -791,8 +828,8 @@ function arrayIndexOf (arr, val, byteOffset, encoding, dir) { } else { if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { + let found = true + for (let j = 0; j < valLength; j++) { if (read(arr, i + j) !== read(val, j)) { found = false break @@ -819,7 +856,7 @@ Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) function hexWrite (buf, string, offset, length) { offset = Number(offset) || 0 - var remaining = buf.length - offset + const remaining = buf.length - offset if (!length) { length = remaining } else { @@ -829,17 +866,26 @@ function hexWrite (buf, string, offset, length) { } } - var strLen = string.length + const strLen = string.length - if (length > strLen / 2) { - length = strLen / 2 + if (length > (strLen >>> 1)) { + length = strLen >>> 1 } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (numberIsNaN(parsed)) return i - buf[offset + i] = parsed + + for (let i = 0; i < length; ++i) { + const a = string.charCodeAt(i * 2 + 0) + const b = string.charCodeAt(i * 2 + 1) + const hi = hexCharValueTable[a & 0x7f] + const lo = hexCharValueTable[b & 0x7f] + + if ((a | b | hi | lo) & ~0x7f) { + return i + } + + buf[offset + i] = (hi << 4) | lo } - return i + + return length } function utf8Write (buf, string, offset, length) { @@ -850,10 +896,6 @@ function asciiWrite (buf, string, offset, length) { return blitBuffer(asciiToBytes(string), buf, offset, length) } -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - function base64Write (buf, string, offset, length) { return blitBuffer(base64ToBytes(string), buf, offset, length) } @@ -889,7 +931,7 @@ Buffer.prototype.write = function write (string, offset, length, encoding) { ) } - var remaining = this.length - offset + const remaining = this.length - offset if (length === undefined || length > remaining) length = remaining if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { @@ -898,7 +940,7 @@ Buffer.prototype.write = function write (string, offset, length, encoding) { if (!encoding) encoding = 'utf8' - var loweredCase = false + let loweredCase = false for (;;) { switch (encoding) { case 'hex': @@ -909,11 +951,9 @@ Buffer.prototype.write = function write (string, offset, length, encoding) { return utf8Write(this, string, offset, length) case 'ascii': - return asciiWrite(this, string, offset, length) - case 'latin1': case 'binary': - return latin1Write(this, string, offset, length) + return asciiWrite(this, string, offset, length) case 'base64': // Warning: maxLength not taken into account in base64Write @@ -936,7 +976,7 @@ Buffer.prototype.write = function write (string, offset, length, encoding) { Buffer.prototype.toJSON = function toJSON () { return { type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) + data: Array.prototype.slice.call(this, 0) } } @@ -950,19 +990,22 @@ function base64Slice (buf, start, end) { function utf8Slice (buf, start, end) { end = Math.min(buf.length, end) - var res = [] + const res = [] - var i = start + let i = start while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 + const firstByte = buf[i] + let codePoint = null + let bytesPerSequence = (firstByte > 0xEF) + ? 4 + : (firstByte > 0xDF) + ? 3 + : (firstByte > 0xBF) + ? 2 + : 1 if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint + let secondByte, thirdByte, fourthByte, tempCodePoint switch (bytesPerSequence) { case 1: @@ -1024,17 +1067,17 @@ function utf8Slice (buf, start, end) { // Based on http://stackoverflow.com/a/22747272/680742, the browser with // the lowest limit is Chrome, with 0x10000 args. // We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 +const MAX_ARGUMENTS_LENGTH = 0x1000 function decodeCodePointsArray (codePoints) { - var len = codePoints.length + const len = codePoints.length if (len <= MAX_ARGUMENTS_LENGTH) { return String.fromCharCode.apply(String, codePoints) // avoid extra slice() } // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 + let res = '' + let i = 0 while (i < len) { res += String.fromCharCode.apply( String, @@ -1045,49 +1088,50 @@ function decodeCodePointsArray (codePoints) { } function asciiSlice (buf, start, end) { - var ret = '' + let ret = '' end = Math.min(buf.length, end) - for (var i = start; i < end; ++i) { + for (let i = start; i < end; ++i) { ret += String.fromCharCode(buf[i] & 0x7F) } return ret } function latin1Slice (buf, start, end) { - var ret = '' + let ret = '' end = Math.min(buf.length, end) - for (var i = start; i < end; ++i) { + for (let i = start; i < end; ++i) { ret += String.fromCharCode(buf[i]) } return ret } function hexSlice (buf, start, end) { - var len = buf.length + const len = buf.length if (!start || start < 0) start = 0 if (!end || end < 0 || end > len) end = len - var out = '' - for (var i = start; i < end; ++i) { - out += toHex(buf[i]) + let out = '' + for (let i = start; i < end; ++i) { + out += hexSliceLookupTable[buf[i]] } return out } function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { + const bytes = buf.slice(start, end) + let res = '' + // If bytes.length is odd, the last 8 bits must be ignored (same as node.js) + for (let i = 0; i < bytes.length - 1; i += 2) { res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256)) } return res } Buffer.prototype.slice = function slice (start, end) { - var len = this.length + const len = this.length start = ~~start end = end === undefined ? len : ~~end @@ -1107,9 +1151,10 @@ Buffer.prototype.slice = function slice (start, end) { if (end < start) end = start - var newBuf = this.subarray(start, end) + const newBuf = this.subarray(start, end) // Return an augmented `Uint8Array` instance - newBuf.__proto__ = Buffer.prototype + Object.setPrototypeOf(newBuf, Buffer.prototype) + return newBuf } @@ -1121,14 +1166,15 @@ function checkOffset (offset, ext, length) { if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') } +Buffer.prototype.readUintLE = Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) - var val = this[offset] - var mul = 1 - var i = 0 + let val = this[offset] + let mul = 1 + let i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } @@ -1136,6 +1182,7 @@ Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) return val } +Buffer.prototype.readUintBE = Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 @@ -1143,8 +1190,8 @@ Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) checkOffset(offset, byteLength, this.length) } - var val = this[offset + --byteLength] - var mul = 1 + let val = this[offset + --byteLength] + let mul = 1 while (byteLength > 0 && (mul *= 0x100)) { val += this[offset + --byteLength] * mul } @@ -1152,24 +1199,28 @@ Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) return val } +Buffer.prototype.readUint8 = Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 1, this.length) return this[offset] } +Buffer.prototype.readUint16LE = Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } +Buffer.prototype.readUint16BE = Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } +Buffer.prototype.readUint32LE = Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) @@ -1180,6 +1231,7 @@ Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { (this[offset + 3] * 0x1000000) } +Buffer.prototype.readUint32BE = Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) @@ -1190,14 +1242,58 @@ Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { this[offset + 3]) } +Buffer.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE (offset) { + offset = offset >>> 0 + validateNumber(offset, 'offset') + const first = this[offset] + const last = this[offset + 7] + if (first === undefined || last === undefined) { + boundsError(offset, this.length - 8) + } + + const lo = first + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 24 + + const hi = this[++offset] + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + last * 2 ** 24 + + return BigInt(lo) + (BigInt(hi) << BigInt(32)) +}) + +Buffer.prototype.readBigUInt64BE = defineBigIntMethod(function readBigUInt64BE (offset) { + offset = offset >>> 0 + validateNumber(offset, 'offset') + const first = this[offset] + const last = this[offset + 7] + if (first === undefined || last === undefined) { + boundsError(offset, this.length - 8) + } + + const hi = first * 2 ** 24 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + this[++offset] + + const lo = this[++offset] * 2 ** 24 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + last + + return (BigInt(hi) << BigInt(32)) + BigInt(lo) +}) + Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) - var val = this[offset] - var mul = 1 - var i = 0 + let val = this[offset] + let mul = 1 + let i = 0 while (++i < byteLength && (mul *= 0x100)) { val += this[offset + i] * mul } @@ -1213,9 +1309,9 @@ Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { byteLength = byteLength >>> 0 if (!noAssert) checkOffset(offset, byteLength, this.length) - var i = byteLength - var mul = 1 - var val = this[offset + --i] + let i = byteLength + let mul = 1 + let val = this[offset + --i] while (i > 0 && (mul *= 0x100)) { val += this[offset + --i] * mul } @@ -1236,14 +1332,14 @@ Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) + const val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) + const val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } @@ -1267,6 +1363,48 @@ Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { (this[offset + 3]) } +Buffer.prototype.readBigInt64LE = defineBigIntMethod(function readBigInt64LE (offset) { + offset = offset >>> 0 + validateNumber(offset, 'offset') + const first = this[offset] + const last = this[offset + 7] + if (first === undefined || last === undefined) { + boundsError(offset, this.length - 8) + } + + const val = this[offset + 4] + + this[offset + 5] * 2 ** 8 + + this[offset + 6] * 2 ** 16 + + (last << 24) // Overflow + + return (BigInt(val) << BigInt(32)) + + BigInt(first + + this[++offset] * 2 ** 8 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 24) +}) + +Buffer.prototype.readBigInt64BE = defineBigIntMethod(function readBigInt64BE (offset) { + offset = offset >>> 0 + validateNumber(offset, 'offset') + const first = this[offset] + const last = this[offset + 7] + if (first === undefined || last === undefined) { + boundsError(offset, this.length - 8) + } + + const val = (first << 24) + // Overflow + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + this[++offset] + + return (BigInt(val) << BigInt(32)) + + BigInt(this[++offset] * 2 ** 24 + + this[++offset] * 2 ** 16 + + this[++offset] * 2 ** 8 + + last) +}) + Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { offset = offset >>> 0 if (!noAssert) checkOffset(offset, 4, this.length) @@ -1297,17 +1435,18 @@ function checkInt (buf, value, offset, ext, max, min) { if (offset + ext > buf.length) throw new RangeError('Index out of range') } +Buffer.prototype.writeUintLE = Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 + const maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } - var mul = 1 - var i = 0 + let mul = 1 + let i = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF @@ -1316,17 +1455,18 @@ Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, return offset + byteLength } +Buffer.prototype.writeUintBE = Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 byteLength = byteLength >>> 0 if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 + const maxBytes = Math.pow(2, 8 * byteLength) - 1 checkInt(this, value, offset, byteLength, maxBytes, 0) } - var i = byteLength - 1 - var mul = 1 + let i = byteLength - 1 + let mul = 1 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xFF @@ -1335,6 +1475,7 @@ Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, return offset + byteLength } +Buffer.prototype.writeUint8 = Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { value = +value offset = offset >>> 0 @@ -1343,6 +1484,7 @@ Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { return offset + 1 } +Buffer.prototype.writeUint16LE = Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { value = +value offset = offset >>> 0 @@ -1352,6 +1494,7 @@ Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert return offset + 2 } +Buffer.prototype.writeUint16BE = Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { value = +value offset = offset >>> 0 @@ -1361,6 +1504,7 @@ Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert return offset + 2 } +Buffer.prototype.writeUint32LE = Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { value = +value offset = offset >>> 0 @@ -1372,6 +1516,7 @@ Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert return offset + 4 } +Buffer.prototype.writeUint32BE = Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { value = +value offset = offset >>> 0 @@ -1383,18 +1528,70 @@ Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert return offset + 4 } +function wrtBigUInt64LE (buf, value, offset, min, max) { + checkIntBI(value, min, max, buf, offset, 7) + + let lo = Number(value & BigInt(0xffffffff)) + buf[offset++] = lo + lo = lo >> 8 + buf[offset++] = lo + lo = lo >> 8 + buf[offset++] = lo + lo = lo >> 8 + buf[offset++] = lo + let hi = Number(value >> BigInt(32) & BigInt(0xffffffff)) + buf[offset++] = hi + hi = hi >> 8 + buf[offset++] = hi + hi = hi >> 8 + buf[offset++] = hi + hi = hi >> 8 + buf[offset++] = hi + return offset +} + +function wrtBigUInt64BE (buf, value, offset, min, max) { + checkIntBI(value, min, max, buf, offset, 7) + + let lo = Number(value & BigInt(0xffffffff)) + buf[offset + 7] = lo + lo = lo >> 8 + buf[offset + 6] = lo + lo = lo >> 8 + buf[offset + 5] = lo + lo = lo >> 8 + buf[offset + 4] = lo + let hi = Number(value >> BigInt(32) & BigInt(0xffffffff)) + buf[offset + 3] = hi + hi = hi >> 8 + buf[offset + 2] = hi + hi = hi >> 8 + buf[offset + 1] = hi + hi = hi >> 8 + buf[offset] = hi + return offset + 8 +} + +Buffer.prototype.writeBigUInt64LE = defineBigIntMethod(function writeBigUInt64LE (value, offset = 0) { + return wrtBigUInt64LE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff')) +}) + +Buffer.prototype.writeBigUInt64BE = defineBigIntMethod(function writeBigUInt64BE (value, offset = 0) { + return wrtBigUInt64BE(this, value, offset, BigInt(0), BigInt('0xffffffffffffffff')) +}) + Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset >>> 0 if (!noAssert) { - var limit = Math.pow(2, (8 * byteLength) - 1) + const limit = Math.pow(2, (8 * byteLength) - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } - var i = 0 - var mul = 1 - var sub = 0 + let i = 0 + let mul = 1 + let sub = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { @@ -1410,14 +1607,14 @@ Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, no value = +value offset = offset >>> 0 if (!noAssert) { - var limit = Math.pow(2, (8 * byteLength) - 1) + const limit = Math.pow(2, (8 * byteLength) - 1) checkInt(this, value, offset, byteLength, limit - 1, -limit) } - var i = byteLength - 1 - var mul = 1 - var sub = 0 + let i = byteLength - 1 + let mul = 1 + let sub = 0 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { @@ -1479,6 +1676,14 @@ Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) return offset + 4 } +Buffer.prototype.writeBigInt64LE = defineBigIntMethod(function writeBigInt64LE (value, offset = 0) { + return wrtBigUInt64LE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff')) +}) + +Buffer.prototype.writeBigInt64BE = defineBigIntMethod(function writeBigInt64BE (value, offset = 0) { + return wrtBigUInt64BE(this, value, offset, -BigInt('0x8000000000000000'), BigInt('0x7fffffffffffffff')) +}) + function checkIEEE754 (buf, value, offset, ext, max, min) { if (offset + ext > buf.length) throw new RangeError('Index out of range') if (offset < 0) throw new RangeError('Index out of range') @@ -1546,16 +1751,11 @@ Buffer.prototype.copy = function copy (target, targetStart, start, end) { end = target.length - targetStart + start } - var len = end - start + const len = end - start if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') { // Use built-in when available, missing from IE11 this.copyWithin(targetStart, start, end) - } else if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (var i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } } else { Uint8Array.prototype.set.call( target, @@ -1589,7 +1789,7 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) { throw new TypeError('Unknown encoding: ' + encoding) } if (val.length === 1) { - var code = val.charCodeAt(0) + const code = val.charCodeAt(0) if ((encoding === 'utf8' && code < 128) || encoding === 'latin1') { // Fast path: If `val` fits into a single byte, use that numeric value. @@ -1598,6 +1798,8 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) { } } else if (typeof val === 'number') { val = val & 255 + } else if (typeof val === 'boolean') { + val = Number(val) } // Invalid ranges are not set to a default, so can range check early. @@ -1614,16 +1816,16 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) { if (!val) val = 0 - var i + let i if (typeof val === 'number') { for (i = start; i < end; ++i) { this[i] = val } } else { - var bytes = Buffer.isBuffer(val) + const bytes = Buffer.isBuffer(val) ? val : Buffer.from(val, encoding) - var len = bytes.length + const len = bytes.length if (len === 0) { throw new TypeError('The value "' + val + '" is invalid for argument "value"') @@ -1636,10 +1838,143 @@ Buffer.prototype.fill = function fill (val, start, end, encoding) { return this } +// CUSTOM ERRORS +// ============= + +// Simplified versions from Node, changed for Buffer-only usage +const errors = {} +function E (sym, getMessage, Base) { + errors[sym] = class NodeError extends Base { + constructor () { + super() + + Object.defineProperty(this, 'message', { + value: getMessage.apply(this, arguments), + writable: true, + configurable: true + }) + + // Add the error code to the name to include it in the stack trace. + this.name = `${this.name} [${sym}]` + // Access the stack to generate the error message including the error code + // from the name. + this.stack // eslint-disable-line no-unused-expressions + // Reset the name to the actual name. + delete this.name + } + + get code () { + return sym + } + + set code (value) { + Object.defineProperty(this, 'code', { + configurable: true, + enumerable: true, + value, + writable: true + }) + } + + toString () { + return `${this.name} [${sym}]: ${this.message}` + } + } +} + +E('ERR_BUFFER_OUT_OF_BOUNDS', + function (name) { + if (name) { + return `${name} is outside of buffer bounds` + } + + return 'Attempt to access memory outside buffer bounds' + }, RangeError) +E('ERR_INVALID_ARG_TYPE', + function (name, actual) { + return `The "${name}" argument must be of type number. Received type ${typeof actual}` + }, TypeError) +E('ERR_OUT_OF_RANGE', + function (str, range, input) { + let msg = `The value of "${str}" is out of range.` + let received = input + if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) { + received = addNumericalSeparator(String(input)) + } else if (typeof input === 'bigint') { + received = String(input) + if (input > BigInt(2) ** BigInt(32) || input < -(BigInt(2) ** BigInt(32))) { + received = addNumericalSeparator(received) + } + received += 'n' + } + msg += ` It must be ${range}. Received ${received}` + return msg + }, RangeError) + +function addNumericalSeparator (val) { + let res = '' + let i = val.length + const start = val[0] === '-' ? 1 : 0 + for (; i >= start + 4; i -= 3) { + res = `_${val.slice(i - 3, i)}${res}` + } + return `${val.slice(0, i)}${res}` +} + +// CHECK FUNCTIONS +// =============== + +function checkBounds (buf, offset, byteLength) { + validateNumber(offset, 'offset') + if (buf[offset] === undefined || buf[offset + byteLength] === undefined) { + boundsError(offset, buf.length - (byteLength + 1)) + } +} + +function checkIntBI (value, min, max, buf, offset, byteLength) { + if (value > max || value < min) { + const n = typeof min === 'bigint' ? 'n' : '' + let range + if (byteLength > 3) { + if (min === 0 || min === BigInt(0)) { + range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}` + } else { + range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and < 2 ** ` + + `${(byteLength + 1) * 8 - 1}${n}` + } + } else { + range = `>= ${min}${n} and <= ${max}${n}` + } + throw new errors.ERR_OUT_OF_RANGE('value', range, value) + } + checkBounds(buf, offset, byteLength) +} + +function validateNumber (value, name) { + if (typeof value !== 'number') { + throw new errors.ERR_INVALID_ARG_TYPE(name, 'number', value) + } +} + +function boundsError (value, length, type) { + if (Math.floor(value) !== value) { + validateNumber(value, type) + throw new errors.ERR_OUT_OF_RANGE(type || 'offset', 'an integer', value) + } + + if (length < 0) { + throw new errors.ERR_BUFFER_OUT_OF_BOUNDS() + } + + throw new errors.ERR_OUT_OF_RANGE(type || 'offset', + `>= ${type ? 1 : 0} and <= ${length}`, + value) +} + // HELPER FUNCTIONS // ================ -var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g +const INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g function base64clean (str) { // Node takes equal signs as end of the Base64 encoding @@ -1655,19 +1990,14 @@ function base64clean (str) { return str } -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} - function utf8ToBytes (string, units) { units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] + let codePoint + const length = string.length + let leadSurrogate = null + const bytes = [] - for (var i = 0; i < length; ++i) { + for (let i = 0; i < length; ++i) { codePoint = string.charCodeAt(i) // is surrogate component @@ -1741,8 +2071,8 @@ function utf8ToBytes (string, units) { } function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { + const byteArray = [] + for (let i = 0; i < str.length; ++i) { // Node's code seems to be doing this and not & 0x7F.. byteArray.push(str.charCodeAt(i) & 0xFF) } @@ -1750,9 +2080,9 @@ function asciiToBytes (str) { } function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { + let c, hi, lo + const byteArray = [] + for (let i = 0; i < str.length; ++i) { if ((units -= 2) < 0) break c = str.charCodeAt(i) @@ -1770,7 +2100,8 @@ function base64ToBytes (str) { } function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { + let i + for (i = 0; i < length; ++i) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] } @@ -1789,3 +2120,48 @@ function numberIsNaN (obj) { // For IE11 support return obj !== obj // eslint-disable-line no-self-compare } + +// Create lookup table for `toString('hex')` +// See: https://github.com/feross/buffer/issues/219 +const hexSliceLookupTable = (function () { + const alphabet = '0123456789abcdef' + const table = new Array(256) + for (let i = 0; i < 16; ++i) { + const i16 = i * 16 + for (let j = 0; j < 16; ++j) { + table[i16 + j] = alphabet[i] + alphabet[j] + } + } + return table +})() + +// hex lookup table for Buffer.from(x, 'hex') +/* eslint-disable no-multi-spaces, indent */ +const hexCharValueTable = [ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 +] +/* eslint-enable no-multi-spaces, indent */ + +// Return not function with Error if BigInt not supported +function defineBigIntMethod (fn) { + return typeof BigInt === 'undefined' ? BufferBigIntNotDefined : fn +} + +function BufferBigIntNotDefined () { + throw new Error('BigInt not supported') +} diff --git a/package.json b/package.json index 706f8443..5ee6b8d9 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,37 @@ { "name": "buffer", "description": "Node.js Buffer API, for the browser", - "version": "5.1.0", + "version": "6.0.3", "author": { "name": "Feross Aboukhadijeh", "email": "feross@feross.org", - "url": "http://feross.org" + "url": "https://feross.org" }, "bugs": { "url": "https://github.com/feross/buffer/issues" }, "contributors": [ + "Daniel Cousens", "Romain Beauxis ", "James Halliday " ], "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" }, "devDependencies": { - "airtap": "0.0.2", - "benchmark": "^2.0.0", - "browserify": "^16.1.0", - "concat-stream": "^1.4.7", - "hyperquest": "^2.0.0", - "is-buffer": "^2.0.0", - "is-nan": "^1.0.1", - "split": "^1.0.0", + "airtap": "^3.0.0", + "benchmark": "^2.1.4", + "browserify": "^17.0.0", + "concat-stream": "^2.0.0", + "hyperquest": "^2.1.3", + "is-buffer": "^2.0.5", + "is-nan": "^1.3.0", + "split": "^1.0.1", "standard": "*", - "tape": "^4.0.0", - "through2": "^2.0.0", - "uglify-js": "^3.3.12" + "tape": "^5.0.1", + "through2": "^4.0.2", + "uglify-js": "^3.11.5" }, "homepage": "https://github.com/feross/buffer", "jspm": { @@ -51,20 +52,21 @@ ], "license": "MIT", "main": "index.js", + "types": "index.d.ts", "repository": { "type": "git", "url": "git://github.com/feross/buffer.git" }, "scripts": { "perf": "browserify --debug perf/bracket-notation.js > perf/bundle.js && open perf/index.html", - "perf-node": "node perf/bracket-notation.js && node perf/concat.js && node perf/copy-big.js && node perf/copy.js && node perf/new-big.js && node perf/new.js && node perf/readDoubleBE.js && node perf/readFloatBE.js && node perf/readUInt32LE.js && node perf/slice.js && node perf/writeFloatBE.js", + "perf-node": "node perf/bracket-notation.js && node perf/concat.js && node perf/copy-big.js && node perf/copy.js && node perf/new-big.js && node perf/new.js && node perf/readDoubleBE.js && node perf/readFloatBE.js && node perf/readUInt32LE.js && node perf/slice.js && node perf/writeFloatBE.js && node perf/write-hex.js", "size": "browserify -r ./ | uglifyjs -c -m | gzip | wc -c", - "test": "standard && node ./bin/test.js", - "test-browser-es5": "airtap -- test/*.js", - "test-browser-es5-local": "airtap --local -- test/*.js", - "test-browser-es6": "airtap -- test/*.js test/node/*.js", - "test-browser-es6-local": "airtap --local -- test/*.js test/node/*.js", - "test-node": "tape test/*.js test/node/*.js", + "standard": "standard", + "test": "tape test/*.js test/node/*.js", + "test-browser-old": "airtap -- test/*.js", + "test-browser-old-local": "airtap --local -- test/*.js", + "test-browser-new": "airtap -- test/*.js test/node/*.js", + "test-browser-new-local": "airtap --local -- test/*.js test/node/*.js", "update-authors": "./bin/update-authors.sh" }, "standard": { @@ -74,5 +76,19 @@ "test/_polyfill.js", "perf/**/*.js" ] - } + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] } diff --git a/perf/write-hex.js b/perf/write-hex.js new file mode 100644 index 00000000..76b03be5 --- /dev/null +++ b/perf/write-hex.js @@ -0,0 +1,24 @@ +const BrowserBuffer = require('../').Buffer // (this module) +const util = require('./util') +const suite = util.suite() + +const LENGTH = 4096 +const browserSubject = BrowserBuffer.alloc(LENGTH) +const nodeSubject = Buffer.alloc(LENGTH) + +const charset = '0123456789abcdef' + +let str = '' + +for (let i = 0; i < LENGTH * 2; i++) + str += charset[Math.random() * charset.length | 0] + +suite + .add('BrowserBuffer#write(' + LENGTH + ', "hex")', function () { + browserSubject.write(str, 'hex') + }) + +if (!process.browser) suite + .add('NodeBuffer#write(' + LENGTH + ', "hex")', function () { + nodeSubject.write(str, 'hex') + }) diff --git a/test/base64.js b/test/base64.js index 533e76d3..977225b3 100644 --- a/test/base64.js +++ b/test/base64.js @@ -1,9 +1,9 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('base64: ignore whitespace', function (t) { - var text = '\n YW9ldQ== ' - var buf = new B(text, 'base64') + const text = '\n YW9ldQ== ' + const buf = new B(text, 'base64') t.equal(buf.toString(), 'aoeu') t.end() }) @@ -46,7 +46,7 @@ test('base64: invalid non-alphanumeric characters -- should be stripped', functi }) test('base64: high byte', function (t) { - var highByte = B.from([128]) + const highByte = B.from([128]) t.deepEqual( B.alloc(1, highByte.toString('base64'), 'base64'), highByte diff --git a/test/basic.js b/test/basic.js index b30c507b..55008929 100644 --- a/test/basic.js +++ b/test/basic.js @@ -1,15 +1,15 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('instanceof Buffer', function (t) { - var buf = new B([1, 2]) + const buf = new B([1, 2]) t.ok(buf instanceof B) t.end() }) test('convert to Uint8Array in modern browsers', function (t) { - var buf = new B([1, 2]) - var uint8array = new Uint8Array(buf.buffer) + const buf = new B([1, 2]) + const uint8array = new Uint8Array(buf.buffer) t.ok(uint8array instanceof Uint8Array) t.equal(uint8array[0], 1) t.equal(uint8array[1], 2) @@ -17,7 +17,7 @@ test('convert to Uint8Array in modern browsers', function (t) { }) test('indexes from a string', function (t) { - var buf = new B('abc') + const buf = new B('abc') t.equal(buf[0], 97) t.equal(buf[1], 98) t.equal(buf[2], 99) @@ -25,7 +25,7 @@ test('indexes from a string', function (t) { }) test('indexes from an array', function (t) { - var buf = new B([ 97, 98, 99 ]) + const buf = new B([97, 98, 99]) t.equal(buf[0], 97) t.equal(buf[1], 98) t.equal(buf[2], 99) @@ -33,7 +33,7 @@ test('indexes from an array', function (t) { }) test('setting index value should modify buffer contents', function (t) { - var buf = new B([ 97, 98, 99 ]) + const buf = new B([97, 98, 99]) t.equal(buf[2], 99) t.equal(buf.toString(), 'abc') @@ -44,7 +44,7 @@ test('setting index value should modify buffer contents', function (t) { }) test('storing negative number should cast to unsigned', function (t) { - var buf = new B(1) + let buf = new B(1) buf[0] = -3 t.equal(buf[0], 253) @@ -57,8 +57,8 @@ test('storing negative number should cast to unsigned', function (t) { }) test('test that memory is copied from array-like', function (t) { - var u = new Uint8Array(4) - var b = new B(u) + const u = new Uint8Array(4) + const b = new B(u) b[0] = 1 b[1] = 2 b[2] = 3 diff --git a/test/compare.js b/test/compare.js index 5d4d76c9..0a7d8117 100644 --- a/test/compare.js +++ b/test/compare.js @@ -1,10 +1,10 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('buffer.compare', function (t) { - var b = new B(1).fill('a') - var c = new B(1).fill('c') - var d = new B(2).fill('aa') + const b = new B(1).fill('a') + const c = new B(1).fill('c') + const d = new B(2).fill('aa') t.equal(b.compare(c), -1) t.equal(c.compare(d), 1) @@ -21,27 +21,27 @@ test('buffer.compare', function (t) { test('buffer.compare argument validation', function (t) { t.throws(function () { - var b = new B(1) + const b = new B(1) B.compare(b, 'abc') }) t.throws(function () { - var b = new B(1) + const b = new B(1) B.compare('abc', b) }) t.throws(function () { - var b = new B(1) + const b = new B(1) b.compare('abc') }) t.end() }) test('buffer.equals', function (t) { - var b = new B(5).fill('abcdf') - var c = new B(5).fill('abcdf') - var d = new B(5).fill('abcde') - var e = new B(6).fill('abcdef') + const b = new B(5).fill('abcdf') + const c = new B(5).fill('abcdf') + const d = new B(5).fill('abcde') + const e = new B(6).fill('abcdef') t.ok(b.equals(c)) t.ok(!c.equals(d)) @@ -51,7 +51,7 @@ test('buffer.equals', function (t) { test('buffer.equals argument validation', function (t) { t.throws(function () { - var b = new B(1) + const b = new B(1) b.equals('abc') }) t.end() diff --git a/test/constructor.js b/test/constructor.js index 96dd2f90..d1083ba0 100644 --- a/test/constructor.js +++ b/test/constructor.js @@ -1,5 +1,5 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('new buffer from array', function (t) { t.equal( @@ -34,16 +34,16 @@ test('new buffer from string', function (t) { }) test('new buffer from buffer', function (t) { - var b1 = new B('asdf') - var b2 = new B(b1) + const b1 = new B('asdf') + const b2 = new B(b1) t.equal(b1.toString('hex'), b2.toString('hex')) t.end() }) test('new buffer from ArrayBuffer', function (t) { if (typeof ArrayBuffer !== 'undefined') { - var arraybuffer = new Uint8Array([0, 1, 2, 3]).buffer - var b = new B(arraybuffer) + const arraybuffer = new Uint8Array([0, 1, 2, 3]).buffer + const b = new B(arraybuffer) t.equal(b.length, 4) t.equal(b[0], 0) t.equal(b[1], 1) @@ -55,9 +55,9 @@ test('new buffer from ArrayBuffer', function (t) { }) test('new buffer from ArrayBuffer, shares memory', function (t) { - var u = new Uint8Array([0, 1, 2, 3]) - var arraybuffer = u.buffer - var b = new B(arraybuffer) + const u = new Uint8Array([0, 1, 2, 3]) + const arraybuffer = u.buffer + const b = new B(arraybuffer) t.equal(b.length, 4) t.equal(b[0], 0) t.equal(b[1], 1) @@ -79,8 +79,8 @@ test('new buffer from ArrayBuffer, shares memory', function (t) { test('new buffer from Uint8Array', function (t) { if (typeof Uint8Array !== 'undefined') { - var b1 = new Uint8Array([0, 1, 2, 3]) - var b2 = new B(b1) + const b1 = new Uint8Array([0, 1, 2, 3]) + const b2 = new B(b1) t.equal(b1.length, b2.length) t.equal(b1[0], 0) t.equal(b1[1], 1) @@ -93,8 +93,8 @@ test('new buffer from Uint8Array', function (t) { test('new buffer from Uint16Array', function (t) { if (typeof Uint16Array !== 'undefined') { - var b1 = new Uint16Array([0, 1, 2, 3]) - var b2 = new B(b1) + const b1 = new Uint16Array([0, 1, 2, 3]) + const b2 = new B(b1) t.equal(b1.length, b2.length) t.equal(b1[0], 0) t.equal(b1[1], 1) @@ -107,8 +107,8 @@ test('new buffer from Uint16Array', function (t) { test('new buffer from Uint32Array', function (t) { if (typeof Uint32Array !== 'undefined') { - var b1 = new Uint32Array([0, 1, 2, 3]) - var b2 = new B(b1) + const b1 = new Uint32Array([0, 1, 2, 3]) + const b2 = new B(b1) t.equal(b1.length, b2.length) t.equal(b1[0], 0) t.equal(b1[1], 1) @@ -121,8 +121,8 @@ test('new buffer from Uint32Array', function (t) { test('new buffer from Int16Array', function (t) { if (typeof Int16Array !== 'undefined') { - var b1 = new Int16Array([0, 1, 2, 3]) - var b2 = new B(b1) + const b1 = new Int16Array([0, 1, 2, 3]) + const b2 = new B(b1) t.equal(b1.length, b2.length) t.equal(b1[0], 0) t.equal(b1[1], 1) @@ -135,8 +135,8 @@ test('new buffer from Int16Array', function (t) { test('new buffer from Int32Array', function (t) { if (typeof Int32Array !== 'undefined') { - var b1 = new Int32Array([0, 1, 2, 3]) - var b2 = new B(b1) + const b1 = new Int32Array([0, 1, 2, 3]) + const b2 = new B(b1) t.equal(b1.length, b2.length) t.equal(b1[0], 0) t.equal(b1[1], 1) @@ -149,8 +149,8 @@ test('new buffer from Int32Array', function (t) { test('new buffer from Float32Array', function (t) { if (typeof Float32Array !== 'undefined') { - var b1 = new Float32Array([0, 1, 2, 3]) - var b2 = new B(b1) + const b1 = new Float32Array([0, 1, 2, 3]) + const b2 = new B(b1) t.equal(b1.length, b2.length) t.equal(b1[0], 0) t.equal(b1[1], 1) @@ -163,8 +163,8 @@ test('new buffer from Float32Array', function (t) { test('new buffer from Float64Array', function (t) { if (typeof Float64Array !== 'undefined') { - var b1 = new Float64Array([0, 1, 2, 3]) - var b2 = new B(b1) + const b1 = new Float64Array([0, 1, 2, 3]) + const b2 = new B(b1) t.equal(b1.length, b2.length) t.equal(b1[0], 0) t.equal(b1[1], 1) @@ -181,10 +181,10 @@ test('new buffer from buffer.toJSON() output', function (t) { t.end() return } - var buf = new B('test') - var json = JSON.stringify(buf) - var obj = JSON.parse(json) - var copy = new B(obj) + const buf = new B('test') + const json = JSON.stringify(buf) + const obj = JSON.parse(json) + const copy = new B(obj) t.ok(buf.equals(copy)) t.end() }) diff --git a/test/from-string.js b/test/from-string.js index 7b6601a0..64414f17 100644 --- a/test/from-string.js +++ b/test/from-string.js @@ -1,131 +1,131 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('detect utf16 surrogate pairs', function (t) { - var text = '\uD83D\uDE38' + '\uD83D\uDCAD' + '\uD83D\uDC4D' - var buf = new B(text) + const text = '\uD83D\uDE38' + '\uD83D\uDCAD' + '\uD83D\uDC4D' + const buf = new B(text) t.equal(text, buf.toString()) t.end() }) test('detect utf16 surrogate pairs over U+20000 until U+10FFFF', function (t) { - var text = '\uD842\uDFB7' + '\uD93D\uDCAD' + '\uDBFF\uDFFF' - var buf = new B(text) + const text = '\uD842\uDFB7' + '\uD93D\uDCAD' + '\uDBFF\uDFFF' + const buf = new B(text) t.equal(text, buf.toString()) t.end() }) test('replace orphaned utf16 surrogate lead code point', function (t) { - var text = '\uD83D\uDE38' + '\uD83D' + '\uD83D\uDC4D' - var buf = new B(text) - t.deepEqual(buf, new B([ 0xf0, 0x9f, 0x98, 0xb8, 0xef, 0xbf, 0xbd, 0xf0, 0x9f, 0x91, 0x8d ])) + const text = '\uD83D\uDE38' + '\uD83D' + '\uD83D\uDC4D' + const buf = new B(text) + t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0xef, 0xbf, 0xbd, 0xf0, 0x9f, 0x91, 0x8d])) t.end() }) test('replace orphaned utf16 surrogate trail code point', function (t) { - var text = '\uD83D\uDE38' + '\uDCAD' + '\uD83D\uDC4D' - var buf = new B(text) - t.deepEqual(buf, new B([ 0xf0, 0x9f, 0x98, 0xb8, 0xef, 0xbf, 0xbd, 0xf0, 0x9f, 0x91, 0x8d ])) + const text = '\uD83D\uDE38' + '\uDCAD' + '\uD83D\uDC4D' + const buf = new B(text) + t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0xef, 0xbf, 0xbd, 0xf0, 0x9f, 0x91, 0x8d])) t.end() }) test('do not write partial utf16 code units', function (t) { - var f = new B([0, 0, 0, 0, 0]) + const f = new B([0, 0, 0, 0, 0]) t.equal(f.length, 5) - var size = f.write('あいうえお', 'utf16le') + const size = f.write('あいうえお', 'utf16le') t.equal(size, 4) t.deepEqual(f, new B([0x42, 0x30, 0x44, 0x30, 0x00])) t.end() }) test('handle partial utf16 code points when encoding to utf8 the way node does', function (t) { - var text = '\uD83D\uDE38' + '\uD83D\uDC4D' + const text = '\uD83D\uDE38' + '\uD83D\uDC4D' - var buf = new B(8) + let buf = new B(8) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0xf0, 0x9f, 0x98, 0xb8, 0xf0, 0x9f, 0x91, 0x8d ])) + t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0xf0, 0x9f, 0x91, 0x8d])) buf = new B(7) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0xf0, 0x9f, 0x98, 0xb8, 0x00, 0x00, 0x00 ])) + t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0x00, 0x00, 0x00])) buf = new B(6) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0xf0, 0x9f, 0x98, 0xb8, 0x00, 0x00 ])) + t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0x00, 0x00])) buf = new B(5) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0xf0, 0x9f, 0x98, 0xb8, 0x00 ])) + t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0x00])) buf = new B(4) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0xf0, 0x9f, 0x98, 0xb8 ])) + t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8])) buf = new B(3) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x00, 0x00, 0x00 ])) + t.deepEqual(buf, new B([0x00, 0x00, 0x00])) buf = new B(2) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x00, 0x00 ])) + t.deepEqual(buf, new B([0x00, 0x00])) buf = new B(1) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x00 ])) + t.deepEqual(buf, new B([0x00])) t.end() }) test('handle invalid utf16 code points when encoding to utf8 the way node does', function (t) { - var text = 'a' + '\uDE38\uD83D' + 'b' + const text = 'a' + '\uDE38\uD83D' + 'b' - var buf = new B(8) + let buf = new B(8) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0x62 ])) + t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0x62])) buf = new B(7) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd ])) + t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd])) buf = new B(6) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61, 0xef, 0xbf, 0xbd, 0x00, 0x00 ])) + t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0x00, 0x00])) buf = new B(5) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61, 0xef, 0xbf, 0xbd, 0x00 ])) + t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0x00])) buf = new B(4) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61, 0xef, 0xbf, 0xbd ])) + t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd])) buf = new B(3) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61, 0x00, 0x00 ])) + t.deepEqual(buf, new B([0x61, 0x00, 0x00])) buf = new B(2) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61, 0x00 ])) + t.deepEqual(buf, new B([0x61, 0x00])) buf = new B(1) buf.fill(0) buf.write(text) - t.deepEqual(buf, new B([ 0x61 ])) + t.deepEqual(buf, new B([0x61])) t.end() }) diff --git a/test/is-buffer.js b/test/is-buffer.js index 177e98ee..88e5ad72 100644 --- a/test/is-buffer.js +++ b/test/is-buffer.js @@ -1,6 +1,6 @@ -var B = require('../').Buffer -var isBuffer = require('is-buffer') -var test = require('tape') +const B = require('../').Buffer +const isBuffer = require('is-buffer') +const test = require('tape') test('is-buffer tests', function (t) { t.ok(isBuffer(new B(4)), 'new Buffer(4)') diff --git a/test/methods.js b/test/methods.js index a63e4c4e..b1bf75ba 100644 --- a/test/methods.js +++ b/test/methods.js @@ -1,21 +1,21 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('buffer.toJSON', function (t) { - var data = [1, 2, 3, 4] + const data = [1, 2, 3, 4] t.deepEqual( new B(data).toJSON(), - { type: 'Buffer', data: [ 1, 2, 3, 4 ] } + { type: 'Buffer', data: [1, 2, 3, 4] } ) t.end() }) test('buffer.copy', function (t) { // copied from nodejs.org example - var buf1 = new B(26) - var buf2 = new B(26) + const buf1 = new B(26) + const buf2 = new B(26) - for (var i = 0; i < 26; i++) { + for (let i = 0; i < 26; i++) { buf1[i] = i + 97 // 97 is ASCII a buf2[i] = 33 // ASCII ! } @@ -30,7 +30,7 @@ test('buffer.copy', function (t) { }) test('test offset returns are correct', function (t) { - var b = new B(16) + const b = new B(16) t.equal(4, b.writeUInt32LE(0, 0)) t.equal(6, b.writeUInt16LE(0, 4)) t.equal(7, b.writeUInt8(0, 6)) @@ -40,17 +40,17 @@ test('test offset returns are correct', function (t) { }) test('concat() a varying number of buffers', function (t) { - var zero = [] - var one = [ new B('asdf') ] - var long = [] - for (var i = 0; i < 10; i++) { + const zero = [] + const one = [new B('asdf')] + const long = [] + for (let i = 0; i < 10; i++) { long.push(new B('asdf')) } - var flatZero = B.concat(zero) - var flatOne = B.concat(one) - var flatLong = B.concat(long) - var flatLongLen = B.concat(long, 40) + const flatZero = B.concat(zero) + const flatOne = B.concat(one) + const flatLong = B.concat(long) + const flatLongLen = B.concat(long, 40) t.equal(flatZero.length, 0) t.equal(flatOne.toString(), 'asdf') @@ -61,21 +61,28 @@ test('concat() a varying number of buffers', function (t) { }) test('concat() works on Uint8Array instances', function (t) { - var result = B.concat([new Uint8Array([1, 2]), new Uint8Array([3, 4])]) - var expected = Buffer.from([1, 2, 3, 4]) + const result = B.concat([new Uint8Array([1, 2]), new Uint8Array([3, 4])]) + const expected = B.from([1, 2, 3, 4]) + t.deepEqual(result, expected) + t.end() +}) + +test('concat() works on Uint8Array instances for smaller provided totalLength', function (t) { + const result = B.concat([new Uint8Array([1, 2]), new Uint8Array([3, 4])], 3) + const expected = B.from([1, 2, 3]) t.deepEqual(result, expected) t.end() }) test('fill', function (t) { - var b = new B(10) + const b = new B(10) b.fill(2) t.equal(b.toString('hex'), '02020202020202020202') t.end() }) test('fill (string)', function (t) { - var b = new B(10) + const b = new B(10) b.fill('abc') t.equal(b.toString(), 'abcabcabca') b.fill('է') @@ -84,18 +91,18 @@ test('fill (string)', function (t) { }) test('copy() empty buffer with sourceEnd=0', function (t) { - var source = new B([42]) - var destination = new B([43]) + const source = new B([42]) + const destination = new B([43]) source.copy(destination, 0, 0, 0) t.equal(destination.readUInt8(0), 43) t.end() }) test('copy() after slice()', function (t) { - var source = new B(200) - var dest = new B(200) - var expected = new B(200) - for (var i = 0; i < 200; i++) { + const source = new B(200) + const dest = new B(200) + const expected = new B(200) + for (let i = 0; i < 200; i++) { source[i] = i dest[i] = 0 } @@ -107,14 +114,14 @@ test('copy() after slice()', function (t) { }) test('copy() ascending', function (t) { - var b = new B('abcdefghij') + const b = new B('abcdefghij') b.copy(b, 0, 3, 10) t.equal(b.toString(), 'defghijhij') t.end() }) test('copy() descending', function (t) { - var b = new B('abcdefghij') + const b = new B('abcdefghij') b.copy(b, 3, 0, 7) t.equal(b.toString(), 'abcabcdefg') t.end() diff --git a/test/node/test-buffer-alloc.js b/test/node/test-buffer-alloc.js index 7980a162..4f98e12a 100644 --- a/test/node/test-buffer-alloc.js +++ b/test/node/test-buffer-alloc.js @@ -51,6 +51,14 @@ assert.strictEqual(0, d.length); assert.deepStrictEqual(value, ui32[key]); } } +{ + const sab = new SharedArrayBuffer(Uint8Array.BYTES_PER_ELEMENT * 4); + const ui32 = new Uint8Array(sab).fill(42); + const e = Buffer(sab); + for (const [key, value] of e.entries()) { + assert.deepStrictEqual(value, ui32[key]); + } +} // Test invalid encoding for Buffer.toString assert.throws(() => b.toString('invalid'), @@ -63,17 +71,18 @@ assert.throws(() => b.write('test', 'utf8', 0), /is no longer supported/); -// Try to create 0-length buffers. Should not throw. -Buffer.from(''); -Buffer.from('', 'ascii'); -Buffer.from('', 'latin1'); -Buffer.alloc(0); -Buffer.allocUnsafe(0); -new Buffer(''); -new Buffer('', 'ascii'); -new Buffer('', 'latin1'); -new Buffer('', 'binary'); -Buffer(0); +// try to create 0-length buffers +assert.doesNotThrow(() => Buffer.from('')); +assert.doesNotThrow(() => Buffer.from('', 'ascii')); +assert.doesNotThrow(() => Buffer.from('', 'latin1')); +assert.doesNotThrow(() => Buffer.alloc(0)); +assert.doesNotThrow(() => Buffer.allocUnsafe(0)); +assert.doesNotThrow(() => new Buffer('')); +assert.doesNotThrow(() => new Buffer('', 'ascii')); +assert.doesNotThrow(() => new Buffer('', 'latin1')); +assert.doesNotThrow(() => new Buffer('', 'binary')); +assert.doesNotThrow(() => Buffer(0)); +assert.doesNotThrow(() => Buffer.alloc(16, !!true)); // try to write a 0-length string beyond the end of b assert.throws(() => b.write('', 2048), RangeError); diff --git a/test/node/test-buffer-badhex.js b/test/node/test-buffer-badhex.js index a6388e31..90c302ff 100644 --- a/test/node/test-buffer-badhex.js +++ b/test/node/test-buffer-badhex.js @@ -14,6 +14,14 @@ const assert = require('assert'); assert.strictEqual(buf.write('abcdef01', 0, 'hex'), 4); assert.deepStrictEqual(buf, new Buffer([0xab, 0xcd, 0xef, 0x01])); assert.strictEqual(buf.toString('hex'), 'abcdef01'); + // Node Buffer behavior check + // > Buffer.from('abc def01','hex') + // + assert.strictEqual(buf.write('00000000', 0, 'hex'), 4); + assert.strictEqual(buf.write('abc def01', 0, 'hex'), 1); + assert.deepStrictEqual(buf, new Buffer([0xab, 0, 0, 0])); + assert.strictEqual(buf.toString('hex'), 'ab000000'); + assert.deepStrictEqual(Buffer.from('abc def01', 'hex'), Buffer.from([0xab])); const copy = Buffer.from(buf.toString('hex'), 'hex'); assert.strictEqual(buf.toString('hex'), copy.toString('hex')); @@ -47,4 +55,3 @@ const assert = require('assert'); const badHex = `${hex.slice(0, 256)}xx${hex.slice(256, 510)}`; assert.deepStrictEqual(Buffer.from(badHex, 'hex'), buf.slice(0, 128)); } - diff --git a/test/node/test-buffer-bigint64.js b/test/node/test-buffer-bigint64.js new file mode 100644 index 00000000..c4d05da6 --- /dev/null +++ b/test/node/test-buffer-bigint64.js @@ -0,0 +1,57 @@ +'use strict' +var Buffer = require('../../').Buffer +const assert = require('assert') + +const buf = Buffer.allocUnsafe(8) + +;['LE', 'BE'].forEach(function(endianness) { + // Should allow simple BigInts to be written and read + let val = 123456789n + buf['writeBigInt64' + endianness](val, 0) + let rtn = buf['readBigInt64' + endianness](0) + assert.strictEqual(val, rtn) + + // Should allow INT64_MAX to be written and read + val = 0x7fffffffffffffffn + buf['writeBigInt64' + endianness](val, 0) + rtn = buf['readBigInt64' + endianness](0) + assert.strictEqual(val, rtn) + + // Should read and write a negative signed 64-bit integer + val = -123456789n + buf['writeBigInt64' + endianness](val, 0) + assert.strictEqual(val, buf['readBigInt64' + endianness](0)) + + // Should read and write an unsigned 64-bit integer + val = 123456789n + buf['writeBigUInt64' + endianness](val, 0) + assert.strictEqual(val, buf['readBigUInt64' + endianness](0)) + + // Should throw a RangeError upon INT64_MAX+1 being written + assert.throws(function() { + const val = 0x8000000000000000n + buf['writeBigInt64' + endianness](val, 0) + }, RangeError) + + // Should throw a RangeError upon UINT64_MAX+1 being written + assert.throws(function() { + const val = 0x10000000000000000n + buf['writeBigUInt64' + endianness](val, 0) + }, function(err) { + assert(err instanceof RangeError) + assert(err.code === 'ERR_OUT_OF_RANGE') + assert(err.message === 'The value of "value" is out of range. It must be ' + + '>= 0n and < 2n ** 64n. Received 18_446_744_073_709_551_616n') + return true; + }) + + // Should throw a TypeError upon invalid input + assert.throws(function() { + buf['writeBigInt64' + endianness]('bad', 0) + }, TypeError) + + // Should throw a TypeError upon invalid input + assert.throws(function() { + buf['writeBigUInt64' + endianness]('bad', 0) + }, TypeError) +}) diff --git a/test/node/test-buffer-inspect.js b/test/node/test-buffer-inspect.js new file mode 100644 index 00000000..8c404335 --- /dev/null +++ b/test/node/test-buffer-inspect.js @@ -0,0 +1,63 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +var Buffer = require('../../').Buffer; + +require('./common'); +const assert = require('assert'); +const util = require('util'); +const buffer = require('../../'); + +var defaultMaxBytes = buffer.INSPECT_MAX_BYTES; +buffer.INSPECT_MAX_BYTES = 2; + +let b = Buffer.allocUnsafe(4); +b.fill('1234'); + +let s = buffer.SlowBuffer(4); +s.fill('1234'); + +let expected = ''; + +assert.strictEqual(util.inspect(b), expected); +assert.strictEqual(util.inspect(s), expected); + +b = Buffer.allocUnsafe(2); +b.fill('12'); + +s = buffer.SlowBuffer(2); +s.fill('12'); + +expected = ''; + +assert.strictEqual(util.inspect(b), expected); +assert.strictEqual(util.inspect(s), expected); + +buffer.INSPECT_MAX_BYTES = Infinity; + +assert.strictEqual(util.inspect(b), expected); +assert.strictEqual(util.inspect(s), expected); + +b.inspect = undefined; +assert.strictEqual(util.inspect(b), expected); + +buffer.INSPECT_MAX_BYTES = defaultMaxBytes; diff --git a/test/node/test-buffer.js b/test/node/test-buffer.js index 3a8c4527..7fe62bf1 100644 --- a/test/node/test-buffer.js +++ b/test/node/test-buffer.js @@ -4,6 +4,7 @@ var Buffer = require('../../').Buffer; var common = { skip: function () {} }; var assert = require('assert'); +const buffer = require('../../'); var Buffer = require('../../').Buffer; var SlowBuffer = require('../../').SlowBuffer; @@ -442,10 +443,10 @@ for (var i = 0; i < Buffer.byteLength(utf8String); i++) { { // Bug regression test var testValue = '\u00F6\u65E5\u672C\u8A9E'; // ö日本語 - var buffer = new Buffer(32); - var size = buffer.write(testValue, 0, 'utf8'); -// console.log('bytes written to buffer: ' + size); - var slice = buffer.toString('utf8', 0, size); + var testBuffer = new Buffer(32); + var size = testBuffer.write(testValue, 0, 'utf8'); +// console.log('bytes written to testBuffer: ' + size); + var slice = testBuffer.toString('utf8', 0, size); assert.equal(slice, testValue); } @@ -1050,12 +1051,12 @@ Buffer(Buffer(0), 0, 0); // GH-5110 { - var buffer = new Buffer('test'); - var string = JSON.stringify(buffer); + var testBuffer = new Buffer('test'); + var string = JSON.stringify(testBuffer); assert.strictEqual(string, '{"type":"Buffer","data":[116,101,115,116]}'); - assert.deepStrictEqual(buffer, JSON.parse(string, function(key, value) { + assert.deepStrictEqual(testBuffer, JSON.parse(string, function(key, value) { return value && value.type === 'Buffer' ? new Buffer(value.data) : value; @@ -1498,3 +1499,9 @@ assert.throws(() => Buffer(-100), assert.throws(() => Buffer(-1), '"size" argument must not be negative'); +// Verify constants +assert.equal(0x7fffffff, buffer.kMaxLength) +assert.equal(buffer.kMaxLength, buffer.constants.MAX_LENGTH) + +assert.equal((1 << 28) - 16, buffer.kStringMaxLength) +assert.equal(buffer.kStringMaxLength, buffer.constants.MAX_STRING_LENGTH) diff --git a/test/slice.js b/test/slice.js index d8cd20ec..035c9aae 100644 --- a/test/slice.js +++ b/test/slice.js @@ -1,13 +1,13 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('modifying buffer created by .slice() modifies original memory', function (t) { - var buf1 = new B(26) - for (var i = 0; i < 26; i++) { + const buf1 = new B(26) + for (let i = 0; i < 26; i++) { buf1[i] = i + 97 // 97 is ASCII a } - var buf2 = buf1.slice(0, 3) + const buf2 = buf1.slice(0, 3) t.equal(buf2.toString('ascii', 0, buf2.length), 'abc') buf2[0] = '!'.charCodeAt(0) @@ -17,12 +17,12 @@ test('modifying buffer created by .slice() modifies original memory', function ( }) test('modifying parent buffer modifies .slice() buffer\'s memory', function (t) { - var buf1 = new B(26) - for (var i = 0; i < 26; i++) { + const buf1 = new B(26) + for (let i = 0; i < 26; i++) { buf1[i] = i + 97 // 97 is ASCII a } - var buf2 = buf1.slice(0, 3) + const buf2 = buf1.slice(0, 3) t.equal(buf2.toString('ascii', 0, buf2.length), 'abc') buf1[0] = '!'.charCodeAt(0) diff --git a/test/static.js b/test/static.js index a2380b54..07ea6c61 100644 --- a/test/static.js +++ b/test/static.js @@ -1,5 +1,5 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('Buffer.isEncoding', function (t) { t.equal(B.isEncoding('HEX'), true) diff --git a/test/to-string.js b/test/to-string.js index b7305d0f..3f146a8e 100644 --- a/test/to-string.js +++ b/test/to-string.js @@ -1,5 +1,5 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('utf8 buffer to base64', function (t) { t.equal( @@ -33,6 +33,14 @@ test('utf16le to utf16', function (t) { t.end() }) +test('utf16le to utf16 with odd byte length input', function (t) { + t.equal( + new B(new B('abcde', 'utf8').toString('utf16le'), 'utf16le').toString('utf8'), + 'abcd' + ) + t.end() +}) + test('utf16le to hex', function (t) { t.equal( new B('abcd', 'utf16le').toString('hex'), @@ -117,11 +125,11 @@ test('utf8 to binary', function (t) { test('utf8 replacement chars (1 byte sequence)', function (t) { t.equal( - new B([ 0x80 ]).toString(), + new B([0x80]).toString(), '\uFFFD' ) t.equal( - new B([ 0x7F ]).toString(), + new B([0x7F]).toString(), '\u007F' ) t.end() @@ -129,19 +137,19 @@ test('utf8 replacement chars (1 byte sequence)', function (t) { test('utf8 replacement chars (2 byte sequences)', function (t) { t.equal( - new B([ 0xC7 ]).toString(), + new B([0xC7]).toString(), '\uFFFD' ) t.equal( - new B([ 0xC7, 0xB1 ]).toString(), + new B([0xC7, 0xB1]).toString(), '\u01F1' ) t.equal( - new B([ 0xC0, 0xB1 ]).toString(), + new B([0xC0, 0xB1]).toString(), '\uFFFD\uFFFD' ) t.equal( - new B([ 0xC1, 0xB1 ]).toString(), + new B([0xC1, 0xB1]).toString(), '\uFFFD\uFFFD' ) t.end() @@ -149,15 +157,15 @@ test('utf8 replacement chars (2 byte sequences)', function (t) { test('utf8 replacement chars (3 byte sequences)', function (t) { t.equal( - new B([ 0xE0 ]).toString(), + new B([0xE0]).toString(), '\uFFFD' ) t.equal( - new B([ 0xE0, 0xAC ]).toString(), + new B([0xE0, 0xAC]).toString(), '\uFFFD\uFFFD' ) t.equal( - new B([ 0xE0, 0xAC, 0xB9 ]).toString(), + new B([0xE0, 0xAC, 0xB9]).toString(), '\u0B39' ) t.end() @@ -165,27 +173,27 @@ test('utf8 replacement chars (3 byte sequences)', function (t) { test('utf8 replacement chars (4 byte sequences)', function (t) { t.equal( - new B([ 0xF4 ]).toString(), + new B([0xF4]).toString(), '\uFFFD' ) t.equal( - new B([ 0xF4, 0x8F ]).toString(), + new B([0xF4, 0x8F]).toString(), '\uFFFD\uFFFD' ) t.equal( - new B([ 0xF4, 0x8F, 0x80 ]).toString(), + new B([0xF4, 0x8F, 0x80]).toString(), '\uFFFD\uFFFD\uFFFD' ) t.equal( - new B([ 0xF4, 0x8F, 0x80, 0x84 ]).toString(), + new B([0xF4, 0x8F, 0x80, 0x84]).toString(), '\uDBFC\uDC04' ) t.equal( - new B([ 0xFF ]).toString(), + new B([0xFF]).toString(), '\uFFFD' ) t.equal( - new B([ 0xFF, 0x8F, 0x80, 0x84 ]).toString(), + new B([0xFF, 0x8F, 0x80, 0x84]).toString(), '\uFFFD\uFFFD\uFFFD\uFFFD' ) t.end() @@ -193,7 +201,7 @@ test('utf8 replacement chars (4 byte sequences)', function (t) { test('utf8 replacement chars on 256 random bytes', function (t) { t.equal( - new B([ 152, 130, 206, 23, 243, 238, 197, 44, 27, 86, 208, 36, 163, 184, 164, 21, 94, 242, 178, 46, 25, 26, 253, 178, 72, 147, 207, 112, 236, 68, 179, 190, 29, 83, 239, 147, 125, 55, 143, 19, 157, 68, 157, 58, 212, 224, 150, 39, 128, 24, 94, 225, 120, 121, 75, 192, 112, 19, 184, 142, 203, 36, 43, 85, 26, 147, 227, 139, 242, 186, 57, 78, 11, 102, 136, 117, 180, 210, 241, 92, 3, 215, 54, 167, 249, 1, 44, 225, 146, 86, 2, 42, 68, 21, 47, 238, 204, 153, 216, 252, 183, 66, 222, 255, 15, 202, 16, 51, 134, 1, 17, 19, 209, 76, 238, 38, 76, 19, 7, 103, 249, 5, 107, 137, 64, 62, 170, 57, 16, 85, 179, 193, 97, 86, 166, 196, 36, 148, 138, 193, 210, 69, 187, 38, 242, 97, 195, 219, 252, 244, 38, 1, 197, 18, 31, 246, 53, 47, 134, 52, 105, 72, 43, 239, 128, 203, 73, 93, 199, 75, 222, 220, 166, 34, 63, 236, 11, 212, 76, 243, 171, 110, 78, 39, 205, 204, 6, 177, 233, 212, 243, 0, 33, 41, 122, 118, 92, 252, 0, 157, 108, 120, 70, 137, 100, 223, 243, 171, 232, 66, 126, 111, 142, 33, 3, 39, 117, 27, 107, 54, 1, 217, 227, 132, 13, 166, 3, 73, 53, 127, 225, 236, 134, 219, 98, 214, 125, 148, 24, 64, 142, 111, 231, 194, 42, 150, 185, 10, 182, 163, 244, 19, 4, 59, 135, 16 ]).toString(), + new B([152, 130, 206, 23, 243, 238, 197, 44, 27, 86, 208, 36, 163, 184, 164, 21, 94, 242, 178, 46, 25, 26, 253, 178, 72, 147, 207, 112, 236, 68, 179, 190, 29, 83, 239, 147, 125, 55, 143, 19, 157, 68, 157, 58, 212, 224, 150, 39, 128, 24, 94, 225, 120, 121, 75, 192, 112, 19, 184, 142, 203, 36, 43, 85, 26, 147, 227, 139, 242, 186, 57, 78, 11, 102, 136, 117, 180, 210, 241, 92, 3, 215, 54, 167, 249, 1, 44, 225, 146, 86, 2, 42, 68, 21, 47, 238, 204, 153, 216, 252, 183, 66, 222, 255, 15, 202, 16, 51, 134, 1, 17, 19, 209, 76, 238, 38, 76, 19, 7, 103, 249, 5, 107, 137, 64, 62, 170, 57, 16, 85, 179, 193, 97, 86, 166, 196, 36, 148, 138, 193, 210, 69, 187, 38, 242, 97, 195, 219, 252, 244, 38, 1, 197, 18, 31, 246, 53, 47, 134, 52, 105, 72, 43, 239, 128, 203, 73, 93, 199, 75, 222, 220, 166, 34, 63, 236, 11, 212, 76, 243, 171, 110, 78, 39, 205, 204, 6, 177, 233, 212, 243, 0, 33, 41, 122, 118, 92, 252, 0, 157, 108, 120, 70, 137, 100, 223, 243, 171, 232, 66, 126, 111, 142, 33, 3, 39, 117, 27, 107, 54, 1, 217, 227, 132, 13, 166, 3, 73, 53, 127, 225, 236, 134, 219, 98, 214, 125, 148, 24, 64, 142, 111, 231, 194, 42, 150, 185, 10, 182, 163, 244, 19, 4, 59, 135, 16]).toString(), '\uFFFD\uFFFD\uFFFD\u0017\uFFFD\uFFFD\uFFFD\u002C\u001B\u0056\uFFFD\u0024\uFFFD\uFFFD\uFFFD\u0015\u005E\uFFFD\uFFFD\u002E\u0019\u001A\uFFFD\uFFFD\u0048\uFFFD\uFFFD\u0070\uFFFD\u0044\uFFFD\uFFFD\u001D\u0053\uFFFD\uFFFD\u007D\u0037\uFFFD\u0013\uFFFD\u0044\uFFFD\u003A\uFFFD\uFFFD\uFFFD\u0027\uFFFD\u0018\u005E\uFFFD\u0078\u0079\u004B\uFFFD\u0070\u0013\uFFFD\uFFFD\uFFFD\u0024\u002B\u0055\u001A\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0039\u004E\u000B\u0066\uFFFD\u0075\uFFFD\uFFFD\uFFFD\u005C\u0003\uFFFD\u0036\uFFFD\uFFFD\u0001\u002C\uFFFD\uFFFD\u0056\u0002\u002A\u0044\u0015\u002F\uFFFD\u0319\uFFFD\uFFFD\uFFFD\u0042\uFFFD\uFFFD\u000F\uFFFD\u0010\u0033\uFFFD\u0001\u0011\u0013\uFFFD\u004C\uFFFD\u0026\u004C\u0013\u0007\u0067\uFFFD\u0005\u006B\uFFFD\u0040\u003E\uFFFD\u0039\u0010\u0055\uFFFD\uFFFD\u0061\u0056\uFFFD\uFFFD\u0024\uFFFD\uFFFD\uFFFD\uFFFD\u0045\uFFFD\u0026\uFFFD\u0061\uFFFD\uFFFD\uFFFD\uFFFD\u0026\u0001\uFFFD\u0012\u001F\uFFFD\u0035\u002F\uFFFD\u0034\u0069\u0048\u002B\uFFFD\uFFFD\uFFFD\u0049\u005D\uFFFD\u004B\uFFFD\u0726\u0022\u003F\uFFFD\u000B\uFFFD\u004C\uFFFD\uFFFD\u006E\u004E\u0027\uFFFD\uFFFD\u0006\uFFFD\uFFFD\uFFFD\uFFFD\u0000\u0021\u0029\u007A\u0076\u005C\uFFFD\u0000\uFFFD\u006C\u0078\u0046\uFFFD\u0064\uFFFD\uFFFD\uFFFD\uFFFD\u0042\u007E\u006F\uFFFD\u0021\u0003\u0027\u0075\u001B\u006B\u0036\u0001\uFFFD\uFFFD\uFFFD\u000D\uFFFD\u0003\u0049\u0035\u007F\uFFFD\uFFFD\uFFFD\uFFFD\u0062\uFFFD\u007D\uFFFD\u0018\u0040\uFFFD\u006F\uFFFD\uFFFD\u002A\uFFFD\uFFFD\u000A\uFFFD\uFFFD\uFFFD\u0013\u0004\u003B\uFFFD\u0010' ) t.end() @@ -201,23 +209,23 @@ test('utf8 replacement chars on 256 random bytes', function (t) { test('utf8 replacement chars for anything in the surrogate pair range', function (t) { t.equal( - new B([ 0xED, 0x9F, 0xBF ]).toString(), + new B([0xED, 0x9F, 0xBF]).toString(), '\uD7FF' ) t.equal( - new B([ 0xED, 0xA0, 0x80 ]).toString(), + new B([0xED, 0xA0, 0x80]).toString(), '\uFFFD\uFFFD\uFFFD' ) t.equal( - new B([ 0xED, 0xBE, 0x8B ]).toString(), + new B([0xED, 0xBE, 0x8B]).toString(), '\uFFFD\uFFFD\uFFFD' ) t.equal( - new B([ 0xED, 0xBF, 0xBF ]).toString(), + new B([0xED, 0xBF, 0xBF]).toString(), '\uFFFD\uFFFD\uFFFD' ) t.equal( - new B([ 0xEE, 0x80, 0x80 ]).toString(), + new B([0xEE, 0x80, 0x80]).toString(), '\uE000' ) t.end() diff --git a/test/write-hex.js b/test/write-hex.js new file mode 100644 index 00000000..c10ac2b2 --- /dev/null +++ b/test/write-hex.js @@ -0,0 +1,59 @@ +'use strict' + +const Buffer = require('../').Buffer +const test = require('tape') + +test('buffer.write("hex") should stop on invalid characters', function (t) { + // Test the entire 16-bit space. + for (let ch = 0; ch <= 0xffff; ch++) { + // 0-9 + if (ch >= 0x30 && ch <= 0x39) { + continue + } + + // A-F + if (ch >= 0x41 && ch <= 0x46) { + continue + } + + // a-f + if (ch >= 0x61 && ch <= 0x66) { + continue + } + + for (const str of [ + 'abcd' + String.fromCharCode(ch) + 'ef0', + 'abcde' + String.fromCharCode(ch) + 'f0', + 'abcd' + String.fromCharCode(ch + 0) + String.fromCharCode(ch + 1) + 'f0', + 'abcde' + String.fromCharCode(ch + 0) + String.fromCharCode(ch + 1) + '0' + ]) { + const buf = Buffer.alloc(4) + t.equal(str.length, 8) + t.equal(buf.write(str, 'hex'), 2) + t.equal(buf.toString('hex'), 'abcd0000') + t.equal(Buffer.from(str, 'hex').toString('hex'), 'abcd') + } + } + + t.end() +}) + +test('buffer.write("hex") should truncate odd string lengths', function (t) { + const buf = Buffer.alloc(32) + const charset = '0123456789abcdef' + + let str = '' + + for (let i = 0; i < 63; i++) { + str += charset[Math.random() * charset.length | 0] + } + + t.equal(buf.write('abcde', 'hex'), 2) + t.equal(buf.toString('hex', 0, 3), 'abcd00') + + buf.fill(0) + + t.equal(buf.write(str, 'hex'), 31) + t.equal(buf.toString('hex', 0, 32), str.slice(0, -1) + '00') + t.end() +}) diff --git a/test/write.js b/test/write.js index f6fc9f3f..d132e850 100644 --- a/test/write.js +++ b/test/write.js @@ -1,9 +1,9 @@ -var B = require('../').Buffer -var test = require('tape') -var isnan = require('is-nan') +const B = require('../').Buffer +const test = require('tape') +const isnan = require('is-nan') test('buffer.write string should get parsed as number', function (t) { - var b = new B(64) + const b = new B(64) b.writeUInt16LE('1003', 0) t.equal(b.readUInt16LE(0), 1003) t.end() @@ -12,14 +12,14 @@ test('buffer.write string should get parsed as number', function (t) { test('buffer.writeUInt8 a fractional number will get Math.floored', function (t) { // Some extra work is necessary to make this test pass with the Object implementation - var b = new B(1) + const b = new B(1) b.writeInt8(5.5, 0) t.equal(b[0], 5) t.end() }) test('writeUint8 with a negative number throws', function (t) { - var buf = new B(1) + const buf = new B(1) t.throws(function () { buf.writeUInt8(-3, 0) @@ -30,30 +30,30 @@ test('writeUint8 with a negative number throws', function (t) { test('hex of write{Uint,Int}{8,16,32}{LE,BE}', function (t) { t.plan(2 * ((2 * 2 * 2) + 2)) - var hex = [ + const hex = [ '03', '0300', '0003', '03000000', '00000003', 'fd', 'fdff', 'fffd', 'fdffffff', 'fffffffd' ] - var reads = [ 3, 3, 3, 3, 3, -3, -3, -3, -3, -3 ] - var xs = ['UInt', 'Int'] - var ys = [8, 16, 32] - for (var i = 0; i < xs.length; i++) { - var x = xs[i] - for (var j = 0; j < ys.length; j++) { - var y = ys[j] - var endianesses = (y === 8) ? [''] : ['LE', 'BE'] - for (var k = 0; k < endianesses.length; k++) { - var z = endianesses[k] + const reads = [3, 3, 3, 3, 3, -3, -3, -3, -3, -3] + const xs = ['UInt', 'Int'] + const ys = [8, 16, 32] + for (let i = 0; i < xs.length; i++) { + const x = xs[i] + for (let j = 0; j < ys.length; j++) { + const y = ys[j] + const endianesses = (y === 8) ? [''] : ['LE', 'BE'] + for (let k = 0; k < endianesses.length; k++) { + const z = endianesses[k] - var v1 = new B(y / 8) - var writefn = 'write' + x + y + z - var val = (x === 'Int') ? -3 : 3 + const v1 = new B(y / 8) + const writefn = 'write' + x + y + z + const val = (x === 'Int') ? -3 : 3 v1[writefn](val, 0) t.equal( v1.toString('hex'), hex.shift() ) - var readfn = 'read' + x + y + z + const readfn = 'read' + x + y + z t.equal( v1[readfn](0), reads.shift() @@ -66,29 +66,29 @@ test('hex of write{Uint,Int}{8,16,32}{LE,BE}', function (t) { test('hex of write{Uint,Int}{8,16,32}{LE,BE} with overflow', function (t) { t.plan(3 * ((2 * 2 * 2) + 2)) - var hex = [ + const hex = [ '', '03', '00', '030000', '000000', '', 'fd', 'ff', 'fdffff', 'ffffff' ] - var reads = [ + const reads = [ undefined, 3, 0, NaN, 0, undefined, 253, -256, 16777213, -256 ] - var xs = ['UInt', 'Int'] - var ys = [8, 16, 32] - for (var i = 0; i < xs.length; i++) { - var x = xs[i] - for (var j = 0; j < ys.length; j++) { - var y = ys[j] - var endianesses = (y === 8) ? [''] : ['LE', 'BE'] - for (var k = 0; k < endianesses.length; k++) { - var z = endianesses[k] + const xs = ['UInt', 'Int'] + const ys = [8, 16, 32] + for (let i = 0; i < xs.length; i++) { + const x = xs[i] + for (let j = 0; j < ys.length; j++) { + const y = ys[j] + const endianesses = (y === 8) ? [''] : ['LE', 'BE'] + for (let k = 0; k < endianesses.length; k++) { + const z = endianesses[k] - var v1 = new B((y / 8) - 1) - var next = new B(4) + const v1 = new B((y / 8) - 1) + const next = new B(4) next.writeUInt32BE(0, 0) - var writefn = 'write' + x + y + z - var val = (x === 'Int') ? -3 : 3 + const writefn = 'write' + x + y + z + const val = (x === 'Int') ? -3 : 3 v1[writefn](val, 0, true) t.equal( v1.toString('hex'), @@ -98,8 +98,8 @@ test('hex of write{Uint,Int}{8,16,32}{LE,BE} with overflow', function (t) { t.equal(next.readUInt32BE(0), 0) // check that no bytes are read from next buffer. next.writeInt32BE(~0, 0) - var readfn = 'read' + x + y + z - var r = reads.shift() + const readfn = 'read' + x + y + z + const r = reads.shift() if (isnan(r)) t.pass('equal') else t.equal(v1[readfn](0, true), r) } @@ -108,11 +108,11 @@ test('hex of write{Uint,Int}{8,16,32}{LE,BE} with overflow', function (t) { t.end() }) test('large values do not improperly roll over (ref #80)', function (t) { - var nums = [-25589992, -633756690, -898146932] - var out = new B(12) + const nums = [-25589992, -633756690, -898146932] + const out = new B(12) out.fill(0) out.writeInt32BE(nums[0], 0) - var newNum = out.readInt32BE(0) + let newNum = out.readInt32BE(0) t.equal(nums[0], newNum) out.writeInt32BE(nums[1], 4) newNum = out.readInt32BE(4) diff --git a/test/write_infinity.js b/test/write_infinity.js index ffe80d67..39f1d378 100644 --- a/test/write_infinity.js +++ b/test/write_infinity.js @@ -1,43 +1,43 @@ -var B = require('../').Buffer -var test = require('tape') +const B = require('../').Buffer +const test = require('tape') test('write/read Infinity as a float', function (t) { - var buf = new B(4) + const buf = new B(4) t.equal(buf.writeFloatBE(Infinity, 0), 4) t.equal(buf.readFloatBE(0), Infinity) t.end() }) test('write/read -Infinity as a float', function (t) { - var buf = new B(4) + const buf = new B(4) t.equal(buf.writeFloatBE(-Infinity, 0), 4) t.equal(buf.readFloatBE(0), -Infinity) t.end() }) test('write/read Infinity as a double', function (t) { - var buf = new B(8) + const buf = new B(8) t.equal(buf.writeDoubleBE(Infinity, 0), 8) t.equal(buf.readDoubleBE(0), Infinity) t.end() }) test('write/read -Infinity as a double', function (t) { - var buf = new B(8) + const buf = new B(8) t.equal(buf.writeDoubleBE(-Infinity, 0), 8) t.equal(buf.readDoubleBE(0), -Infinity) t.end() }) test('write/read float greater than max', function (t) { - var buf = new B(4) + const buf = new B(4) t.equal(buf.writeFloatBE(4e38, 0), 4) t.equal(buf.readFloatBE(0), Infinity) t.end() }) test('write/read float less than min', function (t) { - var buf = new B(4) + const buf = new B(4) t.equal(buf.writeFloatBE(-4e40, 0), 4) t.equal(buf.readFloatBE(0), -Infinity) t.end()