├── perf
├── index.html
├── new.js
├── new-big.js
├── util.js
├── slice.js
├── write-hex.js
├── writeUtf8.js
├── bracket-notation.js
├── copy.js
├── copy-big.js
├── writeFloatBE.js
├── concat.js
├── readFloatBE.js
├── readDoubleBE.js
├── readUInt32LE.js
└── readUtf8.js
├── .github
├── FUNDING.yml
└── workflows
│ └── ci.yml
├── .gitignore
├── .npmignore
├── bin
├── airtap-old.yml
├── airtap-new.yml
├── update-authors.sh
├── test.js
└── download-node-tests.js
├── test
├── node
│ ├── test-buffer-new.js
│ ├── test-buffer-zero-fill.js
│ ├── test-buffer-zero-fill-reset.js
│ ├── test-buffer-bad-overload.js
│ ├── test-buffer-safe-unsafe.js
│ ├── test-buffer-isencoding.js
│ ├── test-buffer-prototype-inspect.js
│ ├── test-buffer-zero-fill-cli.js
│ ├── test-buffer-parent-property.js
│ ├── test-buffer-tojson.js
│ ├── test-buffer-inheritance.js
│ ├── test-buffer-iterator.js
│ ├── test-buffer-tostring.js
│ ├── test-buffer-concat.js
│ ├── test-buffer-failed-alloc-typed-arrays.js
│ ├── test-buffer-compare.js
│ ├── test-buffer-from.js
│ ├── test-buffer-bigint64.js
│ ├── test-buffer-ascii.js
│ ├── test-buffer-badhex.js
│ ├── test-buffer-inspect.js
│ ├── test-buffer-slow.js
│ ├── test-buffer-write.js
│ ├── test-buffer-compare-offset.js
│ ├── test-buffer-arraybuffer.js
│ ├── test-buffer-bytelength.js
│ ├── common.js
│ ├── test-buffer-slice.js
│ ├── test-buffer-swap.js
│ ├── test-buffer-fill.js
│ ├── test-buffer-includes.js
│ └── test-buffer-indexof.js
├── static.js
├── is-buffer.js
├── slice.js
├── write_infinity.js
├── compare.js
├── write-hex.js
├── basic.js
├── base64.js
├── from-string.js
├── write.js
├── methods.js
├── typing.js
├── constructor.js
└── to-string.js
├── LICENSE
├── package.json
├── AUTHORS.md
├── index.d.ts
└── README.md
/perf/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: feross
2 | tidelift: npm/buffer
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .airtap.yml
3 | *.log
4 | node_modules/
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .airtap.yml
2 | .github/
3 | bin/
4 | perf/
5 | test/
6 |
--------------------------------------------------------------------------------
/bin/airtap-old.yml:
--------------------------------------------------------------------------------
1 | sauce_connect: true
2 | loopback: airtap.local
3 | browsers:
4 | - name: safari
5 | version: 11..13
6 | - name: iphone
7 | version: 11.3
8 |
--------------------------------------------------------------------------------
/bin/airtap-new.yml:
--------------------------------------------------------------------------------
1 | sauce_connect: true
2 | loopback: airtap.local
3 | browsers:
4 | - name: chrome
5 | version: -1..latest
6 | - name: firefox
7 | version: -1..latest
8 | # - name: safari
9 | # version: 14..latest
10 | - name: microsoftedge
11 | version: -1..latest
12 | # - name: iphone
13 | # version: latest
14 |
--------------------------------------------------------------------------------
/test/node/test-buffer-new.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 |
6 | common.expectsError(() => new Buffer(42, 'utf8'), {
7 | code: 'ERR_INVALID_ARG_TYPE',
8 | type: TypeError,
9 | message: 'The "string" argument must be of type string. Received type number'
10 | });
11 |
12 |
--------------------------------------------------------------------------------
/test/node/test-buffer-zero-fill.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 |
7 | const buf1 = Buffer(100);
8 | const buf2 = new Buffer(100);
9 |
10 | for (let n = 0; n < buf1.length; n++)
11 | assert.strictEqual(buf1[n], 0);
12 |
13 | for (let n = 0; n < buf2.length; n++)
14 | assert.strictEqual(buf2[n], 0);
15 |
16 |
--------------------------------------------------------------------------------
/test/static.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('Buffer.isEncoding', function (t) {
5 | t.equal(B.isEncoding('HEX'), true)
6 | t.equal(B.isEncoding('hex'), true)
7 | t.equal(B.isEncoding('bad'), false)
8 | t.end()
9 | })
10 |
11 | test('Buffer.isBuffer', function (t) {
12 | t.equal(B.isBuffer(new B('hey', 'utf8')), true)
13 | t.equal(B.isBuffer(new B([1, 2, 3], 'utf8')), true)
14 | t.equal(B.isBuffer('hey'), false)
15 | t.end()
16 | })
17 |
--------------------------------------------------------------------------------
/perf/new.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 16
6 |
7 | suite
8 | .add('BrowserBuffer#new(' + LENGTH + ')', function () {
9 | var buf = new BrowserBuffer(LENGTH)
10 | })
11 | .add('Uint8Array#new(' + LENGTH + ')', function () {
12 | var buf = new Uint8Array(LENGTH)
13 | })
14 |
15 | if (!process.browser) suite
16 | .add('NodeBuffer#new(' + LENGTH + ')', function () {
17 | var buf = new Buffer(LENGTH)
18 | })
19 |
--------------------------------------------------------------------------------
/perf/new-big.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 16000
6 |
7 | suite
8 | .add('BrowserBuffer#new(' + LENGTH + ')', function () {
9 | var buf = new BrowserBuffer(LENGTH)
10 | })
11 | .add('Uint8Array#new(' + LENGTH + ')', function () {
12 | var buf = new Uint8Array(LENGTH)
13 | })
14 |
15 | if (!process.browser) suite
16 | .add('NodeBuffer#new(' + LENGTH + ')', function () {
17 | var buf = new Buffer(LENGTH)
18 | })
19 |
--------------------------------------------------------------------------------
/test/node/test-buffer-zero-fill-reset.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 |
7 |
8 | function testUint8Array(ui) {
9 | const length = ui.length;
10 | for (let i = 0; i < length; i++)
11 | if (ui[i] !== 0) return false;
12 | return true;
13 | }
14 |
15 |
16 | for (let i = 0; i < 100; i++) {
17 | Buffer.alloc(0);
18 | const ui = new Uint8Array(65);
19 | assert.ok(testUint8Array(ui), `Uint8Array is not zero-filled: ${ui}`);
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/perf/util.js:
--------------------------------------------------------------------------------
1 | var benchmark = require('benchmark')
2 |
3 | exports.suite = function () {
4 | var suite = new benchmark.Suite()
5 | process.nextTick(function () {
6 | suite
7 | .on('error', function (event) {
8 | console.error(event.target.error.stack)
9 | })
10 | .on('cycle', function (event) {
11 | console.log(String(event.target))
12 | })
13 | .on('complete', function () {
14 | console.log('Fastest is ' + this.filter('fastest').map('name'))
15 | })
16 | .run({ async: true })
17 | })
18 | return suite
19 | }
20 |
--------------------------------------------------------------------------------
/bin/update-authors.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Update AUTHORS.md based on git history.
3 |
4 | git log --reverse --format='%aN (%aE)' | perl -we '
5 | BEGIN {
6 | %seen = (), @authors = ();
7 | }
8 | while (<>) {
9 | next if $seen{$_};
10 | next if /(support\@greenkeeper.io)/;
11 | next if /(dcousens\@users.noreply.github.com)/;
12 | next if /(cmetcalf\@appgeo.com)/;
13 | $seen{$_} = push @authors, "- ", $_;
14 | }
15 | END {
16 | print "# Authors\n\n";
17 | print "#### Ordered by first contribution.\n\n";
18 | print @authors, "\n";
19 | print "#### Generated by bin/update-authors.sh.\n";
20 | }
21 | ' > AUTHORS.md
22 |
--------------------------------------------------------------------------------
/perf/slice.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 160
6 |
7 | var browserBuffer = new BrowserBuffer(LENGTH)
8 | var typedarray = new Uint8Array(LENGTH)
9 | var nodeBuffer = new Buffer(LENGTH)
10 |
11 | suite
12 | .add('BrowserBuffer#slice', function () {
13 | var x = browserBuffer.slice(4)
14 | })
15 | .add('Uint8Array#subarray', function () {
16 | var x = typedarray.subarray(4)
17 | })
18 |
19 | if (!process.browser) suite
20 | .add('NodeBuffer#slice', function () {
21 | var x = nodeBuffer.slice(4)
22 | })
23 |
--------------------------------------------------------------------------------
/test/node/test-buffer-bad-overload.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 | const common = require('./common');
4 | const assert = require('assert');
5 |
6 | assert.doesNotThrow(function() {
7 | Buffer.allocUnsafe(10);
8 | });
9 |
10 | const err = common.expectsError({
11 | code: 'ERR_INVALID_ARG_TYPE',
12 | type: TypeError,
13 | message: 'The "value" argument must not be of type number. ' +
14 | 'Received type number'
15 | });
16 | assert.throws(function() {
17 | Buffer.from(10, 'hex');
18 | }, err);
19 |
20 | assert.doesNotThrow(function() {
21 | Buffer.from('deadbeaf', 'hex');
22 | });
23 |
24 |
--------------------------------------------------------------------------------
/test/is-buffer.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const isBuffer = require('is-buffer')
3 | const test = require('tape')
4 |
5 | test('is-buffer tests', function (t) {
6 | t.ok(isBuffer(new B(4)), 'new Buffer(4)')
7 |
8 | t.notOk(isBuffer(undefined), 'undefined')
9 | t.notOk(isBuffer(null), 'null')
10 | t.notOk(isBuffer(''), 'empty string')
11 | t.notOk(isBuffer(true), 'true')
12 | t.notOk(isBuffer(false), 'false')
13 | t.notOk(isBuffer(0), '0')
14 | t.notOk(isBuffer(1), '1')
15 | t.notOk(isBuffer(1.0), '1.0')
16 | t.notOk(isBuffer('string'), 'string')
17 | t.notOk(isBuffer({}), '{}')
18 | t.notOk(isBuffer(function foo () {}), 'function foo () {}')
19 |
20 | t.end()
21 | })
22 |
--------------------------------------------------------------------------------
/test/node/test-buffer-safe-unsafe.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 |
7 | const safe = Buffer.alloc(10);
8 |
9 | function isZeroFilled(buf) {
10 | for (let n = 0; n < buf.length; n++)
11 | if (buf[n] !== 0) return false;
12 | return true;
13 | }
14 |
15 | assert(isZeroFilled(safe));
16 |
17 | // Test that unsafe allocations doesn't affect subsequent safe allocations
18 | Buffer.allocUnsafe(10);
19 | assert(isZeroFilled(new Float64Array(10)));
20 |
21 | new Buffer(10);
22 | assert(isZeroFilled(new Float64Array(10)));
23 |
24 | Buffer.allocUnsafe(10);
25 | assert(isZeroFilled(Buffer.alloc(10)));
26 |
27 |
--------------------------------------------------------------------------------
/test/node/test-buffer-isencoding.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 |
7 | [
8 | 'hex',
9 | 'utf8',
10 | 'utf-8',
11 | 'ascii',
12 | 'latin1',
13 | 'binary',
14 | 'base64',
15 | 'ucs2',
16 | 'ucs-2',
17 | 'utf16le',
18 | 'utf-16le'
19 | ].forEach((enc) => {
20 | assert.strictEqual(Buffer.isEncoding(enc), true);
21 | });
22 |
23 | [
24 | 'utf9',
25 | 'utf-7',
26 | 'Unicode-FTW',
27 | 'new gnu gun',
28 | false,
29 | NaN,
30 | {},
31 | Infinity,
32 | [],
33 | 1,
34 | 0,
35 | -1
36 | ].forEach((enc) => {
37 | assert.strictEqual(Buffer.isEncoding(enc), false);
38 | });
39 |
40 |
--------------------------------------------------------------------------------
/test/node/test-buffer-prototype-inspect.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 | require('./common');
4 |
5 | // lib/buffer.js defines Buffer.prototype.inspect() to override how buffers are
6 | // presented by util.inspect().
7 |
8 | const assert = require('assert');
9 | const util = require('util');
10 |
11 | {
12 | const buf = Buffer.from('fhqwhgads');
13 | assert.strictEqual(util.inspect(buf), '');
14 | }
15 |
16 | {
17 | const buf = Buffer.from('');
18 | assert.strictEqual(util.inspect(buf), '');
19 | }
20 |
21 | {
22 | const buf = Buffer.from('x'.repeat(51));
23 | assert.ok(/^$/.test(util.inspect(buf)));
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/perf/write-hex.js:
--------------------------------------------------------------------------------
1 | const BrowserBuffer = require('../').Buffer // (this module)
2 | const util = require('./util')
3 | const suite = util.suite()
4 |
5 | const LENGTH = 4096
6 | const browserSubject = BrowserBuffer.alloc(LENGTH)
7 | const nodeSubject = Buffer.alloc(LENGTH)
8 |
9 | const charset = '0123456789abcdef'
10 |
11 | let str = ''
12 |
13 | for (let i = 0; i < LENGTH * 2; i++)
14 | str += charset[Math.random() * charset.length | 0]
15 |
16 | suite
17 | .add('BrowserBuffer#write(' + LENGTH + ', "hex")', function () {
18 | browserSubject.write(str, 'hex')
19 | })
20 |
21 | if (!process.browser) suite
22 | .add('NodeBuffer#write(' + LENGTH + ', "hex")', function () {
23 | nodeSubject.write(str, 'hex')
24 | })
25 |
--------------------------------------------------------------------------------
/perf/writeUtf8.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 9
6 | var singleByte = 'abcdefghi'
7 | var multiByte = '\u0610' + '\u6100' + '\uD944\uDC00'
8 |
9 | var browserBuffer = new BrowserBuffer(LENGTH)
10 | var nodeBuffer = new Buffer(LENGTH)
11 |
12 | suite
13 | .add('BrowserBuffer#singleByte', function () {
14 | browserBuffer.write(singleByte)
15 | })
16 | .add('BrowserBuffer#multiByte', function () {
17 | browserBuffer.write(multiByte)
18 | })
19 |
20 | if (!process.browser) suite
21 | .add('NodeBuffer#singleByte', function () {
22 | nodeBuffer.write(singleByte)
23 | })
24 | .add('NodeBuffer#multiByte', function () {
25 | nodeBuffer.write(multiByte)
26 | })
27 |
--------------------------------------------------------------------------------
/perf/bracket-notation.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 50
6 | var browserBuffer = new BrowserBuffer(LENGTH)
7 | var typedarray = new Uint8Array(LENGTH)
8 | var nodeBuffer = new Buffer(LENGTH)
9 |
10 | suite
11 | .add('BrowserBuffer#bracket-notation', function () {
12 | for (var i = 0; i < LENGTH; i++) {
13 | browserBuffer[i] = i + 97
14 | }
15 | })
16 | .add('Uint8Array#bracket-notation', function () {
17 | for (var i = 0; i < LENGTH; i++) {
18 | typedarray[i] = i + 97
19 | }
20 | })
21 |
22 | if (!process.browser) suite
23 | .add('NodeBuffer#bracket-notation', function () {
24 | for (var i = 0; i < LENGTH; i++) {
25 | nodeBuffer[i] = i + 97
26 | }
27 | })
28 |
--------------------------------------------------------------------------------
/perf/copy.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 16
6 |
7 | var browserSubject = new BrowserBuffer(LENGTH)
8 | var typedarraySubject = new Uint8Array(LENGTH)
9 | var nodeSubject = new Buffer(LENGTH)
10 |
11 | var browserTarget = new BrowserBuffer(LENGTH)
12 | var typedarrayTarget = new Uint8Array(LENGTH)
13 | var nodeTarget = new Buffer(LENGTH)
14 |
15 | suite
16 | .add('BrowserBuffer#copy(' + LENGTH + ')', function () {
17 | browserSubject.copy(browserTarget)
18 | })
19 | .add('Uint8Array#copy(' + LENGTH + ')', function () {
20 | typedarrayTarget.set(typedarraySubject, 0)
21 | })
22 |
23 | if (!process.browser) suite
24 | .add('NodeBuffer#copy(' + LENGTH + ')', function () {
25 | nodeSubject.copy(nodeTarget)
26 | })
27 |
--------------------------------------------------------------------------------
/perf/copy-big.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 16000
6 |
7 | var browserSubject = new BrowserBuffer(LENGTH)
8 | var typedarraySubject = new Uint8Array(LENGTH)
9 | var nodeSubject = new Buffer(LENGTH)
10 |
11 | var browserTarget = new BrowserBuffer(LENGTH)
12 | var typedarrayTarget = new Uint8Array(LENGTH)
13 | var nodeTarget = new Buffer(LENGTH)
14 |
15 | suite
16 | .add('BrowserBuffer#copy(' + LENGTH + ')', function () {
17 | browserSubject.copy(browserTarget)
18 | })
19 | .add('Uint8Array#copy(' + LENGTH + ')', function () {
20 | typedarrayTarget.set(typedarraySubject, 0)
21 | })
22 |
23 | if (!process.browser) suite
24 | .add('NodeBuffer#copy(' + LENGTH + ')', function () {
25 | nodeSubject.copy(nodeTarget)
26 | })
27 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | unit:
11 | runs-on: ubuntu-latest
12 | strategy:
13 | fail-fast: false
14 | matrix:
15 | # see https://nodejs.org/en/about/releases/
16 | node-version: [16.x, 18.x, 20.x]
17 |
18 | steps:
19 | - uses: actions/checkout@main
20 | - uses: actions/setup-node@main
21 | with:
22 | node-version: ${{ matrix.node-version }}
23 | - run: npm install
24 | - run: npm test
25 |
26 | standard:
27 | runs-on: ubuntu-latest
28 |
29 | steps:
30 | - uses: actions/checkout@main
31 | - uses: actions/setup-node@main
32 | with:
33 | # don't use lts/* to prevent hitting rate-limit
34 | node-version: 20.x
35 | - run: npm install
36 | - run: npm run standard
37 |
--------------------------------------------------------------------------------
/perf/writeFloatBE.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 160
6 |
7 | var browserBuffer = new BrowserBuffer(LENGTH * 4)
8 | var typedarray = new Uint8Array(LENGTH * 4)
9 | var dataview = new DataView(typedarray.buffer)
10 | var nodeBuffer = new Buffer(LENGTH * 4)
11 |
12 | suite
13 | .add('BrowserBuffer#writeFloatBE', function () {
14 | for (var i = 0; i < LENGTH; i++) {
15 | browserBuffer.writeFloatBE(97.1919 + i, i * 4)
16 | }
17 | })
18 | .add('DataView#setFloat32', function () {
19 | for (var i = 0; i < LENGTH; i++) {
20 | dataview.setFloat32(i * 4, 97.1919 + i)
21 | }
22 | })
23 |
24 | if (!process.browser) suite
25 | .add('NodeBuffer#writeFloatBE', function () {
26 | for (var i = 0; i < LENGTH; i++) {
27 | nodeBuffer.writeFloatBE(97.1919 + i, i * 4)
28 | }
29 | })
30 |
--------------------------------------------------------------------------------
/test/slice.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('modifying buffer created by .slice() modifies original memory', function (t) {
5 | const buf1 = new B(26)
6 | for (let i = 0; i < 26; i++) {
7 | buf1[i] = i + 97 // 97 is ASCII a
8 | }
9 |
10 | const buf2 = buf1.slice(0, 3)
11 | t.equal(buf2.toString('ascii', 0, buf2.length), 'abc')
12 |
13 | buf2[0] = '!'.charCodeAt(0)
14 | t.equal(buf1.toString('ascii', 0, buf2.length), '!bc')
15 |
16 | t.end()
17 | })
18 |
19 | test('modifying parent buffer modifies .slice() buffer\'s memory', function (t) {
20 | const buf1 = new B(26)
21 | for (let i = 0; i < 26; i++) {
22 | buf1[i] = i + 97 // 97 is ASCII a
23 | }
24 |
25 | const buf2 = buf1.slice(0, 3)
26 | t.equal(buf2.toString('ascii', 0, buf2.length), 'abc')
27 |
28 | buf1[0] = '!'.charCodeAt(0)
29 | t.equal(buf2.toString('ascii', 0, buf2.length), '!bc')
30 |
31 | t.end()
32 | })
33 |
--------------------------------------------------------------------------------
/test/node/test-buffer-zero-fill-cli.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 | // Flags: --zero-fill-buffers
4 |
5 | // when using --zero-fill-buffers, every Buffer and SlowBuffer
6 | // instance must be zero filled upon creation
7 |
8 | require('./common');
9 | const SlowBuffer = require('../../').SlowBuffer;
10 | const assert = require('assert');
11 |
12 | function isZeroFilled(buf) {
13 | for (let n = 0; n < buf.length; n++)
14 | if (buf[n] > 0) return false;
15 | return true;
16 | }
17 |
18 | // This can be somewhat unreliable because the
19 | // allocated memory might just already happen to
20 | // contain all zeroes. The test is run multiple
21 | // times to improve the reliability.
22 | for (let i = 0; i < 50; i++) {
23 | const bufs = [
24 | Buffer.alloc(20),
25 | Buffer.allocUnsafe(20),
26 | SlowBuffer(20),
27 | Buffer(20),
28 | new SlowBuffer(20)
29 | ];
30 | for (const buf of bufs) {
31 | assert(isZeroFilled(buf));
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/test/node/test-buffer-parent-property.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | /*
5 | * Fix for https://github.com/nodejs/node/issues/8266
6 | *
7 | * Zero length Buffer objects should expose the `buffer` property of the
8 | * TypedArrays, via the `parent` property.
9 | */
10 | require('./common');
11 | const assert = require('assert');
12 |
13 | // If the length of the buffer object is zero
14 | assert((new Buffer(0)).parent instanceof ArrayBuffer);
15 |
16 | // If the length of the buffer object is equal to the underlying ArrayBuffer
17 | assert((new Buffer(Buffer.poolSize)).parent instanceof ArrayBuffer);
18 |
19 | // Same as the previous test, but with user created buffer
20 | const arrayBuffer = new ArrayBuffer(0);
21 | assert.strictEqual(new Buffer(arrayBuffer).parent, arrayBuffer);
22 | assert.strictEqual(new Buffer(arrayBuffer).buffer, arrayBuffer);
23 | assert.strictEqual(Buffer.from(arrayBuffer).parent, arrayBuffer);
24 | assert.strictEqual(Buffer.from(arrayBuffer).buffer, arrayBuffer);
25 |
26 |
--------------------------------------------------------------------------------
/test/node/test-buffer-tojson.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 |
7 | {
8 | assert.strictEqual(JSON.stringify(Buffer.alloc(0)),
9 | '{"type":"Buffer","data":[]}');
10 | assert.strictEqual(JSON.stringify(Buffer.from([1, 2, 3, 4])),
11 | '{"type":"Buffer","data":[1,2,3,4]}');
12 | }
13 |
14 | // issue GH-7849
15 | {
16 | const buf = Buffer.from('test');
17 | const json = JSON.stringify(buf);
18 | const obj = JSON.parse(json);
19 | const copy = Buffer.from(obj);
20 |
21 | assert.deepStrictEqual(buf, copy);
22 | }
23 |
24 | // GH-5110
25 | {
26 | const buffer = Buffer.from('test');
27 | const string = JSON.stringify(buffer);
28 |
29 | assert.strictEqual(string, '{"type":"Buffer","data":[116,101,115,116]}');
30 |
31 | function receiver(key, value) {
32 | return value && value.type === 'Buffer' ? Buffer.from(value.data) : value;
33 | }
34 |
35 | assert.deepStrictEqual(buffer, JSON.parse(string, receiver));
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/test/node/test-buffer-inheritance.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 |
7 |
8 | function T(n) {
9 | const ui8 = new Uint8Array(n);
10 | Object.setPrototypeOf(ui8, T.prototype);
11 | return ui8;
12 | }
13 | Object.setPrototypeOf(T.prototype, Buffer.prototype);
14 | Object.setPrototypeOf(T, Buffer);
15 |
16 | T.prototype.sum = function sum() {
17 | let cntr = 0;
18 | for (let i = 0; i < this.length; i++)
19 | cntr += this[i];
20 | return cntr;
21 | };
22 |
23 |
24 | const vals = [new T(4), T(4)];
25 |
26 | vals.forEach(function(t) {
27 | assert.strictEqual(t.constructor, T);
28 | assert.strictEqual(Object.getPrototypeOf(t), T.prototype);
29 | assert.strictEqual(Object.getPrototypeOf(Object.getPrototypeOf(t)),
30 | Buffer.prototype);
31 |
32 | t.fill(5);
33 | let cntr = 0;
34 | for (let i = 0; i < t.length; i++)
35 | cntr += t[i];
36 | assert.strictEqual(t.length * 5, cntr);
37 |
38 | // Check this does not throw
39 | t.toString();
40 | });
41 |
42 |
--------------------------------------------------------------------------------
/perf/concat.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 160
6 | var browserBuffer = new BrowserBuffer(LENGTH)
7 | var browserBuffer2 = new BrowserBuffer(LENGTH)
8 | var typedarray = new Uint8Array(LENGTH)
9 | var typedarray2 = new Uint8Array(LENGTH)
10 | var nodeBuffer = new Buffer(LENGTH)
11 | var nodeBuffer2 = new Buffer(LENGTH)
12 |
13 | ;[browserBuffer, browserBuffer2, typedarray, typedarray2, nodeBuffer, nodeBuffer2].forEach(function (buf) {
14 | for (var i = 0; i < LENGTH; i++) {
15 | buf[i] = i + 97
16 | }
17 | })
18 |
19 | suite
20 | .add('BrowserBuffer#concat', function () {
21 | var x = BrowserBuffer.concat([browserBuffer, browserBuffer2], LENGTH * 2)
22 | })
23 | .add('Uint8Array#concat', function () {
24 | var x = new Uint8Array(LENGTH * 2)
25 | x.set(typedarray, 0)
26 | x.set(typedarray2, typedarray.length)
27 | })
28 |
29 | if (!process.browser) suite
30 | .add('NodeBuffer#concat', function () {
31 | var x = Buffer.concat([nodeBuffer, nodeBuffer2], LENGTH * 2)
32 | })
33 |
--------------------------------------------------------------------------------
/bin/test.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const cp = require('child_process')
4 | const fs = require('fs')
5 | const path = require('path')
6 |
7 | const node = cp.spawn('npm', ['run', 'test-node'], { stdio: 'inherit' })
8 | node.on('close', function (code) {
9 | if (code !== 0) return process.exit(code)
10 | runBrowserTests()
11 | })
12 |
13 | function runBrowserTests () {
14 | const airtapYmlPath = path.join(__dirname, '..', '.airtap.yml')
15 |
16 | writeES5AirtapYml()
17 | cp.spawn('npm', ['run', 'test-browser-old'], { stdio: 'inherit' })
18 | .on('close', function (code) {
19 | if (code !== 0) process.exit(code)
20 | writeES6AirtapYml()
21 | cp.spawn('npm', ['run', 'test-browser-new'], { stdio: 'inherit' })
22 | .on('close', function (code) {
23 | process.exit(code)
24 | })
25 | })
26 |
27 | function writeES5AirtapYml () {
28 | fs.writeFileSync(airtapYmlPath, fs.readFileSync(path.join(__dirname, 'airtap-old.yml')))
29 | }
30 |
31 | function writeES6AirtapYml () {
32 | fs.writeFileSync(airtapYmlPath, fs.readFileSync(path.join(__dirname, 'airtap-new.yml')))
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/perf/readFloatBE.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 160
6 |
7 | var browserBuffer = new BrowserBuffer(LENGTH * 4)
8 | var typedarray = new Uint8Array(LENGTH * 4)
9 | var dataview = new DataView(typedarray.buffer)
10 | var nodeBuffer = new Buffer(LENGTH * 4)
11 |
12 | ;[browserBuffer, nodeBuffer].forEach(function (buf) {
13 | for (var i = 0; i < LENGTH; i++) {
14 | buf.writeFloatBE(97.1919 + i, i * 4)
15 | }
16 | })
17 |
18 | for (var i = 0; i < LENGTH; i++) {
19 | dataview.setFloat32(i * 4, 97.1919 + i)
20 | }
21 |
22 | suite
23 | .add('BrowserBuffer#readFloatBE', function () {
24 | for (var i = 0; i < LENGTH; i++) {
25 | var x = browserBuffer.readFloatBE(i * 4)
26 | }
27 | })
28 | .add('DataView#getFloat32', function () {
29 | for (var i = 0; i < LENGTH; i++) {
30 | var x = dataview.getFloat32(i * 4)
31 | }
32 | })
33 |
34 | if (!process.browser) suite
35 | .add('NodeBuffer#readFloatBE', function () {
36 | for (var i = 0; i < LENGTH; i++) {
37 | var x = nodeBuffer.readFloatBE(i * 4)
38 | }
39 | })
40 |
--------------------------------------------------------------------------------
/perf/readDoubleBE.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 160
6 |
7 | var browserBuffer = new BrowserBuffer(LENGTH * 8)
8 | var typedarray = new Uint8Array(LENGTH * 8)
9 | var dataview = new DataView(typedarray.buffer)
10 | var nodeBuffer = new Buffer(LENGTH * 8)
11 |
12 | ;[browserBuffer, nodeBuffer].forEach(function (buf) {
13 | for (var i = 0; i < LENGTH; i++) {
14 | buf.writeDoubleBE(97.1919 + i, i * 8)
15 | }
16 | })
17 |
18 | for (var i = 0; i < LENGTH; i++) {
19 | dataview.setFloat64(i * 8, 97.1919 + i)
20 | }
21 |
22 | suite
23 | .add('BrowserBuffer#readDoubleBE', function () {
24 | for (var i = 0; i < LENGTH; i++) {
25 | var x = browserBuffer.readDoubleBE(i * 8)
26 | }
27 | })
28 | .add('DataView#getFloat64', function () {
29 | for (var i = 0; i < LENGTH; i++) {
30 | var x = dataview.getFloat64(i * 8)
31 | }
32 | })
33 |
34 | if (!process.browser) suite
35 | .add('NodeBuffer#readDoubleBE', function () {
36 | for (var i = 0; i < LENGTH; i++) {
37 | var x = nodeBuffer.readDoubleBE(i * 8)
38 | }
39 | })
40 |
--------------------------------------------------------------------------------
/perf/readUInt32LE.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | var LENGTH = 160
6 |
7 | var browserBuffer = new BrowserBuffer(LENGTH * 4)
8 | var typedarray = new Uint8Array(LENGTH * 4)
9 | var dataview = new DataView(typedarray.buffer)
10 | var nodeBuffer = new Buffer(LENGTH * 4)
11 |
12 | ;[browserBuffer, nodeBuffer].forEach(function (buf) {
13 | for (var i = 0; i < LENGTH; i++) {
14 | buf.writeUInt32LE(7000 + i, i * 4)
15 | }
16 | })
17 |
18 | for (var i = 0; i < LENGTH; i++) {
19 | dataview.setUint32(i * 4, 7000 + i)
20 | }
21 |
22 | suite
23 | .add('BrowserBuffer#readUInt32LE', function () {
24 | for (var i = 0; i < LENGTH; i++) {
25 | var x = browserBuffer.readUInt32LE(i * 4)
26 | }
27 | })
28 | .add('DataView#getUint32', function () {
29 | for (var i = 0; i < LENGTH; i++) {
30 | var x = dataview.getUint32(i * 4, true)
31 | }
32 | })
33 |
34 | if (!process.browser) suite
35 | .add('NodeBuffer#readUInt32LE', function () {
36 | for (var i = 0; i < LENGTH; i++) {
37 | var x = nodeBuffer.readUInt32LE(i * 4)
38 | }
39 | })
40 |
--------------------------------------------------------------------------------
/test/node/test-buffer-iterator.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 | require('./common');
4 | const assert = require('assert');
5 |
6 | const buffer = Buffer.from([1, 2, 3, 4, 5]);
7 | let arr;
8 | let b;
9 |
10 | // buffers should be iterable
11 |
12 | arr = [];
13 |
14 | for (b of buffer)
15 | arr.push(b);
16 |
17 | assert.deepStrictEqual(arr, [1, 2, 3, 4, 5]);
18 |
19 |
20 | // buffer iterators should be iterable
21 |
22 | arr = [];
23 |
24 | for (b of buffer[Symbol.iterator]())
25 | arr.push(b);
26 |
27 | assert.deepStrictEqual(arr, [1, 2, 3, 4, 5]);
28 |
29 |
30 | // buffer#values() should return iterator for values
31 |
32 | arr = [];
33 |
34 | for (b of buffer.values())
35 | arr.push(b);
36 |
37 | assert.deepStrictEqual(arr, [1, 2, 3, 4, 5]);
38 |
39 |
40 | // buffer#keys() should return iterator for keys
41 |
42 | arr = [];
43 |
44 | for (b of buffer.keys())
45 | arr.push(b);
46 |
47 | assert.deepStrictEqual(arr, [0, 1, 2, 3, 4]);
48 |
49 |
50 | // buffer#entries() should return iterator for entries
51 |
52 | arr = [];
53 |
54 | for (b of buffer.entries())
55 | arr.push(b);
56 |
57 | assert.deepStrictEqual(arr, [
58 | [0, 1],
59 | [1, 2],
60 | [2, 3],
61 | [3, 4],
62 | [4, 5]
63 | ]);
64 |
65 |
--------------------------------------------------------------------------------
/test/node/test-buffer-tostring.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const assert = require('assert');
6 |
7 | // utf8, ucs2, ascii, latin1, utf16le
8 | const encodings = ['utf8', 'utf-8', 'ucs2', 'ucs-2', 'ascii', 'latin1',
9 | 'binary', 'utf16le', 'utf-16le'];
10 |
11 | encodings
12 | .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
13 | .forEach((encoding) => {
14 | assert.strictEqual(Buffer.from('foo', encoding).toString(encoding), 'foo');
15 | });
16 |
17 | // base64
18 | ['base64', 'BASE64'].forEach((encoding) => {
19 | assert.strictEqual(Buffer.from('Zm9v', encoding).toString(encoding), 'Zm9v');
20 | });
21 |
22 | // hex
23 | ['hex', 'HEX'].forEach((encoding) => {
24 | assert.strictEqual(Buffer.from('666f6f', encoding).toString(encoding),
25 | '666f6f');
26 | });
27 |
28 | // Invalid encodings
29 | for (let i = 1; i < 10; i++) {
30 | const encoding = String(i).repeat(i);
31 | const error = common.expectsError({
32 | code: 'ERR_UNKNOWN_ENCODING',
33 | type: TypeError,
34 | message: `Unknown encoding: ${encoding}`
35 | });
36 | assert.ok(!Buffer.isEncoding(encoding));
37 | assert.throws(() => Buffer.from('foo').toString(encoding), error);
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/test/write_infinity.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('write/read Infinity as a float', function (t) {
5 | const buf = new B(4)
6 | t.equal(buf.writeFloatBE(Infinity, 0), 4)
7 | t.equal(buf.readFloatBE(0), Infinity)
8 | t.end()
9 | })
10 |
11 | test('write/read -Infinity as a float', function (t) {
12 | const buf = new B(4)
13 | t.equal(buf.writeFloatBE(-Infinity, 0), 4)
14 | t.equal(buf.readFloatBE(0), -Infinity)
15 | t.end()
16 | })
17 |
18 | test('write/read Infinity as a double', function (t) {
19 | const buf = new B(8)
20 | t.equal(buf.writeDoubleBE(Infinity, 0), 8)
21 | t.equal(buf.readDoubleBE(0), Infinity)
22 | t.end()
23 | })
24 |
25 | test('write/read -Infinity as a double', function (t) {
26 | const buf = new B(8)
27 | t.equal(buf.writeDoubleBE(-Infinity, 0), 8)
28 | t.equal(buf.readDoubleBE(0), -Infinity)
29 | t.end()
30 | })
31 |
32 | test('write/read float greater than max', function (t) {
33 | const buf = new B(4)
34 | t.equal(buf.writeFloatBE(4e38, 0), 4)
35 | t.equal(buf.readFloatBE(0), Infinity)
36 | t.end()
37 | })
38 |
39 | test('write/read float less than min', function (t) {
40 | const buf = new B(4)
41 | t.equal(buf.writeFloatBE(-4e40, 0), 4)
42 | t.equal(buf.readFloatBE(0), -Infinity)
43 | t.end()
44 | })
45 |
--------------------------------------------------------------------------------
/test/node/test-buffer-concat.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 |
5 | var assert = require('assert');
6 |
7 | var zero = [];
8 | var one = [ Buffer.from('asdf') ];
9 | var long = [];
10 | for (var i = 0; i < 10; i++) long.push(Buffer.from('asdf'));
11 |
12 | var flatZero = Buffer.concat(zero);
13 | var flatOne = Buffer.concat(one);
14 | var flatLong = Buffer.concat(long);
15 | var flatLongLen = Buffer.concat(long, 40);
16 |
17 | assert(flatZero.length === 0);
18 | assert(flatOne.toString() === 'asdf');
19 | // A special case where concat used to return the first item,
20 | // if the length is one. This check is to make sure that we don't do that.
21 | assert(flatOne !== one[0]);
22 | assert(flatLong.toString() === (new Array(10 + 1).join('asdf')));
23 | assert(flatLongLen.toString() === (new Array(10 + 1).join('asdf')));
24 |
25 | assertWrongList();
26 | assertWrongList(null);
27 | assertWrongList(Buffer.from('hello'));
28 | assertWrongList([42]);
29 | assertWrongList(['hello', 'world']);
30 | assertWrongList(['hello', Buffer.from('world')]);
31 |
32 | function assertWrongList(value) {
33 | assert.throws(function() {
34 | Buffer.concat(value);
35 | }, function(err) {
36 | return err instanceof TypeError &&
37 | err.message === '"list" argument must be an Array of Buffers';
38 | });
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/test/node/test-buffer-failed-alloc-typed-arrays.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 | const SlowBuffer = require('../../').SlowBuffer;
7 |
8 | // Test failed or zero-sized Buffer allocations not affecting typed arrays.
9 | // This test exists because of a regression that occurred. Because Buffer
10 | // instances are allocated with the same underlying allocator as TypedArrays,
11 | // but Buffer's can optional be non-zero filled, there was a regression that
12 | // occurred when a Buffer allocated failed, the internal flag specifying
13 | // whether or not to zero-fill was not being reset, causing TypedArrays to
14 | // allocate incorrectly.
15 | const zeroArray = new Uint32Array(10).fill(0);
16 | const sizes = [1e10, 0, 0.1, -1, 'a', undefined, null, NaN];
17 | const allocators = [
18 | Buffer,
19 | SlowBuffer,
20 | Buffer.alloc,
21 | Buffer.allocUnsafe,
22 | Buffer.allocUnsafeSlow
23 | ];
24 | for (const allocator of allocators) {
25 | for (const size of sizes) {
26 | try {
27 | // These allocations are known to fail. If they do,
28 | // Uint32Array should still produce a zeroed out result.
29 | allocator(size);
30 | } catch (e) {
31 | assert.deepStrictEqual(new Uint32Array(10), zeroArray);
32 | }
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/test/compare.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('buffer.compare', function (t) {
5 | const b = new B(1).fill('a')
6 | const c = new B(1).fill('c')
7 | const d = new B(2).fill('aa')
8 |
9 | t.equal(b.compare(c), -1)
10 | t.equal(c.compare(d), 1)
11 | t.equal(d.compare(b), 1)
12 | t.equal(b.compare(d), -1)
13 |
14 | // static method
15 | t.equal(B.compare(b, c), -1)
16 | t.equal(B.compare(c, d), 1)
17 | t.equal(B.compare(d, b), 1)
18 | t.equal(B.compare(b, d), -1)
19 | t.end()
20 | })
21 |
22 | test('buffer.compare argument validation', function (t) {
23 | t.throws(function () {
24 | const b = new B(1)
25 | B.compare(b, 'abc')
26 | })
27 |
28 | t.throws(function () {
29 | const b = new B(1)
30 | B.compare('abc', b)
31 | })
32 |
33 | t.throws(function () {
34 | const b = new B(1)
35 | b.compare('abc')
36 | })
37 | t.end()
38 | })
39 |
40 | test('buffer.equals', function (t) {
41 | const b = new B(5).fill('abcdf')
42 | const c = new B(5).fill('abcdf')
43 | const d = new B(5).fill('abcde')
44 | const e = new B(6).fill('abcdef')
45 |
46 | t.ok(b.equals(c))
47 | t.ok(!c.equals(d))
48 | t.ok(!d.equals(e))
49 | t.end()
50 | })
51 |
52 | test('buffer.equals argument validation', function (t) {
53 | t.throws(function () {
54 | const b = new B(1)
55 | b.equals('abc')
56 | })
57 | t.end()
58 | })
59 |
--------------------------------------------------------------------------------
/perf/readUtf8.js:
--------------------------------------------------------------------------------
1 | var BrowserBuffer = require('../').Buffer // (this module)
2 | var util = require('./util')
3 | var suite = util.suite()
4 |
5 | // 256 random bytes
6 | var array = [ 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 ]
7 |
8 | var browserBuffer = new BrowserBuffer(array)
9 | var nodeBuffer = new Buffer(array)
10 |
11 | suite
12 | .add('BrowserBuffer#readUtf8', function () {
13 | browserBuffer.toString()
14 | })
15 |
16 | if (!process.browser) suite
17 | .add('NodeBuffer#readUtf8', function () {
18 | nodeBuffer.toString()
19 | })
20 |
--------------------------------------------------------------------------------
/test/write-hex.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const Buffer = require('../').Buffer
4 | const test = require('tape')
5 |
6 | test('buffer.write("hex") should stop on invalid characters', function (t) {
7 | // Test the entire 16-bit space.
8 | for (let ch = 0; ch <= 0xffff; ch++) {
9 | // 0-9
10 | if (ch >= 0x30 && ch <= 0x39) {
11 | continue
12 | }
13 |
14 | // A-F
15 | if (ch >= 0x41 && ch <= 0x46) {
16 | continue
17 | }
18 |
19 | // a-f
20 | if (ch >= 0x61 && ch <= 0x66) {
21 | continue
22 | }
23 |
24 | for (const str of [
25 | 'abcd' + String.fromCharCode(ch) + 'ef0',
26 | 'abcde' + String.fromCharCode(ch) + 'f0',
27 | 'abcd' + String.fromCharCode(ch + 0) + String.fromCharCode(ch + 1) + 'f0',
28 | 'abcde' + String.fromCharCode(ch + 0) + String.fromCharCode(ch + 1) + '0'
29 | ]) {
30 | const buf = Buffer.alloc(4)
31 | t.equal(str.length, 8)
32 | t.equal(buf.write(str, 'hex'), 2)
33 | t.equal(buf.toString('hex'), 'abcd0000')
34 | t.equal(Buffer.from(str, 'hex').toString('hex'), 'abcd')
35 | }
36 | }
37 |
38 | t.end()
39 | })
40 |
41 | test('buffer.write("hex") should truncate odd string lengths', function (t) {
42 | const buf = Buffer.alloc(32)
43 | const charset = '0123456789abcdef'
44 |
45 | let str = ''
46 |
47 | for (let i = 0; i < 63; i++) {
48 | str += charset[Math.random() * charset.length | 0]
49 | }
50 |
51 | t.equal(buf.write('abcde', 'hex'), 2)
52 | t.equal(buf.toString('hex', 0, 3), 'abcd00')
53 |
54 | buf.fill(0)
55 |
56 | t.equal(buf.write(str, 'hex'), 31)
57 | t.equal(buf.toString('hex', 0, 32), str.slice(0, -1) + '00')
58 | t.end()
59 | })
60 |
--------------------------------------------------------------------------------
/test/basic.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('instanceof Buffer', function (t) {
5 | const buf = new B([1, 2])
6 | t.ok(buf instanceof B)
7 | t.end()
8 | })
9 |
10 | test('convert to Uint8Array in modern browsers', function (t) {
11 | const buf = new B([1, 2])
12 | const uint8array = new Uint8Array(buf.buffer)
13 | t.ok(uint8array instanceof Uint8Array)
14 | t.equal(uint8array[0], 1)
15 | t.equal(uint8array[1], 2)
16 | t.end()
17 | })
18 |
19 | test('indexes from a string', function (t) {
20 | const buf = new B('abc')
21 | t.equal(buf[0], 97)
22 | t.equal(buf[1], 98)
23 | t.equal(buf[2], 99)
24 | t.end()
25 | })
26 |
27 | test('indexes from an array', function (t) {
28 | const buf = new B([97, 98, 99])
29 | t.equal(buf[0], 97)
30 | t.equal(buf[1], 98)
31 | t.equal(buf[2], 99)
32 | t.end()
33 | })
34 |
35 | test('setting index value should modify buffer contents', function (t) {
36 | const buf = new B([97, 98, 99])
37 | t.equal(buf[2], 99)
38 | t.equal(buf.toString(), 'abc')
39 |
40 | buf[2] += 10
41 | t.equal(buf[2], 109)
42 | t.equal(buf.toString(), 'abm')
43 | t.end()
44 | })
45 |
46 | test('storing negative number should cast to unsigned', function (t) {
47 | let buf = new B(1)
48 |
49 | buf[0] = -3
50 | t.equal(buf[0], 253)
51 |
52 | buf = new B(1)
53 | buf.writeInt8(-3, 0)
54 | t.equal(buf[0], 253)
55 |
56 | t.end()
57 | })
58 |
59 | test('test that memory is copied from array-like', function (t) {
60 | const u = new Uint8Array(4)
61 | const b = new B(u)
62 | b[0] = 1
63 | b[1] = 2
64 | b[2] = 3
65 | b[3] = 4
66 |
67 | t.equal(u[0], 0)
68 | t.equal(u[1], 0)
69 | t.equal(u[2], 0)
70 | t.equal(u[3], 0)
71 |
72 | t.end()
73 | })
74 |
--------------------------------------------------------------------------------
/test/node/test-buffer-compare.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const assert = require('assert');
6 |
7 | const b = Buffer.alloc(1, 'a');
8 | const c = Buffer.alloc(1, 'c');
9 | const d = Buffer.alloc(2, 'aa');
10 | const e = new Uint8Array([ 0x61, 0x61 ]); // ASCII 'aa', same as d
11 |
12 | assert.strictEqual(b.compare(c), -1);
13 | assert.strictEqual(c.compare(d), 1);
14 | assert.strictEqual(d.compare(b), 1);
15 | assert.strictEqual(d.compare(e), 0);
16 | assert.strictEqual(b.compare(d), -1);
17 | assert.strictEqual(b.compare(b), 0);
18 |
19 | assert.strictEqual(Buffer.compare(b, c), -1);
20 | assert.strictEqual(Buffer.compare(c, d), 1);
21 | assert.strictEqual(Buffer.compare(d, b), 1);
22 | assert.strictEqual(Buffer.compare(b, d), -1);
23 | assert.strictEqual(Buffer.compare(c, c), 0);
24 | assert.strictEqual(Buffer.compare(e, e), 0);
25 | assert.strictEqual(Buffer.compare(d, e), 0);
26 | assert.strictEqual(Buffer.compare(d, b), 1);
27 |
28 | assert.strictEqual(Buffer.compare(Buffer.alloc(0), Buffer.alloc(0)), 0);
29 | assert.strictEqual(Buffer.compare(Buffer.alloc(0), Buffer.alloc(1)), -1);
30 | assert.strictEqual(Buffer.compare(Buffer.alloc(1), Buffer.alloc(0)), 1);
31 |
32 | const errMsg = common.expectsError({
33 | code: 'ERR_INVALID_ARG_TYPE',
34 | type: TypeError,
35 | message: 'The "buf1", "buf2" arguments must be one of ' +
36 | 'type Buffer or Uint8Array'
37 | }, 2);
38 | assert.throws(() => Buffer.compare(Buffer.alloc(1), 'abc'), errMsg);
39 |
40 | assert.throws(() => Buffer.compare('abc', Buffer.alloc(1)), errMsg);
41 |
42 | common.expectsError(() => Buffer.alloc(1).compare('abc'), {
43 | code: 'ERR_INVALID_ARG_TYPE',
44 | type: TypeError,
45 | message: 'The "target" argument must be one of ' +
46 | 'type Buffer or Uint8Array. Received type string'
47 | });
48 |
49 |
--------------------------------------------------------------------------------
/test/base64.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('base64: ignore whitespace', function (t) {
5 | const text = '\n YW9ldQ== '
6 | const buf = new B(text, 'base64')
7 | t.equal(buf.toString(), 'aoeu')
8 | t.end()
9 | })
10 |
11 | test('base64: strings without padding', function (t) {
12 | t.equal((new B('YW9ldQ', 'base64').toString()), 'aoeu')
13 | t.end()
14 | })
15 |
16 | test('base64: newline in utf8 -- should not be an issue', function (t) {
17 | t.equal(
18 | new B('LS0tCnRpdGxlOiBUaHJlZSBkYXNoZXMgbWFya3MgdGhlIHNwb3QKdGFnczoK', 'base64').toString('utf8'),
19 | '---\ntitle: Three dashes marks the spot\ntags:\n'
20 | )
21 | t.end()
22 | })
23 |
24 | test('base64: newline in base64 -- should get stripped', function (t) {
25 | t.equal(
26 | new B('LS0tCnRpdGxlOiBUaHJlZSBkYXNoZXMgbWFya3MgdGhlIHNwb3QKdGFnczoK\nICAtIHlhbWwKICAtIGZyb250LW1hdHRlcgogIC0gZGFzaGVzCmV4cGFuZWQt', 'base64').toString('utf8'),
27 | '---\ntitle: Three dashes marks the spot\ntags:\n - yaml\n - front-matter\n - dashes\nexpaned-'
28 | )
29 | t.end()
30 | })
31 |
32 | test('base64: tab characters in base64 - should get stripped', function (t) {
33 | t.equal(
34 | new B('LS0tCnRpdGxlOiBUaHJlZSBkYXNoZXMgbWFya3MgdGhlIHNwb3QKdGFnczoK\t\t\t\tICAtIHlhbWwKICAtIGZyb250LW1hdHRlcgogIC0gZGFzaGVzCmV4cGFuZWQt', 'base64').toString('utf8'),
35 | '---\ntitle: Three dashes marks the spot\ntags:\n - yaml\n - front-matter\n - dashes\nexpaned-'
36 | )
37 | t.end()
38 | })
39 |
40 | test('base64: invalid non-alphanumeric characters -- should be stripped', function (t) {
41 | t.equal(
42 | new B('!"#$%&\'()*,.:;<=>?@[\\]^`{|}~', 'base64').toString('utf8'),
43 | ''
44 | )
45 | t.end()
46 | })
47 |
48 | test('base64: high byte', function (t) {
49 | const highByte = B.from([128])
50 | t.deepEqual(
51 | B.alloc(1, highByte.toString('base64'), 'base64'),
52 | highByte
53 | )
54 | t.end()
55 | })
56 |
--------------------------------------------------------------------------------
/test/node/test-buffer-from.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const { deepStrictEqual, throws } = require('assert');
6 | const { runInNewContext } = require('vm');
7 |
8 | const checkString = 'test';
9 |
10 | const check = Buffer.from(checkString);
11 |
12 | class MyString extends String {
13 | constructor() {
14 | super(checkString);
15 | }
16 | }
17 |
18 | class MyPrimitive {
19 | [Symbol.toPrimitive]() {
20 | return checkString;
21 | }
22 | }
23 |
24 | class MyBadPrimitive {
25 | [Symbol.toPrimitive]() {
26 | return 1;
27 | }
28 | }
29 |
30 | deepStrictEqual(Buffer.from(new String(checkString)), check);
31 | deepStrictEqual(Buffer.from(new MyString()), check);
32 | deepStrictEqual(Buffer.from(new MyPrimitive()), check);
33 | deepStrictEqual(
34 | Buffer.from(runInNewContext('new String(checkString)', { checkString })),
35 | check
36 | );
37 |
38 | [
39 | [{}, 'object'],
40 | [new Boolean(true), 'boolean'],
41 | [{ valueOf() { return null; } }, 'object'],
42 | [{ valueOf() { return undefined; } }, 'object'],
43 | [{ valueOf: null }, 'object'],
44 | [Object.create(null), 'object']
45 | ].forEach(([input, actualType]) => {
46 | const err = common.expectsError({
47 | code: 'ERR_INVALID_ARG_TYPE',
48 | type: TypeError,
49 | message: 'The first argument must be one of type string, Buffer, ' +
50 | 'ArrayBuffer, Array, or Array-like Object. Received ' +
51 | `type ${actualType}`
52 | });
53 | throws(() => Buffer.from(input), err);
54 | });
55 |
56 | [
57 | new Number(true),
58 | new MyBadPrimitive()
59 | ].forEach((input) => {
60 | const errMsg = common.expectsError({
61 | code: 'ERR_INVALID_ARG_TYPE',
62 | type: TypeError,
63 | message: 'The "value" argument must not be of type number. ' +
64 | 'Received type number'
65 | });
66 | throws(() => Buffer.from(input), errMsg);
67 | });
68 |
69 |
--------------------------------------------------------------------------------
/test/node/test-buffer-bigint64.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | var Buffer = require('../../').Buffer
3 | const assert = require('assert')
4 |
5 | const buf = Buffer.allocUnsafe(8)
6 |
7 | ;['LE', 'BE'].forEach(function(endianness) {
8 | // Should allow simple BigInts to be written and read
9 | let val = 123456789n
10 | buf['writeBigInt64' + endianness](val, 0)
11 | let rtn = buf['readBigInt64' + endianness](0)
12 | assert.strictEqual(val, rtn)
13 |
14 | // Should allow INT64_MAX to be written and read
15 | val = 0x7fffffffffffffffn
16 | buf['writeBigInt64' + endianness](val, 0)
17 | rtn = buf['readBigInt64' + endianness](0)
18 | assert.strictEqual(val, rtn)
19 |
20 | // Should read and write a negative signed 64-bit integer
21 | val = -123456789n
22 | buf['writeBigInt64' + endianness](val, 0)
23 | assert.strictEqual(val, buf['readBigInt64' + endianness](0))
24 |
25 | // Should read and write an unsigned 64-bit integer
26 | val = 123456789n
27 | buf['writeBigUInt64' + endianness](val, 0)
28 | assert.strictEqual(val, buf['readBigUInt64' + endianness](0))
29 |
30 | // Should throw a RangeError upon INT64_MAX+1 being written
31 | assert.throws(function() {
32 | const val = 0x8000000000000000n
33 | buf['writeBigInt64' + endianness](val, 0)
34 | }, RangeError)
35 |
36 | // Should throw a RangeError upon UINT64_MAX+1 being written
37 | assert.throws(function() {
38 | const val = 0x10000000000000000n
39 | buf['writeBigUInt64' + endianness](val, 0)
40 | }, function(err) {
41 | assert(err instanceof RangeError)
42 | assert(err.code === 'ERR_OUT_OF_RANGE')
43 | assert(err.message === 'The value of "value" is out of range. It must be ' +
44 | '>= 0n and < 2n ** 64n. Received 18_446_744_073_709_551_616n')
45 | return true;
46 | })
47 |
48 | // Should throw a TypeError upon invalid input
49 | assert.throws(function() {
50 | buf['writeBigInt64' + endianness]('bad', 0)
51 | }, TypeError)
52 |
53 | // Should throw a TypeError upon invalid input
54 | assert.throws(function() {
55 | buf['writeBigUInt64' + endianness]('bad', 0)
56 | }, TypeError)
57 | })
58 |
--------------------------------------------------------------------------------
/test/node/test-buffer-ascii.js:
--------------------------------------------------------------------------------
1 | // Copyright Joyent, Inc. and other Node contributors.var Buffer = require('../../').Buffer;
2 | // Copyright Joyent, Inc. and other Node contributors.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a
5 | // copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit
9 | // persons to whom the Software is furnished to do so, subject to the
10 | // following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included
13 | // in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
18 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
23 | 'use strict';
24 | require('./common');
25 | const assert = require('assert');
26 |
27 | // ASCII conversion in node.js simply masks off the high bits,
28 | // it doesn't do transliteration.
29 | assert.strictEqual(Buffer.from('hérité').toString('ascii'), 'hC)ritC)');
30 |
31 | // 71 characters, 78 bytes. The ’ character is a triple-byte sequence.
32 | const input = 'C’est, graphiquement, la réunion d’un accent aigu ' +
33 | 'et d’un accent grave.';
34 |
35 | const expected = 'Cb\u0000\u0019est, graphiquement, la rC)union ' +
36 | 'db\u0000\u0019un accent aigu et db\u0000\u0019un ' +
37 | 'accent grave.';
38 |
39 | const buf = Buffer.from(input);
40 |
41 | for (let i = 0; i < expected.length; ++i) {
42 | assert.strictEqual(buf.slice(i).toString('ascii'), expected.slice(i));
43 |
44 | // Skip remainder of multi-byte sequence.
45 | if (input.charCodeAt(i) > 65535) ++i;
46 | if (input.charCodeAt(i) > 127) ++i;
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/test/node/test-buffer-badhex.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 | require('./common');
4 | const assert = require('assert');
5 |
6 | // Test hex strings and bad hex strings
7 | {
8 | const buf = Buffer.alloc(4);
9 | assert.strictEqual(buf.length, 4);
10 | assert.deepStrictEqual(buf, new Buffer([0, 0, 0, 0]));
11 | assert.strictEqual(buf.write('abcdxx', 0, 'hex'), 2);
12 | assert.deepStrictEqual(buf, new Buffer([0xab, 0xcd, 0x00, 0x00]));
13 | assert.strictEqual(buf.toString('hex'), 'abcd0000');
14 | assert.strictEqual(buf.write('abcdef01', 0, 'hex'), 4);
15 | assert.deepStrictEqual(buf, new Buffer([0xab, 0xcd, 0xef, 0x01]));
16 | assert.strictEqual(buf.toString('hex'), 'abcdef01');
17 | // Node Buffer behavior check
18 | // > Buffer.from('abc def01','hex')
19 | //
20 | assert.strictEqual(buf.write('00000000', 0, 'hex'), 4);
21 | assert.strictEqual(buf.write('abc def01', 0, 'hex'), 1);
22 | assert.deepStrictEqual(buf, new Buffer([0xab, 0, 0, 0]));
23 | assert.strictEqual(buf.toString('hex'), 'ab000000');
24 | assert.deepStrictEqual(Buffer.from('abc def01', 'hex'), Buffer.from([0xab]));
25 |
26 | const copy = Buffer.from(buf.toString('hex'), 'hex');
27 | assert.strictEqual(buf.toString('hex'), copy.toString('hex'));
28 | }
29 |
30 | {
31 | const buf = Buffer.alloc(5);
32 | assert.strictEqual(buf.write('abcdxx', 1, 'hex'), 2);
33 | assert.strictEqual(buf.toString('hex'), '00abcd0000');
34 | }
35 |
36 | {
37 | const buf = Buffer.alloc(4);
38 | assert.deepStrictEqual(buf, new Buffer([0, 0, 0, 0]));
39 | assert.strictEqual(buf.write('xxabcd', 0, 'hex'), 0);
40 | assert.deepStrictEqual(buf, new Buffer([0, 0, 0, 0]));
41 | assert.strictEqual(buf.write('xxab', 1, 'hex'), 0);
42 | assert.deepStrictEqual(buf, new Buffer([0, 0, 0, 0]));
43 | assert.strictEqual(buf.write('cdxxab', 0, 'hex'), 1);
44 | assert.deepStrictEqual(buf, new Buffer([0xcd, 0, 0, 0]));
45 | }
46 |
47 | {
48 | const buf = Buffer.alloc(256);
49 | for (let i = 0; i < 256; i++)
50 | buf[i] = i;
51 |
52 | const hex = buf.toString('hex');
53 | assert.deepStrictEqual(Buffer.from(hex, 'hex'), buf);
54 |
55 | const badHex = `${hex.slice(0, 256)}xx${hex.slice(256, 510)}`;
56 | assert.deepStrictEqual(Buffer.from(badHex, 'hex'), buf.slice(0, 128));
57 | }
58 |
--------------------------------------------------------------------------------
/test/node/test-buffer-inspect.js:
--------------------------------------------------------------------------------
1 | // Copyright Joyent, Inc. and other Node contributors.
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a
4 | // copy of this software and associated documentation files (the
5 | // "Software"), to deal in the Software without restriction, including
6 | // without limitation the rights to use, copy, modify, merge, publish,
7 | // distribute, sublicense, and/or sell copies of the Software, and to permit
8 | // persons to whom the Software is furnished to do so, subject to the
9 | // following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included
12 | // in all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | 'use strict';
23 | var Buffer = require('../../').Buffer;
24 |
25 | require('./common');
26 | const assert = require('assert');
27 | const util = require('util');
28 | const buffer = require('../../');
29 |
30 | var defaultMaxBytes = buffer.INSPECT_MAX_BYTES;
31 | buffer.INSPECT_MAX_BYTES = 2;
32 |
33 | let b = Buffer.allocUnsafe(4);
34 | b.fill('1234');
35 |
36 | let s = buffer.SlowBuffer(4);
37 | s.fill('1234');
38 |
39 | let expected = '';
40 |
41 | assert.strictEqual(util.inspect(b), expected);
42 | assert.strictEqual(util.inspect(s), expected);
43 |
44 | b = Buffer.allocUnsafe(2);
45 | b.fill('12');
46 |
47 | s = buffer.SlowBuffer(2);
48 | s.fill('12');
49 |
50 | expected = '';
51 |
52 | assert.strictEqual(util.inspect(b), expected);
53 | assert.strictEqual(util.inspect(s), expected);
54 |
55 | buffer.INSPECT_MAX_BYTES = Infinity;
56 |
57 | assert.strictEqual(util.inspect(b), expected);
58 | assert.strictEqual(util.inspect(s), expected);
59 |
60 | b.inspect = undefined;
61 | assert.strictEqual(util.inspect(b), expected);
62 |
63 | buffer.INSPECT_MAX_BYTES = defaultMaxBytes;
64 |
--------------------------------------------------------------------------------
/test/node/test-buffer-slow.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const assert = require('assert');
6 | const buffer = require('../../');
7 | const SlowBuffer = buffer.SlowBuffer;
8 |
9 | const ones = [1, 1, 1, 1];
10 |
11 | // should create a Buffer
12 | let sb = SlowBuffer(4);
13 | assert(sb instanceof Buffer);
14 | assert.strictEqual(sb.length, 4);
15 | sb.fill(1);
16 | for (const [key, value] of sb.entries()) {
17 | assert.deepStrictEqual(value, ones[key]);
18 | }
19 |
20 | // underlying ArrayBuffer should have the same length
21 | assert.strictEqual(sb.buffer.byteLength, 4);
22 |
23 | // should work without new
24 | sb = SlowBuffer(4);
25 | assert(sb instanceof Buffer);
26 | assert.strictEqual(sb.length, 4);
27 | sb.fill(1);
28 | for (const [key, value] of sb.entries()) {
29 | assert.deepStrictEqual(value, ones[key]);
30 | }
31 |
32 | // should work with edge cases
33 | assert.strictEqual(SlowBuffer(0).length, 0);
34 | try {
35 | assert.strictEqual(
36 | SlowBuffer(buffer.kMaxLength).length, buffer.kMaxLength);
37 | } catch (e) {
38 | // Don't match on message as it is from the JavaScript engine. V8 and
39 | // ChakraCore provide different messages.
40 | assert.strictEqual(e.name, 'RangeError');
41 | }
42 |
43 | // should work with number-coercible values
44 | assert.strictEqual(SlowBuffer('6').length, 6);
45 | assert.strictEqual(SlowBuffer(true).length, 1);
46 |
47 | // should create zero-length buffer if parameter is not a number
48 | assert.strictEqual(SlowBuffer().length, 0);
49 | assert.strictEqual(SlowBuffer(NaN).length, 0);
50 | assert.strictEqual(SlowBuffer({}).length, 0);
51 | assert.strictEqual(SlowBuffer('string').length, 0);
52 |
53 | // should throw with invalid length
54 | const bufferMaxSizeMsg = common.expectsError({
55 | code: 'ERR_INVALID_OPT_VALUE',
56 | type: RangeError,
57 | message: /^The value "[^"]*" is invalid for option "size"$/
58 | }, 2);
59 | assert.throws(function() {
60 | SlowBuffer(Infinity);
61 | }, bufferMaxSizeMsg);
62 | common.expectsError(function() {
63 | SlowBuffer(-1);
64 | }, {
65 | code: 'ERR_INVALID_OPT_VALUE',
66 | type: RangeError,
67 | message: 'The value "-1" is invalid for option "size"'
68 | });
69 |
70 | assert.throws(function() {
71 | SlowBuffer(buffer.kMaxLength + 1);
72 | }, bufferMaxSizeMsg);
73 |
74 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Feross Aboukhadijeh, and other contributors.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 | Parts of this software are based on node.js:
24 |
25 | Copyright Node.js contributors. All rights reserved.
26 |
27 | Permission is hereby granted, free of charge, to any person obtaining a copy
28 | of this software and associated documentation files (the "Software"), to
29 | deal in the Software without restriction, including without limitation the
30 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
31 | sell copies of the Software, and to permit persons to whom the Software is
32 | furnished to do so, subject to the following conditions:
33 |
34 | The above copyright notice and this permission notice shall be included in
35 | all copies or substantial portions of the Software.
36 |
37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
43 | IN THE SOFTWARE.
44 |
45 | See https://github.com/nodejs/node/blob/main/LICENSE for more information.
46 |
--------------------------------------------------------------------------------
/test/node/test-buffer-write.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const assert = require('assert');
6 |
7 | const outsideBounds = common.expectsError({
8 | code: 'ERR_BUFFER_OUT_OF_BOUNDS',
9 | type: RangeError,
10 | message: 'Attempt to write outside buffer bounds'
11 | }, 2);
12 |
13 | assert.throws(() => Buffer.alloc(9).write('foo', -1), outsideBounds);
14 | assert.throws(() => Buffer.alloc(9).write('foo', 10), outsideBounds);
15 |
16 | const resultMap = new Map([
17 | ['utf8', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
18 | ['ucs2', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])],
19 | ['ascii', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
20 | ['latin1', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
21 | ['binary', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
22 | ['utf16le', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])],
23 | ['base64', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])],
24 | ['hex', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])]
25 | ]);
26 |
27 | // utf8, ucs2, ascii, latin1, utf16le
28 | const encodings = ['utf8', 'utf-8', 'ucs2', 'ucs-2', 'ascii', 'latin1',
29 | 'binary', 'utf16le', 'utf-16le'];
30 |
31 | encodings
32 | .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
33 | .forEach((encoding) => {
34 | const buf = Buffer.alloc(9);
35 | const len = Buffer.byteLength('foo', encoding);
36 | assert.strictEqual(buf.write('foo', 0, len, encoding), len);
37 |
38 | if (encoding.includes('-'))
39 | encoding = encoding.replace('-', '');
40 |
41 | assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase()));
42 | });
43 |
44 | // base64
45 | ['base64', 'BASE64'].forEach((encoding) => {
46 | const buf = Buffer.alloc(9);
47 | const len = Buffer.byteLength('Zm9v', encoding);
48 |
49 | assert.strictEqual(buf.write('Zm9v', 0, len, encoding), len);
50 | assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase()));
51 | });
52 |
53 | // hex
54 | ['hex', 'HEX'].forEach((encoding) => {
55 | const buf = Buffer.alloc(9);
56 | const len = Buffer.byteLength('666f6f', encoding);
57 |
58 | assert.strictEqual(buf.write('666f6f', 0, len, encoding), len);
59 | assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase()));
60 | });
61 |
62 | // Invalid encodings
63 | for (let i = 1; i < 10; i++) {
64 | const encoding = String(i).repeat(i);
65 | const error = common.expectsError({
66 | code: 'ERR_UNKNOWN_ENCODING',
67 | type: TypeError,
68 | message: `Unknown encoding: ${encoding}`
69 | });
70 |
71 | assert.ok(!Buffer.isEncoding(encoding));
72 | assert.throws(() => Buffer.alloc(9).write('foo', encoding), error);
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/test/node/test-buffer-compare-offset.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const assert = require('assert');
6 |
7 | const a = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
8 | const b = Buffer.from([5, 6, 7, 8, 9, 0, 1, 2, 3, 4]);
9 |
10 | assert.strictEqual(-1, a.compare(b));
11 |
12 | // Equivalent to a.compare(b).
13 | assert.strictEqual(-1, a.compare(b, 0));
14 | assert.strictEqual(-1, a.compare(b, '0'));
15 | assert.strictEqual(-1, a.compare(b, undefined));
16 |
17 | // Equivalent to a.compare(b).
18 | assert.strictEqual(-1, a.compare(b, 0, undefined, 0));
19 |
20 | // Zero-length target, return 1
21 | assert.strictEqual(1, a.compare(b, 0, 0, 0));
22 | assert.strictEqual(1, a.compare(b, '0', '0', '0'));
23 |
24 | // Equivalent to Buffer.compare(a, b.slice(6, 10))
25 | assert.strictEqual(1, a.compare(b, 6, 10));
26 |
27 | // Zero-length source, return -1
28 | assert.strictEqual(-1, a.compare(b, 6, 10, 0, 0));
29 |
30 | // Zero-length source and target, return 0
31 | assert.strictEqual(0, a.compare(b, 0, 0, 0, 0));
32 | assert.strictEqual(0, a.compare(b, 1, 1, 2, 2));
33 |
34 | // Equivalent to Buffer.compare(a.slice(4), b.slice(0, 5))
35 | assert.strictEqual(1, a.compare(b, 0, 5, 4));
36 |
37 | // Equivalent to Buffer.compare(a.slice(1), b.slice(5))
38 | assert.strictEqual(1, a.compare(b, 5, undefined, 1));
39 |
40 | // Equivalent to Buffer.compare(a.slice(2), b.slice(2, 4))
41 | assert.strictEqual(-1, a.compare(b, 2, 4, 2));
42 |
43 | // Equivalent to Buffer.compare(a.slice(4), b.slice(0, 7))
44 | assert.strictEqual(-1, a.compare(b, 0, 7, 4));
45 |
46 | // Equivalent to Buffer.compare(a.slice(4, 6), b.slice(0, 7));
47 | assert.strictEqual(-1, a.compare(b, 0, 7, 4, 6));
48 |
49 | // zero length target
50 | assert.strictEqual(1, a.compare(b, 0, null));
51 |
52 | // coerces to targetEnd == 5
53 | assert.strictEqual(-1, a.compare(b, 0, { valueOf: () => 5 }));
54 |
55 | // zero length target
56 | assert.strictEqual(1, a.compare(b, Infinity, -Infinity));
57 |
58 | // zero length target because default for targetEnd <= targetSource
59 | assert.strictEqual(1, a.compare(b, '0xff'));
60 |
61 | const oor = common.expectsError({ code: 'ERR_INDEX_OUT_OF_RANGE' }, 7);
62 |
63 | assert.throws(() => a.compare(b, 0, 100, 0), oor);
64 | assert.throws(() => a.compare(b, 0, 1, 0, 100), oor);
65 | assert.throws(() => a.compare(b, -1), oor);
66 | assert.throws(() => a.compare(b, 0, '0xff'), oor);
67 | assert.throws(() => a.compare(b, 0, Infinity), oor);
68 | assert.throws(() => a.compare(b, 0, 1, -1), oor);
69 | assert.throws(() => a.compare(b, -Infinity, Infinity), oor);
70 | common.expectsError(() => a.compare(), {
71 | code: 'ERR_INVALID_ARG_TYPE',
72 | type: TypeError,
73 | message: 'The "target" argument must be one of ' +
74 | 'type Buffer or Uint8Array. Received type undefined'
75 | });
76 |
77 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "buffer",
3 | "description": "Node.js Buffer API, for the browser",
4 | "version": "6.0.3",
5 | "author": {
6 | "name": "Feross Aboukhadijeh",
7 | "email": "feross@feross.org",
8 | "url": "https://feross.org"
9 | },
10 | "bugs": {
11 | "url": "https://github.com/feross/buffer/issues"
12 | },
13 | "contributors": [
14 | "Daniel Cousens",
15 | "Romain Beauxis ",
16 | "James Halliday "
17 | ],
18 | "dependencies": {
19 | "base64-js": "^1.3.1",
20 | "ieee754": "^1.2.1"
21 | },
22 | "devDependencies": {
23 | "airtap": "^3.0.0",
24 | "benchmark": "^2.1.4",
25 | "browserify": "^17.0.0",
26 | "concat-stream": "^2.0.0",
27 | "hyperquest": "^2.1.3",
28 | "is-buffer": "^2.0.5",
29 | "is-nan": "^1.3.0",
30 | "split": "^1.0.1",
31 | "standard": "*",
32 | "tape": "^5.0.1",
33 | "through2": "^4.0.2",
34 | "uglify-js": "^3.11.5"
35 | },
36 | "homepage": "https://github.com/feross/buffer",
37 | "jspm": {
38 | "map": {
39 | "./index.js": {
40 | "node": "@node/buffer"
41 | }
42 | }
43 | },
44 | "keywords": [
45 | "arraybuffer",
46 | "browser",
47 | "browserify",
48 | "buffer",
49 | "compatible",
50 | "dataview",
51 | "uint8array"
52 | ],
53 | "license": "MIT",
54 | "main": "index.js",
55 | "types": "index.d.ts",
56 | "repository": {
57 | "type": "git",
58 | "url": "https://github.com/feross/buffer.git"
59 | },
60 | "scripts": {
61 | "perf": "browserify --debug perf/bracket-notation.js > perf/bundle.js && open perf/index.html",
62 | "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",
63 | "size": "browserify -r ./ | uglifyjs -c -m | gzip | wc -c",
64 | "standard": "standard",
65 | "test": "tape test/*.js test/node/*.js",
66 | "test-browser-old": "airtap -- test/*.js",
67 | "test-browser-old-local": "airtap --local -- test/*.js",
68 | "test-browser-new": "airtap -- test/*.js test/node/*.js",
69 | "test-browser-new-local": "airtap --local -- test/*.js test/node/*.js",
70 | "update-authors": "./bin/update-authors.sh"
71 | },
72 | "standard": {
73 | "ignore": [
74 | "test/node/**/*.js",
75 | "test/common.js",
76 | "test/_polyfill.js",
77 | "perf/**/*.js"
78 | ]
79 | },
80 | "funding": [
81 | {
82 | "type": "github",
83 | "url": "https://github.com/sponsors/feross"
84 | },
85 | {
86 | "type": "patreon",
87 | "url": "https://www.patreon.com/feross"
88 | },
89 | {
90 | "type": "consulting",
91 | "url": "https://feross.org/support"
92 | }
93 | ]
94 | }
95 |
--------------------------------------------------------------------------------
/AUTHORS.md:
--------------------------------------------------------------------------------
1 | # Authors
2 |
3 | #### Ordered by first contribution.
4 |
5 | - Romain Beauxis (toots@rastageeks.org)
6 | - Tobias Koppers (tobias.koppers@googlemail.com)
7 | - Janus (ysangkok@gmail.com)
8 | - Rainer Dreyer (rdrey1@gmail.com)
9 | - Tõnis Tiigi (tonistiigi@gmail.com)
10 | - James Halliday (mail@substack.net)
11 | - Michael Williamson (mike@zwobble.org)
12 | - elliottcable (github@elliottcable.name)
13 | - rafael (rvalle@livelens.net)
14 | - Andrew Kelley (superjoe30@gmail.com)
15 | - Andreas Madsen (amwebdk@gmail.com)
16 | - Mike Brevoort (mike.brevoort@pearson.com)
17 | - Brian White (mscdex@mscdex.net)
18 | - Feross Aboukhadijeh (feross@feross.org)
19 | - Ruben Verborgh (ruben@verborgh.org)
20 | - eliang (eliang.cs@gmail.com)
21 | - Jesse Tane (jesse.tane@gmail.com)
22 | - Alfonso Boza (alfonso@cloud.com)
23 | - Mathias Buus (mathiasbuus@gmail.com)
24 | - Devon Govett (devongovett@gmail.com)
25 | - Daniel Cousens (github@dcousens.com)
26 | - Joseph Dykstra (josephdykstra@gmail.com)
27 | - Parsha Pourkhomami (parshap+git@gmail.com)
28 | - Damjan Košir (damjan.kosir@gmail.com)
29 | - daverayment (dave.rayment@gmail.com)
30 | - kawanet (u-suke@kawa.net)
31 | - Linus Unnebäck (linus@folkdatorn.se)
32 | - Nolan Lawson (nolan.lawson@gmail.com)
33 | - Calvin Metcalf (calvin.metcalf@gmail.com)
34 | - Koki Takahashi (hakatasiloving@gmail.com)
35 | - Guy Bedford (guybedford@gmail.com)
36 | - Jan Schär (jscissr@gmail.com)
37 | - RaulTsc (tomescu.raul@gmail.com)
38 | - Matthieu Monsch (monsch@alum.mit.edu)
39 | - Dan Ehrenberg (littledan@chromium.org)
40 | - Kirill Fomichev (fanatid@ya.ru)
41 | - Yusuke Kawasaki (u-suke@kawa.net)
42 | - DC (dcposch@dcpos.ch)
43 | - John-David Dalton (john.david.dalton@gmail.com)
44 | - adventure-yunfei (adventure030@gmail.com)
45 | - Emil Bay (github@tixz.dk)
46 | - Sam Sudar (sudar.sam@gmail.com)
47 | - Volker Mische (volker.mische@gmail.com)
48 | - David Walton (support@geekstocks.com)
49 | - Сковорода Никита Андреевич (chalkerx@gmail.com)
50 | - greenkeeper[bot] (greenkeeper[bot]@users.noreply.github.com)
51 | - ukstv (sergey.ukustov@machinomy.com)
52 | - Renée Kooi (renee@kooi.me)
53 | - ranbochen (ranbochen@qq.com)
54 | - Vladimir Borovik (bobahbdb@gmail.com)
55 | - greenkeeper[bot] (23040076+greenkeeper[bot]@users.noreply.github.com)
56 | - kumavis (aaron@kumavis.me)
57 | - Sergey Ukustov (sergey.ukustov@machinomy.com)
58 | - Fei Liu (liu.feiwood@gmail.com)
59 | - Blaine Bublitz (blaine.bublitz@gmail.com)
60 | - clement (clement@seald.io)
61 | - Koushik Dutta (koushd@gmail.com)
62 | - Jordan Harband (ljharb@gmail.com)
63 | - Niklas Mischkulnig (mischnic@users.noreply.github.com)
64 | - Nikolai Vavilov (vvnicholas@gmail.com)
65 | - Fedor Nezhivoi (gyzerok@users.noreply.github.com)
66 | - shuse2 (shus.toda@gmail.com)
67 | - Peter Newman (peternewman@users.noreply.github.com)
68 | - mathmakgakpak (44949126+mathmakgakpak@users.noreply.github.com)
69 | - jkkang (jkkang@smartauth.kr)
70 | - Deklan Webster (deklanw@gmail.com)
71 | - Martin Heidegger (martin.heidegger@gmail.com)
72 | - junderw (junderwood@bitcoinbank.co.jp)
73 |
74 | #### Generated by bin/update-authors.sh.
75 |
--------------------------------------------------------------------------------
/test/from-string.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('detect utf16 surrogate pairs', function (t) {
5 | const text = '\uD83D\uDE38' + '\uD83D\uDCAD' + '\uD83D\uDC4D'
6 | const buf = new B(text)
7 | t.equal(text, buf.toString())
8 | t.end()
9 | })
10 |
11 | test('detect utf16 surrogate pairs over U+20000 until U+10FFFF', function (t) {
12 | const text = '\uD842\uDFB7' + '\uD93D\uDCAD' + '\uDBFF\uDFFF'
13 | const buf = new B(text)
14 | t.equal(text, buf.toString())
15 | t.end()
16 | })
17 |
18 | test('replace orphaned utf16 surrogate lead code point', function (t) {
19 | const text = '\uD83D\uDE38' + '\uD83D' + '\uD83D\uDC4D'
20 | const buf = new B(text)
21 | t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0xef, 0xbf, 0xbd, 0xf0, 0x9f, 0x91, 0x8d]))
22 | t.end()
23 | })
24 |
25 | test('replace orphaned utf16 surrogate trail code point', function (t) {
26 | const text = '\uD83D\uDE38' + '\uDCAD' + '\uD83D\uDC4D'
27 | const buf = new B(text)
28 | t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0xef, 0xbf, 0xbd, 0xf0, 0x9f, 0x91, 0x8d]))
29 | t.end()
30 | })
31 |
32 | test('do not write partial utf16 code units', function (t) {
33 | const f = new B([0, 0, 0, 0, 0])
34 | t.equal(f.length, 5)
35 | const size = f.write('あいうえお', 'utf16le')
36 | t.equal(size, 4)
37 | t.deepEqual(f, new B([0x42, 0x30, 0x44, 0x30, 0x00]))
38 | t.end()
39 | })
40 |
41 | test('handle partial utf16 code points when encoding to utf8 the way node does', function (t) {
42 | const text = '\uD83D\uDE38' + '\uD83D\uDC4D'
43 |
44 | let buf = new B(8)
45 | buf.fill(0)
46 | buf.write(text)
47 | t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0xf0, 0x9f, 0x91, 0x8d]))
48 |
49 | buf = new B(7)
50 | buf.fill(0)
51 | buf.write(text)
52 | t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0x00, 0x00, 0x00]))
53 |
54 | buf = new B(6)
55 | buf.fill(0)
56 | buf.write(text)
57 | t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0x00, 0x00]))
58 |
59 | buf = new B(5)
60 | buf.fill(0)
61 | buf.write(text)
62 | t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8, 0x00]))
63 |
64 | buf = new B(4)
65 | buf.fill(0)
66 | buf.write(text)
67 | t.deepEqual(buf, new B([0xf0, 0x9f, 0x98, 0xb8]))
68 |
69 | buf = new B(3)
70 | buf.fill(0)
71 | buf.write(text)
72 | t.deepEqual(buf, new B([0x00, 0x00, 0x00]))
73 |
74 | buf = new B(2)
75 | buf.fill(0)
76 | buf.write(text)
77 | t.deepEqual(buf, new B([0x00, 0x00]))
78 |
79 | buf = new B(1)
80 | buf.fill(0)
81 | buf.write(text)
82 | t.deepEqual(buf, new B([0x00]))
83 |
84 | t.end()
85 | })
86 |
87 | test('handle invalid utf16 code points when encoding to utf8 the way node does', function (t) {
88 | const text = 'a' + '\uDE38\uD83D' + 'b'
89 |
90 | let buf = new B(8)
91 | buf.fill(0)
92 | buf.write(text)
93 | t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0x62]))
94 |
95 | buf = new B(7)
96 | buf.fill(0)
97 | buf.write(text)
98 | t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd]))
99 |
100 | buf = new B(6)
101 | buf.fill(0)
102 | buf.write(text)
103 | t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0x00, 0x00]))
104 |
105 | buf = new B(5)
106 | buf.fill(0)
107 | buf.write(text)
108 | t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd, 0x00]))
109 |
110 | buf = new B(4)
111 | buf.fill(0)
112 | buf.write(text)
113 | t.deepEqual(buf, new B([0x61, 0xef, 0xbf, 0xbd]))
114 |
115 | buf = new B(3)
116 | buf.fill(0)
117 | buf.write(text)
118 | t.deepEqual(buf, new B([0x61, 0x00, 0x00]))
119 |
120 | buf = new B(2)
121 | buf.fill(0)
122 | buf.write(text)
123 | t.deepEqual(buf, new B([0x61, 0x00]))
124 |
125 | buf = new B(1)
126 | buf.fill(0)
127 | buf.write(text)
128 | t.deepEqual(buf, new B([0x61]))
129 |
130 | t.end()
131 | })
132 |
--------------------------------------------------------------------------------
/test/write.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 | const isnan = require('is-nan')
4 |
5 | test('buffer.write string should get parsed as number', function (t) {
6 | const b = new B(64)
7 | b.writeUInt16LE('1003', 0)
8 | t.equal(b.readUInt16LE(0), 1003)
9 | t.end()
10 | })
11 |
12 | test('buffer.writeUInt8 a fractional number will get Math.floored', function (t) {
13 | // Some extra work is necessary to make this test pass with the Object implementation
14 |
15 | const b = new B(1)
16 | b.writeInt8(5.5, 0)
17 | t.equal(b[0], 5)
18 | t.end()
19 | })
20 |
21 | test('writeUint8 with a negative number throws', function (t) {
22 | const buf = new B(1)
23 |
24 | t.throws(function () {
25 | buf.writeUInt8(-3, 0)
26 | })
27 |
28 | t.end()
29 | })
30 |
31 | test('hex of write{Uint,Int}{8,16,32}{LE,BE}', function (t) {
32 | t.plan(2 * ((2 * 2 * 2) + 2))
33 | const hex = [
34 | '03', '0300', '0003', '03000000', '00000003',
35 | 'fd', 'fdff', 'fffd', 'fdffffff', 'fffffffd'
36 | ]
37 | const reads = [3, 3, 3, 3, 3, -3, -3, -3, -3, -3]
38 | const xs = ['UInt', 'Int']
39 | const ys = [8, 16, 32]
40 | for (let i = 0; i < xs.length; i++) {
41 | const x = xs[i]
42 | for (let j = 0; j < ys.length; j++) {
43 | const y = ys[j]
44 | const endianesses = (y === 8) ? [''] : ['LE', 'BE']
45 | for (let k = 0; k < endianesses.length; k++) {
46 | const z = endianesses[k]
47 |
48 | const v1 = new B(y / 8)
49 | const writefn = 'write' + x + y + z
50 | const val = (x === 'Int') ? -3 : 3
51 | v1[writefn](val, 0)
52 | t.equal(
53 | v1.toString('hex'),
54 | hex.shift()
55 | )
56 | const readfn = 'read' + x + y + z
57 | t.equal(
58 | v1[readfn](0),
59 | reads.shift()
60 | )
61 | }
62 | }
63 | }
64 | t.end()
65 | })
66 |
67 | test('hex of write{Uint,Int}{8,16,32}{LE,BE} with overflow', function (t) {
68 | t.plan(3 * ((2 * 2 * 2) + 2))
69 | const hex = [
70 | '', '03', '00', '030000', '000000',
71 | '', 'fd', 'ff', 'fdffff', 'ffffff'
72 | ]
73 | const reads = [
74 | undefined, 3, 0, NaN, 0,
75 | undefined, 253, -256, 16777213, -256
76 | ]
77 | const xs = ['UInt', 'Int']
78 | const ys = [8, 16, 32]
79 | for (let i = 0; i < xs.length; i++) {
80 | const x = xs[i]
81 | for (let j = 0; j < ys.length; j++) {
82 | const y = ys[j]
83 | const endianesses = (y === 8) ? [''] : ['LE', 'BE']
84 | for (let k = 0; k < endianesses.length; k++) {
85 | const z = endianesses[k]
86 |
87 | const v1 = new B((y / 8) - 1)
88 | const next = new B(4)
89 | next.writeUInt32BE(0, 0)
90 | const writefn = 'write' + x + y + z
91 | const val = (x === 'Int') ? -3 : 3
92 | v1[writefn](val, 0, true)
93 | t.equal(
94 | v1.toString('hex'),
95 | hex.shift()
96 | )
97 | // check that nothing leaked to next buffer.
98 | t.equal(next.readUInt32BE(0), 0)
99 | // check that no bytes are read from next buffer.
100 | next.writeInt32BE(~0, 0)
101 | const readfn = 'read' + x + y + z
102 | const r = reads.shift()
103 | if (isnan(r)) t.pass('equal')
104 | else t.equal(v1[readfn](0, true), r)
105 | }
106 | }
107 | }
108 | t.end()
109 | })
110 | test('large values do not improperly roll over (ref #80)', function (t) {
111 | const nums = [-25589992, -633756690, -898146932]
112 | const out = new B(12)
113 | out.fill(0)
114 | out.writeInt32BE(nums[0], 0)
115 | let newNum = out.readInt32BE(0)
116 | t.equal(nums[0], newNum)
117 | out.writeInt32BE(nums[1], 4)
118 | newNum = out.readInt32BE(4)
119 | t.equal(nums[1], newNum)
120 | out.writeInt32BE(nums[2], 8)
121 | newNum = out.readInt32BE(8)
122 | t.equal(nums[2], newNum)
123 | t.end()
124 | })
125 |
--------------------------------------------------------------------------------
/test/methods.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('buffer.toJSON', function (t) {
5 | const data = [1, 2, 3, 4]
6 | t.deepEqual(
7 | new B(data).toJSON(),
8 | { type: 'Buffer', data: [1, 2, 3, 4] }
9 | )
10 | t.end()
11 | })
12 |
13 | test('buffer.copy', function (t) {
14 | // copied from nodejs.org example
15 | const buf1 = new B(26)
16 | const buf2 = new B(26)
17 |
18 | for (let i = 0; i < 26; i++) {
19 | buf1[i] = i + 97 // 97 is ASCII a
20 | buf2[i] = 33 // ASCII !
21 | }
22 |
23 | buf1.copy(buf2, 8, 16, 20)
24 |
25 | t.equal(
26 | buf2.toString('ascii', 0, 25),
27 | '!!!!!!!!qrst!!!!!!!!!!!!!'
28 | )
29 | t.end()
30 | })
31 |
32 | test('test offset returns are correct', function (t) {
33 | const b = new B(16)
34 | t.equal(4, b.writeUInt32LE(0, 0))
35 | t.equal(6, b.writeUInt16LE(0, 4))
36 | t.equal(7, b.writeUInt8(0, 6))
37 | t.equal(8, b.writeInt8(0, 7))
38 | t.equal(16, b.writeDoubleLE(0, 8))
39 | t.end()
40 | })
41 |
42 | test('concat() a varying number of buffers', function (t) {
43 | const zero = []
44 | const one = [new B('asdf')]
45 | const long = []
46 | for (let i = 0; i < 10; i++) {
47 | long.push(new B('asdf'))
48 | }
49 |
50 | const flatZero = B.concat(zero)
51 | const flatOne = B.concat(one)
52 | const flatLong = B.concat(long)
53 | const flatLongLen = B.concat(long, 40)
54 |
55 | t.equal(flatZero.length, 0)
56 | t.equal(flatOne.toString(), 'asdf')
57 | t.deepEqual(flatOne, one[0])
58 | t.equal(flatLong.toString(), (new Array(10 + 1).join('asdf')))
59 | t.equal(flatLongLen.toString(), (new Array(10 + 1).join('asdf')))
60 | t.end()
61 | })
62 |
63 | test('concat() works on Uint8Array instances', function (t) {
64 | const result = B.concat([new Uint8Array([1, 2]), new Uint8Array([3, 4])])
65 | const expected = B.from([1, 2, 3, 4])
66 | t.deepEqual(result, expected)
67 | t.end()
68 | })
69 |
70 | test('concat() works on Uint8Array instances for smaller provided totalLength', function (t) {
71 | const result = B.concat([new Uint8Array([1, 2]), new Uint8Array([3, 4])], 3)
72 | const expected = B.from([1, 2, 3])
73 | t.deepEqual(result, expected)
74 | t.end()
75 | })
76 |
77 | test('fill', function (t) {
78 | const b = new B(10)
79 | b.fill(2)
80 | t.equal(b.toString('hex'), '02020202020202020202')
81 | t.end()
82 | })
83 |
84 | test('fill (string)', function (t) {
85 | const b = new B(10)
86 | b.fill('abc')
87 | t.equal(b.toString(), 'abcabcabca')
88 | b.fill('է')
89 | t.equal(b.toString(), 'էէէէէ')
90 | t.end()
91 | })
92 |
93 | test('copy() empty buffer with sourceEnd=0', function (t) {
94 | const source = new B([42])
95 | const destination = new B([43])
96 | source.copy(destination, 0, 0, 0)
97 | t.equal(destination.readUInt8(0), 43)
98 | t.end()
99 | })
100 |
101 | test('copy() after slice()', function (t) {
102 | const source = new B(200)
103 | const dest = new B(200)
104 | const expected = new B(200)
105 | for (let i = 0; i < 200; i++) {
106 | source[i] = i
107 | dest[i] = 0
108 | }
109 |
110 | source.slice(2).copy(dest)
111 | source.copy(expected, 0, 2)
112 | t.deepEqual(dest, expected)
113 | t.end()
114 | })
115 |
116 | test('copy() ascending', function (t) {
117 | const b = new B('abcdefghij')
118 | b.copy(b, 0, 3, 10)
119 | t.equal(b.toString(), 'defghijhij')
120 | t.end()
121 | })
122 |
123 | test('copy() descending', function (t) {
124 | const b = new B('abcdefghij')
125 | b.copy(b, 3, 0, 7)
126 | t.equal(b.toString(), 'abcabcdefg')
127 | t.end()
128 | })
129 |
130 | test('buffer.slice sets indexes', function (t) {
131 | t.equal((new B('hallo')).slice(0, 5).toString(), 'hallo')
132 | t.end()
133 | })
134 |
135 | test('buffer.slice out of range', function (t) {
136 | t.plan(2)
137 | t.equal((new B('hallo')).slice(0, 10).toString(), 'hallo')
138 | t.equal((new B('hallo')).slice(10, 2).toString(), '')
139 | t.end()
140 | })
141 |
--------------------------------------------------------------------------------
/bin/download-node-tests.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const concat = require('concat-stream')
4 | const cp = require('child_process')
5 | const fs = require('fs')
6 | const hyperquest = require('hyperquest')
7 | const path = require('path')
8 | const split = require('split')
9 | const through = require('through2')
10 |
11 | const url = 'https://api.github.com/repos/nodejs/node/contents'
12 | const dirs = [
13 | '/test/parallel',
14 | '/test/pummel'
15 | ]
16 |
17 | cp.execSync('rm -rf node/test-*.js', { cwd: path.join(__dirname, '../test') })
18 |
19 | const httpOpts = {
20 | headers: {
21 | 'User-Agent': null
22 | // auth if github rate-limits you...
23 | // 'Authorization': 'Basic ' + Buffer('username:password').toString('base64'),
24 | }
25 | }
26 |
27 | dirs.forEach(function (dir) {
28 | const req = hyperquest(url + dir, httpOpts)
29 | req.pipe(concat(function (data) {
30 | if (req.response.statusCode !== 200) {
31 | throw new Error(url + dir + ': ' + data.toString())
32 | }
33 | downloadBufferTests(dir, JSON.parse(data))
34 | }))
35 | })
36 |
37 | function downloadBufferTests (dir, files) {
38 | files.forEach(function (file) {
39 | if (!/test-buffer.*/.test(file.name)) return
40 |
41 | const skipFileNames = [
42 | // Only applies to node. Calls into C++ and needs to ensure the prototype can't
43 | // be faked, or else there will be a segfault.
44 | 'test-buffer-fakes.js',
45 | // Tests SharedArrayBuffer support, which is obscure and now temporarily
46 | // disabled in all browsers due to the Spectre/Meltdown security issue.
47 | 'test-buffer-sharedarraybuffer.js',
48 | // References Node.js internals, irrelevant to browser implementation
49 | 'test-buffer-bindingobj-no-zerofill.js',
50 | // Destructive test, modifies buffer.INSPECT_MAX_BYTES and causes later tests
51 | // to fail.
52 | 'test-buffer-inspect.js'
53 | ]
54 |
55 | // Skip test files with these names
56 | if (skipFileNames.includes(file.name)) return
57 |
58 | console.log(file.download_url)
59 |
60 | const out = path.join(__dirname, '../test/node', file.name)
61 | hyperquest(file.download_url, httpOpts)
62 | .pipe(split())
63 | .pipe(testfixer(file.name))
64 | .pipe(fs.createWriteStream(out))
65 | .on('finish', function () {
66 | console.log('wrote ' + file.name)
67 | })
68 | })
69 | }
70 |
71 | function testfixer (filename) {
72 | let firstline = true
73 |
74 | return through(function (line, enc, cb) {
75 | line = line.toString()
76 |
77 | if (firstline) {
78 | // require buffer explicitly
79 | const preamble = 'var Buffer = require(\'../../\').Buffer;'
80 | if (/use strict/.test(line)) line += '\n' + preamble
81 | else line += preamble + '\n' + line
82 | firstline = false
83 | }
84 |
85 | // make `require('../common')` work
86 | line = line.replace(/require\('\.\.\/common'\);/g, 'require(\'./common\');')
87 |
88 | // require browser buffer
89 | line = line.replace(/(.*)require\('buffer'\)(.*)/g, '$1require(\'../../\')$2')
90 |
91 | // comment out console logs
92 | line = line.replace(/(.*console\..*)/g, '// $1')
93 |
94 | // we can't reliably test typed array max-sizes in the browser
95 | if (filename === 'test-buffer-big.js') {
96 | line = line.replace(/(.*new Int8Array.*RangeError.*)/, '// $1')
97 | line = line.replace(/(.*new ArrayBuffer.*RangeError.*)/, '// $1')
98 | line = line.replace(/(.*new Float64Array.*RangeError.*)/, '// $1')
99 | }
100 |
101 | // https://github.com/nodejs/node/blob/v0.12/test/parallel/test-buffer.js#L1138
102 | // unfortunately we can't run this because crypto-browserify doesn't work in old
103 | // versions of ie
104 | if (filename === 'test-buffer.js') {
105 | line = line.replace(/^(\s*)(var crypto = require.*)/, '$1// $2')
106 | line = line.replace(/(crypto.createHash.*\))/, '1 /*$1*/')
107 | }
108 |
109 | cb(null, line + '\n')
110 | })
111 | }
112 |
--------------------------------------------------------------------------------
/test/typing.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const Buffer = require('../').Buffer
4 | const test = require('tape')
5 | const vm = require('vm')
6 |
7 | // Get a Uint8Array and Buffer constructor from another context.
8 | const code = `
9 | 'use strict'
10 | function Buffer (...args) {
11 | const buf = new Uint8Array(...args)
12 | Object.setPrototypeOf(buf, Buffer.prototype)
13 | return buf
14 | }
15 | Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype)
16 | Object.setPrototypeOf(Buffer, Uint8Array)
17 | Buffer.prototype._isBuffer = true
18 | exports.Uint8Array = Uint8Array
19 | exports.Buffer = Buffer
20 | `
21 |
22 | const context = {}
23 |
24 | // Should work in browserify.
25 | vm.runInNewContext(code, { exports: context })
26 |
27 | const arrays = [context.Uint8Array, context.Buffer]
28 |
29 | // Extracted from the index.js code for testing purposes.
30 | function isInstance (obj, type) {
31 | return (obj instanceof type) ||
32 | (obj != null &&
33 | obj.constructor != null &&
34 | obj.constructor.name != null &&
35 | obj.constructor.name === type.name) ||
36 | (type === Uint8Array && Buffer.isBuffer(obj))
37 | }
38 |
39 | test('Uint8Arrays and Buffers from other contexts', (t) => {
40 | // Our buffer is considered a view.
41 | t.ok(ArrayBuffer.isView(Buffer.alloc(0)))
42 |
43 | for (const ForeignArray of arrays) {
44 | const buf = new ForeignArray(1)
45 |
46 | buf[0] = 1
47 |
48 | // Prove that ArrayBuffer.isView and isInstance
49 | // return true for objects from other contexts.
50 | t.ok(!(buf instanceof Object))
51 | t.ok(!(buf instanceof Uint8Array))
52 | t.ok(!(buf instanceof Buffer))
53 | t.ok(ArrayBuffer.isView(buf))
54 |
55 | // Now returns true even for Buffers from other contexts:
56 | t.ok(isInstance(buf, Uint8Array))
57 |
58 | if (ForeignArray === context.Uint8Array) {
59 | t.ok(!Buffer.isBuffer(buf))
60 | } else {
61 | t.ok(Buffer.isBuffer(buf))
62 | }
63 |
64 | // They even behave the same!
65 | const copy = new Uint8Array(buf)
66 |
67 | t.ok(copy instanceof Object)
68 | t.ok(copy instanceof Uint8Array)
69 | t.ok(ArrayBuffer.isView(copy))
70 | t.equal(copy[0], 1)
71 | }
72 |
73 | t.end()
74 | })
75 |
76 | test('should instantiate from foreign arrays', (t) => {
77 | for (const ForeignArray of arrays) {
78 | const arr = new ForeignArray(2)
79 |
80 | arr[0] = 1
81 | arr[1] = 2
82 |
83 | const buf = Buffer.from(arr)
84 |
85 | t.equal(buf.toString('hex'), '0102')
86 | }
87 |
88 | t.end()
89 | })
90 |
91 | test('should do comparisons with foreign arrays', (t) => {
92 | const a = Buffer.from([1, 2, 3])
93 | const b = new context.Uint8Array(a)
94 | const c = new context.Buffer(a)
95 |
96 | t.equal(Buffer.byteLength(a), 3)
97 | t.equal(Buffer.byteLength(b), 3)
98 | t.equal(Buffer.byteLength(c), 3)
99 | t.equal(b[0], 1)
100 | t.equal(c[0], 1)
101 |
102 | t.ok(a.equals(b))
103 | t.ok(a.equals(c))
104 | t.ok(a.compare(b) === 0)
105 | t.ok(a.compare(c) === 0)
106 | t.ok(Buffer.compare(a, b) === 0)
107 | t.ok(Buffer.compare(a, c) === 0)
108 | t.ok(Buffer.compare(b, c) === 0)
109 | t.ok(Buffer.compare(c, b) === 0)
110 |
111 | a[0] = 0
112 |
113 | t.ok(!a.equals(b))
114 | t.ok(!a.equals(c))
115 | t.ok(a.compare(b) < 0)
116 | t.ok(a.compare(c) < 0)
117 | t.ok(Buffer.compare(a, b) < 0)
118 | t.ok(Buffer.compare(a, c) < 0)
119 |
120 | b[0] = 0
121 |
122 | t.ok(Buffer.compare(b, c) < 0)
123 | t.ok(Buffer.compare(c, b) > 0)
124 |
125 | t.end()
126 | })
127 |
128 | test('should fill with foreign arrays', (t) => {
129 | for (const ForeignArray of arrays) {
130 | const buf = Buffer.alloc(4)
131 | const arr = new ForeignArray(2)
132 |
133 | arr[0] = 1
134 | arr[1] = 2
135 |
136 | buf.fill(arr)
137 |
138 | t.equal(buf.toString('hex'), '01020102')
139 | }
140 |
141 | t.end()
142 | })
143 |
144 | test('should do concatenation with foreign arrays', (t) => {
145 | for (const ForeignArray of arrays) {
146 | const a = new ForeignArray(2)
147 |
148 | a[0] = 1
149 | a[1] = 2
150 |
151 | const b = new ForeignArray(a)
152 |
153 | {
154 | const buf = Buffer.concat([a, b])
155 | t.equal(buf.toString('hex'), '01020102')
156 | }
157 |
158 | {
159 | const buf = Buffer.concat([a, b], 3)
160 | t.equal(buf.toString('hex'), '010201')
161 | }
162 | }
163 |
164 | t.end()
165 | })
166 |
167 | test('should copy on to foreign arrays', (t) => {
168 | for (const ForeignArray of arrays) {
169 | const a = Buffer.from([1, 2])
170 | const b = new ForeignArray(2)
171 |
172 | a.copy(b)
173 |
174 | t.equal(b[0], 1)
175 | t.equal(b[1], 2)
176 | }
177 |
178 | t.end()
179 | })
180 |
--------------------------------------------------------------------------------
/test/node/test-buffer-arraybuffer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const assert = require('assert');
6 |
7 | const LENGTH = 16;
8 |
9 | const ab = new ArrayBuffer(LENGTH);
10 | const dv = new DataView(ab);
11 | const ui = new Uint8Array(ab);
12 | const buf = Buffer.from(ab);
13 |
14 |
15 | assert.ok(buf instanceof Buffer);
16 | assert.strictEqual(buf.parent, buf.buffer);
17 | assert.strictEqual(buf.buffer, ab);
18 | assert.strictEqual(buf.length, ab.byteLength);
19 |
20 |
21 | buf.fill(0xC);
22 | for (let i = 0; i < LENGTH; i++) {
23 | assert.strictEqual(ui[i], 0xC);
24 | ui[i] = 0xF;
25 | assert.strictEqual(buf[i], 0xF);
26 | }
27 |
28 | buf.writeUInt32LE(0xF00, 0);
29 | buf.writeUInt32BE(0xB47, 4);
30 | buf.writeDoubleLE(3.1415, 8);
31 |
32 | assert.strictEqual(dv.getUint32(0, true), 0xF00);
33 | assert.strictEqual(dv.getUint32(4), 0xB47);
34 | assert.strictEqual(dv.getFloat64(8, true), 3.1415);
35 |
36 |
37 | // Now test protecting users from doing stupid things
38 |
39 | assert.throws(function() {
40 | function AB() { }
41 | Object.setPrototypeOf(AB, ArrayBuffer);
42 | Object.setPrototypeOf(AB.prototype, ArrayBuffer.prototype);
43 | Buffer.from(new AB());
44 | }, TypeError);
45 |
46 | // write{Double,Float}{LE,BE} with noAssert should not crash, cf. #3766
47 | const b = Buffer.allocUnsafe(1);
48 | b.writeFloatLE(11.11, 0, true);
49 | b.writeFloatBE(11.11, 0, true);
50 | b.writeDoubleLE(11.11, 0, true);
51 | b.writeDoubleBE(11.11, 0, true);
52 |
53 | // Test the byteOffset and length arguments
54 | {
55 | const ab = new Uint8Array(5);
56 | ab[0] = 1;
57 | ab[1] = 2;
58 | ab[2] = 3;
59 | ab[3] = 4;
60 | ab[4] = 5;
61 | const buf = Buffer.from(ab.buffer, 1, 3);
62 | assert.strictEqual(buf.length, 3);
63 | assert.strictEqual(buf[0], 2);
64 | assert.strictEqual(buf[1], 3);
65 | assert.strictEqual(buf[2], 4);
66 | buf[0] = 9;
67 | assert.strictEqual(ab[1], 9);
68 |
69 | common.expectsError(() => Buffer.from(ab.buffer, 6), {
70 | code: 'ERR_BUFFER_OUT_OF_BOUNDS',
71 | type: RangeError,
72 | message: '"offset" is outside of buffer bounds'
73 | });
74 | common.expectsError(() => Buffer.from(ab.buffer, 3, 6), {
75 | code: 'ERR_BUFFER_OUT_OF_BOUNDS',
76 | type: RangeError,
77 | message: '"length" is outside of buffer bounds'
78 | });
79 | }
80 |
81 | // Test the deprecated Buffer() version also
82 | {
83 | const ab = new Uint8Array(5);
84 | ab[0] = 1;
85 | ab[1] = 2;
86 | ab[2] = 3;
87 | ab[3] = 4;
88 | ab[4] = 5;
89 | const buf = Buffer(ab.buffer, 1, 3);
90 | assert.strictEqual(buf.length, 3);
91 | assert.strictEqual(buf[0], 2);
92 | assert.strictEqual(buf[1], 3);
93 | assert.strictEqual(buf[2], 4);
94 | buf[0] = 9;
95 | assert.strictEqual(ab[1], 9);
96 |
97 | common.expectsError(() => Buffer(ab.buffer, 6), {
98 | code: 'ERR_BUFFER_OUT_OF_BOUNDS',
99 | type: RangeError,
100 | message: '"offset" is outside of buffer bounds'
101 | });
102 | common.expectsError(() => Buffer(ab.buffer, 3, 6), {
103 | code: 'ERR_BUFFER_OUT_OF_BOUNDS',
104 | type: RangeError,
105 | message: '"length" is outside of buffer bounds'
106 | });
107 | }
108 |
109 | {
110 | // If byteOffset is not numeric, it defaults to 0.
111 | const ab = new ArrayBuffer(10);
112 | const expected = Buffer.from(ab, 0);
113 | assert.deepStrictEqual(Buffer.from(ab, 'fhqwhgads'), expected);
114 | assert.deepStrictEqual(Buffer.from(ab, NaN), expected);
115 | assert.deepStrictEqual(Buffer.from(ab, {}), expected);
116 | assert.deepStrictEqual(Buffer.from(ab, []), expected);
117 |
118 | // If byteOffset can be converted to a number, it will be.
119 | assert.deepStrictEqual(Buffer.from(ab, [1]), Buffer.from(ab, 1));
120 |
121 | // If byteOffset is Infinity, throw.
122 | common.expectsError(() => {
123 | Buffer.from(ab, Infinity);
124 | }, {
125 | code: 'ERR_BUFFER_OUT_OF_BOUNDS',
126 | type: RangeError,
127 | message: '"offset" is outside of buffer bounds'
128 | });
129 | }
130 |
131 | {
132 | // If length is not numeric, it defaults to 0.
133 | const ab = new ArrayBuffer(10);
134 | const expected = Buffer.from(ab, 0, 0);
135 | assert.deepStrictEqual(Buffer.from(ab, 0, 'fhqwhgads'), expected);
136 | assert.deepStrictEqual(Buffer.from(ab, 0, NaN), expected);
137 | assert.deepStrictEqual(Buffer.from(ab, 0, {}), expected);
138 | assert.deepStrictEqual(Buffer.from(ab, 0, []), expected);
139 |
140 | // If length can be converted to a number, it will be.
141 | assert.deepStrictEqual(Buffer.from(ab, 0, [1]), Buffer.from(ab, 0, 1));
142 |
143 | //If length is Infinity, throw.
144 | common.expectsError(() => {
145 | Buffer.from(ab, 0, Infinity);
146 | }, {
147 | code: 'ERR_BUFFER_OUT_OF_BOUNDS',
148 | type: RangeError,
149 | message: '"length" is outside of buffer bounds'
150 | });
151 | }
152 |
153 |
--------------------------------------------------------------------------------
/test/node/test-buffer-bytelength.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | const common = require('./common');
5 | const assert = require('assert');
6 | const SlowBuffer = require('../../').SlowBuffer;
7 | const vm = require('vm');
8 |
9 | [
10 | [32, 'latin1'],
11 | [NaN, 'utf8'],
12 | [{}, 'latin1'],
13 | []
14 | ].forEach((args) => {
15 | common.expectsError(
16 | () => Buffer.byteLength(...args),
17 | {
18 | code: 'ERR_INVALID_ARG_TYPE',
19 | type: TypeError,
20 | message: 'The "string" argument must be one of type string, ' +
21 | `Buffer, or ArrayBuffer. Received type ${typeof args[0]}`
22 | }
23 | );
24 | });
25 |
26 | assert.strictEqual(Buffer.byteLength('', undefined, true), -1);
27 |
28 | assert(ArrayBuffer.isView(new Buffer(10)));
29 | assert(ArrayBuffer.isView(new SlowBuffer(10)));
30 | assert(ArrayBuffer.isView(Buffer.alloc(10)));
31 | assert(ArrayBuffer.isView(Buffer.allocUnsafe(10)));
32 | assert(ArrayBuffer.isView(Buffer.allocUnsafeSlow(10)));
33 | assert(ArrayBuffer.isView(Buffer.from('')));
34 |
35 | // buffer
36 | const incomplete = Buffer.from([0xe4, 0xb8, 0xad, 0xe6, 0x96]);
37 | assert.strictEqual(Buffer.byteLength(incomplete), 5);
38 | const ascii = Buffer.from('abc');
39 | assert.strictEqual(Buffer.byteLength(ascii), 3);
40 |
41 | // ArrayBuffer
42 | const buffer = new ArrayBuffer(8);
43 | assert.strictEqual(Buffer.byteLength(buffer), 8);
44 |
45 | // TypedArray
46 | const int8 = new Int8Array(8);
47 | assert.strictEqual(Buffer.byteLength(int8), 8);
48 | const uint8 = new Uint8Array(8);
49 | assert.strictEqual(Buffer.byteLength(uint8), 8);
50 | const uintc8 = new Uint8ClampedArray(2);
51 | assert.strictEqual(Buffer.byteLength(uintc8), 2);
52 | const int16 = new Int16Array(8);
53 | assert.strictEqual(Buffer.byteLength(int16), 16);
54 | const uint16 = new Uint16Array(8);
55 | assert.strictEqual(Buffer.byteLength(uint16), 16);
56 | const int32 = new Int32Array(8);
57 | assert.strictEqual(Buffer.byteLength(int32), 32);
58 | const uint32 = new Uint32Array(8);
59 | assert.strictEqual(Buffer.byteLength(uint32), 32);
60 | const float32 = new Float32Array(8);
61 | assert.strictEqual(Buffer.byteLength(float32), 32);
62 | const float64 = new Float64Array(8);
63 | assert.strictEqual(Buffer.byteLength(float64), 64);
64 |
65 | // DataView
66 | const dv = new DataView(new ArrayBuffer(2));
67 | assert.strictEqual(Buffer.byteLength(dv), 2);
68 |
69 | // special case: zero length string
70 | assert.strictEqual(Buffer.byteLength('', 'ascii'), 0);
71 | assert.strictEqual(Buffer.byteLength('', 'HeX'), 0);
72 |
73 | // utf8
74 | assert.strictEqual(Buffer.byteLength('∑éllö wørl∂!', 'utf-8'), 19);
75 | assert.strictEqual(Buffer.byteLength('κλμνξο', 'utf8'), 12);
76 | assert.strictEqual(Buffer.byteLength('挵挶挷挸挹', 'utf-8'), 15);
77 | assert.strictEqual(Buffer.byteLength('𠝹𠱓𠱸', 'UTF8'), 12);
78 | // without an encoding, utf8 should be assumed
79 | assert.strictEqual(Buffer.byteLength('hey there'), 9);
80 | assert.strictEqual(Buffer.byteLength('𠱸挶νξ#xx :)'), 17);
81 | assert.strictEqual(Buffer.byteLength('hello world', ''), 11);
82 | // it should also be assumed with unrecognized encoding
83 | assert.strictEqual(Buffer.byteLength('hello world', 'abc'), 11);
84 | assert.strictEqual(Buffer.byteLength('ßœ∑≈', 'unkn0wn enc0ding'), 10);
85 |
86 | // base64
87 | assert.strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ=', 'base64'), 11);
88 | assert.strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ=', 'BASE64'), 11);
89 | assert.strictEqual(Buffer.byteLength('bm9kZS5qcyByb2NrcyE=', 'base64'), 14);
90 | assert.strictEqual(Buffer.byteLength('aGkk', 'base64'), 3);
91 | assert.strictEqual(
92 | Buffer.byteLength('bHNrZGZsa3NqZmtsc2xrZmFqc2RsZmtqcw==', 'base64'), 25
93 | );
94 | // special padding
95 | assert.strictEqual(Buffer.byteLength('aaa=', 'base64'), 2);
96 | assert.strictEqual(Buffer.byteLength('aaaa==', 'base64'), 3);
97 |
98 | assert.strictEqual(Buffer.byteLength('Il était tué'), 14);
99 | assert.strictEqual(Buffer.byteLength('Il était tué', 'utf8'), 14);
100 |
101 | ['ascii', 'latin1', 'binary']
102 | .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
103 | .forEach((encoding) => {
104 | assert.strictEqual(Buffer.byteLength('Il était tué', encoding), 12);
105 | });
106 |
107 | ['ucs2', 'ucs-2', 'utf16le', 'utf-16le']
108 | .reduce((es, e) => es.concat(e, e.toUpperCase()), [])
109 | .forEach((encoding) => {
110 | assert.strictEqual(Buffer.byteLength('Il était tué', encoding), 24);
111 | });
112 |
113 | // Test that ArrayBuffer from a different context is detected correctly
114 | const arrayBuf = vm.runInNewContext('new ArrayBuffer()');
115 | assert.strictEqual(Buffer.byteLength(arrayBuf), 0);
116 |
117 | // Verify that invalid encodings are treated as utf8
118 | for (let i = 1; i < 10; i++) {
119 | const encoding = String(i).repeat(i);
120 |
121 | assert.ok(!Buffer.isEncoding(encoding));
122 | assert.strictEqual(Buffer.byteLength('foo', encoding),
123 | Buffer.byteLength('foo', 'utf8'));
124 | }
125 |
126 |
--------------------------------------------------------------------------------
/test/node/common.js:
--------------------------------------------------------------------------------
1 | // Copyright Joyent, Inc. and other Node contributors.
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a
4 | // copy of this software and associated documentation files (the
5 | // "Software"), to deal in the Software without restriction, including
6 | // without limitation the rights to use, copy, modify, merge, publish,
7 | // distribute, sublicense, and/or sell copies of the Software, and to permit
8 | // persons to whom the Software is furnished to do so, subject to the
9 | // following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included
12 | // in all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 | /* eslint-disable required-modules, crypto-check */
23 | 'use strict';
24 | const assert = require('assert');
25 | const mustCallChecks = [];
26 |
27 | function runCallChecks(exitCode) {
28 | if (exitCode !== 0) return;
29 |
30 | const failed = mustCallChecks.filter(function(context) {
31 | if ('minimum' in context) {
32 | context.messageSegment = `at least ${context.minimum}`;
33 | return context.actual < context.minimum;
34 | } else {
35 | context.messageSegment = `exactly ${context.exact}`;
36 | return context.actual !== context.exact;
37 | }
38 | });
39 |
40 | failed.forEach(function(context) {
41 | console.log('Mismatched %s function calls. Expected %s, actual %d.',
42 | context.name,
43 | context.messageSegment,
44 | context.actual);
45 | console.log(context.stack.split('\n').slice(2).join('\n'));
46 | });
47 |
48 | if (failed.length) process.exit(1);
49 | }
50 |
51 | exports.mustCall = function(fn, exact) {
52 | return _mustCallInner(fn, exact, 'exact');
53 | };
54 |
55 | function _mustCallInner(fn, criteria = 1, field) {
56 | if (process._exiting)
57 | throw new Error('Cannot use common.mustCall*() in process exit handler');
58 | if (typeof fn === 'number') {
59 | criteria = fn;
60 | fn = noop;
61 | } else if (fn === undefined) {
62 | fn = noop;
63 | }
64 |
65 | if (typeof criteria !== 'number')
66 | throw new TypeError(`Invalid ${field} value: ${criteria}`);
67 |
68 | const context = {
69 | [field]: criteria,
70 | actual: 0,
71 | stack: (new Error()).stack,
72 | name: fn.name || ''
73 | };
74 |
75 | // add the exit listener only once to avoid listener leak warnings
76 | if (mustCallChecks.length === 0) process.on('exit', runCallChecks);
77 |
78 | mustCallChecks.push(context);
79 |
80 | return function() {
81 | context.actual++;
82 | return fn.apply(this, arguments);
83 | };
84 | }
85 |
86 | exports.printSkipMessage = function(msg) {}
87 |
88 | // Useful for testing expected internal/error objects
89 | exports.expectsError = function expectsError(fn, settings, exact) {
90 | if (typeof fn !== 'function') {
91 | exact = settings;
92 | settings = fn;
93 | fn = undefined;
94 | }
95 | function innerFn(error) {
96 | if ('type' in settings) {
97 | const type = settings.type;
98 | if (type !== Error && !Error.isPrototypeOf(type)) {
99 | throw new TypeError('`settings.type` must inherit from `Error`');
100 | }
101 | assert(error instanceof type,
102 | `${error.name} is not instance of ${type.name}`);
103 | let typeName = error.constructor.name;
104 | if (typeName === 'NodeError' && type.name !== 'NodeError') {
105 | typeName = Object.getPrototypeOf(error.constructor).name;
106 | }
107 | assert.strictEqual(typeName, type.name);
108 | }
109 | if ('message' in settings) {
110 | const message = settings.message;
111 | if (typeof message === 'string') {
112 | assert.strictEqual(error.message, message);
113 | } else {
114 | assert(message.test(error.message),
115 | `${error.message} does not match ${message}`);
116 | }
117 | }
118 | if ('name' in settings) {
119 | assert.strictEqual(error.name, settings.name);
120 | }
121 | if (error.constructor.name === 'AssertionError') {
122 | ['generatedMessage', 'actual', 'expected', 'operator'].forEach((key) => {
123 | if (key in settings) {
124 | const actual = error[key];
125 | const expected = settings[key];
126 | assert.strictEqual(actual, expected,
127 | `${key}: expected ${expected}, not ${actual}`);
128 | }
129 | });
130 | }
131 | return true;
132 | }
133 | if (fn) {
134 | assert.throws(fn, innerFn);
135 | return;
136 | }
137 | return exports.mustCall(innerFn, exact);
138 | };
139 |
--------------------------------------------------------------------------------
/test/constructor.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('new buffer from array', function (t) {
5 | t.equal(
6 | new B([1, 2, 3]).toString(),
7 | '\u0001\u0002\u0003'
8 | )
9 | t.end()
10 | })
11 |
12 | test('new buffer from array w/ negatives', function (t) {
13 | t.equal(
14 | new B([-1, -2, -3]).toString('hex'),
15 | 'fffefd'
16 | )
17 | t.end()
18 | })
19 |
20 | test('new buffer from array with mixed signed input', function (t) {
21 | t.equal(
22 | new B([-255, 255, -128, 128, 512, -512, 511, -511]).toString('hex'),
23 | '01ff80800000ff01'
24 | )
25 | t.end()
26 | })
27 |
28 | test('new buffer from string', function (t) {
29 | t.equal(
30 | new B('hey', 'utf8').toString(),
31 | 'hey'
32 | )
33 | t.end()
34 | })
35 |
36 | test('new buffer from buffer', function (t) {
37 | const b1 = new B('asdf')
38 | const b2 = new B(b1)
39 | t.equal(b1.toString('hex'), b2.toString('hex'))
40 | t.end()
41 | })
42 |
43 | test('new buffer from ArrayBuffer', function (t) {
44 | if (typeof ArrayBuffer !== 'undefined') {
45 | const arraybuffer = new Uint8Array([0, 1, 2, 3]).buffer
46 | const b = new B(arraybuffer)
47 | t.equal(b.length, 4)
48 | t.equal(b[0], 0)
49 | t.equal(b[1], 1)
50 | t.equal(b[2], 2)
51 | t.equal(b[3], 3)
52 | t.equal(b[4], undefined)
53 | }
54 | t.end()
55 | })
56 |
57 | test('new buffer from ArrayBuffer, shares memory', function (t) {
58 | const u = new Uint8Array([0, 1, 2, 3])
59 | const arraybuffer = u.buffer
60 | const b = new B(arraybuffer)
61 | t.equal(b.length, 4)
62 | t.equal(b[0], 0)
63 | t.equal(b[1], 1)
64 | t.equal(b[2], 2)
65 | t.equal(b[3], 3)
66 | t.equal(b[4], undefined)
67 |
68 | // changing the Uint8Array (and thus the ArrayBuffer), changes the Buffer
69 | u[0] = 10
70 | t.equal(b[0], 10)
71 | u[1] = 11
72 | t.equal(b[1], 11)
73 | u[2] = 12
74 | t.equal(b[2], 12)
75 | u[3] = 13
76 | t.equal(b[3], 13)
77 | t.end()
78 | })
79 |
80 | test('new buffer from Uint8Array', function (t) {
81 | if (typeof Uint8Array !== 'undefined') {
82 | const b1 = new Uint8Array([0, 1, 2, 3])
83 | const b2 = new B(b1)
84 | t.equal(b1.length, b2.length)
85 | t.equal(b1[0], 0)
86 | t.equal(b1[1], 1)
87 | t.equal(b1[2], 2)
88 | t.equal(b1[3], 3)
89 | t.equal(b1[4], undefined)
90 | }
91 | t.end()
92 | })
93 |
94 | test('new buffer from Uint16Array', function (t) {
95 | if (typeof Uint16Array !== 'undefined') {
96 | const b1 = new Uint16Array([0, 1, 2, 3])
97 | const b2 = new B(b1)
98 | t.equal(b1.length, b2.length)
99 | t.equal(b1[0], 0)
100 | t.equal(b1[1], 1)
101 | t.equal(b1[2], 2)
102 | t.equal(b1[3], 3)
103 | t.equal(b1[4], undefined)
104 | }
105 | t.end()
106 | })
107 |
108 | test('new buffer from Uint32Array', function (t) {
109 | if (typeof Uint32Array !== 'undefined') {
110 | const b1 = new Uint32Array([0, 1, 2, 3])
111 | const b2 = new B(b1)
112 | t.equal(b1.length, b2.length)
113 | t.equal(b1[0], 0)
114 | t.equal(b1[1], 1)
115 | t.equal(b1[2], 2)
116 | t.equal(b1[3], 3)
117 | t.equal(b1[4], undefined)
118 | }
119 | t.end()
120 | })
121 |
122 | test('new buffer from Int16Array', function (t) {
123 | if (typeof Int16Array !== 'undefined') {
124 | const b1 = new Int16Array([0, 1, 2, 3])
125 | const b2 = new B(b1)
126 | t.equal(b1.length, b2.length)
127 | t.equal(b1[0], 0)
128 | t.equal(b1[1], 1)
129 | t.equal(b1[2], 2)
130 | t.equal(b1[3], 3)
131 | t.equal(b1[4], undefined)
132 | }
133 | t.end()
134 | })
135 |
136 | test('new buffer from Int32Array', function (t) {
137 | if (typeof Int32Array !== 'undefined') {
138 | const b1 = new Int32Array([0, 1, 2, 3])
139 | const b2 = new B(b1)
140 | t.equal(b1.length, b2.length)
141 | t.equal(b1[0], 0)
142 | t.equal(b1[1], 1)
143 | t.equal(b1[2], 2)
144 | t.equal(b1[3], 3)
145 | t.equal(b1[4], undefined)
146 | }
147 | t.end()
148 | })
149 |
150 | test('new buffer from Float32Array', function (t) {
151 | if (typeof Float32Array !== 'undefined') {
152 | const b1 = new Float32Array([0, 1, 2, 3])
153 | const b2 = new B(b1)
154 | t.equal(b1.length, b2.length)
155 | t.equal(b1[0], 0)
156 | t.equal(b1[1], 1)
157 | t.equal(b1[2], 2)
158 | t.equal(b1[3], 3)
159 | t.equal(b1[4], undefined)
160 | }
161 | t.end()
162 | })
163 |
164 | test('new buffer from Float64Array', function (t) {
165 | if (typeof Float64Array !== 'undefined') {
166 | const b1 = new Float64Array([0, 1, 2, 3])
167 | const b2 = new B(b1)
168 | t.equal(b1.length, b2.length)
169 | t.equal(b1[0], 0)
170 | t.equal(b1[1], 1)
171 | t.equal(b1[2], 2)
172 | t.equal(b1[3], 3)
173 | t.equal(b1[4], undefined)
174 | }
175 | t.end()
176 | })
177 |
178 | test('new buffer from buffer.toJSON() output', function (t) {
179 | if (typeof JSON === 'undefined') {
180 | // ie6, ie7 lack support
181 | t.end()
182 | return
183 | }
184 | const buf = new B('test')
185 | const json = JSON.stringify(buf)
186 | const obj = JSON.parse(json)
187 | const copy = new B(obj)
188 | t.ok(buf.equals(copy))
189 | t.end()
190 | })
191 |
--------------------------------------------------------------------------------
/test/node/test-buffer-slice.js:
--------------------------------------------------------------------------------
1 | // Copyright Joyent, Inc. and other Node contributors.var Buffer = require('../../').Buffer;
2 | // Copyright Joyent, Inc. and other Node contributors.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a
5 | // copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit
9 | // persons to whom the Software is furnished to do so, subject to the
10 | // following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included
13 | // in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
18 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
23 | 'use strict';
24 |
25 | require('./common');
26 | const assert = require('assert');
27 |
28 | assert.strictEqual(0, Buffer.from('hello', 'utf8').slice(0, 0).length);
29 | assert.strictEqual(0, Buffer('hello', 'utf8').slice(0, 0).length);
30 |
31 | const buf = Buffer.from('0123456789', 'utf8');
32 | const expectedSameBufs = [
33 | [buf.slice(-10, 10), Buffer.from('0123456789', 'utf8')],
34 | [buf.slice(-20, 10), Buffer.from('0123456789', 'utf8')],
35 | [buf.slice(-20, -10), Buffer.from('', 'utf8')],
36 | [buf.slice(), Buffer.from('0123456789', 'utf8')],
37 | [buf.slice(0), Buffer.from('0123456789', 'utf8')],
38 | [buf.slice(0, 0), Buffer.from('', 'utf8')],
39 | [buf.slice(undefined), Buffer.from('0123456789', 'utf8')],
40 | [buf.slice('foobar'), Buffer.from('0123456789', 'utf8')],
41 | [buf.slice(undefined, undefined), Buffer.from('0123456789', 'utf8')],
42 | [buf.slice(2), Buffer.from('23456789', 'utf8')],
43 | [buf.slice(5), Buffer.from('56789', 'utf8')],
44 | [buf.slice(10), Buffer.from('', 'utf8')],
45 | [buf.slice(5, 8), Buffer.from('567', 'utf8')],
46 | [buf.slice(8, -1), Buffer.from('8', 'utf8')],
47 | [buf.slice(-10), Buffer.from('0123456789', 'utf8')],
48 | [buf.slice(0, -9), Buffer.from('0', 'utf8')],
49 | [buf.slice(0, -10), Buffer.from('', 'utf8')],
50 | [buf.slice(0, -1), Buffer.from('012345678', 'utf8')],
51 | [buf.slice(2, -2), Buffer.from('234567', 'utf8')],
52 | [buf.slice(0, 65536), Buffer.from('0123456789', 'utf8')],
53 | [buf.slice(65536, 0), Buffer.from('', 'utf8')],
54 | [buf.slice(-5, -8), Buffer.from('', 'utf8')],
55 | [buf.slice(-5, -3), Buffer.from('56', 'utf8')],
56 | [buf.slice(-10, 10), Buffer.from('0123456789', 'utf8')],
57 | [buf.slice('0', '1'), Buffer.from('0', 'utf8')],
58 | [buf.slice('-5', '10'), Buffer.from('56789', 'utf8')],
59 | [buf.slice('-10', '10'), Buffer.from('0123456789', 'utf8')],
60 | [buf.slice('-10', '-5'), Buffer.from('01234', 'utf8')],
61 | [buf.slice('-10', '-0'), Buffer.from('', 'utf8')],
62 | [buf.slice('111'), Buffer.from('', 'utf8')],
63 | [buf.slice('0', '-111'), Buffer.from('', 'utf8')]
64 | ];
65 |
66 | for (let i = 0, s = buf.toString(); i < buf.length; ++i) {
67 | expectedSameBufs.push(
68 | [buf.slice(i), Buffer.from(s.slice(i))],
69 | [buf.slice(0, i), Buffer.from(s.slice(0, i))],
70 | [buf.slice(-i), Buffer.from(s.slice(-i))],
71 | [buf.slice(0, -i), Buffer.from(s.slice(0, -i))]
72 | );
73 | }
74 |
75 | expectedSameBufs.forEach(([buf1, buf2]) => {
76 | assert.strictEqual(0, Buffer.compare(buf1, buf2));
77 | });
78 |
79 | const utf16Buf = Buffer.from('0123456789', 'utf16le');
80 | assert.deepStrictEqual(utf16Buf.slice(0, 6), Buffer.from('012', 'utf16le'));
81 | // try to slice a zero length Buffer
82 | // see https://github.com/joyent/node/issues/5881
83 | assert.doesNotThrow(() => Buffer.alloc(0).slice(0, 1));
84 | assert.strictEqual(Buffer.alloc(0).slice(0, 1).length, 0);
85 |
86 | {
87 | // Single argument slice
88 | assert.strictEqual('bcde',
89 | Buffer.from('abcde', 'utf8').slice(1).toString('utf8'));
90 | }
91 |
92 | // slice(0,0).length === 0
93 | assert.strictEqual(0, Buffer.from('hello', 'utf8').slice(0, 0).length);
94 |
95 | {
96 | // Regression tests for https://github.com/nodejs/node/issues/9096
97 | const buf = Buffer.from('abcd', 'utf8');
98 | assert.strictEqual(buf.slice(buf.length / 3).toString('utf8'), 'bcd');
99 | assert.strictEqual(
100 | buf.slice(buf.length / 3, buf.length).toString(),
101 | 'bcd'
102 | );
103 | }
104 |
105 | {
106 | const buf = Buffer.from('abcdefg', 'utf8');
107 | assert.strictEqual(buf.slice(-(-1 >>> 0) - 1).toString('utf8'),
108 | buf.toString('utf8'));
109 | }
110 |
111 | {
112 | const buf = Buffer.from('abc', 'utf8');
113 | assert.strictEqual(buf.slice(-0.5).toString('utf8'), buf.toString('utf8'));
114 | }
115 |
116 | {
117 | const buf = Buffer.from([
118 | 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0,
119 | 0, 0, 18, 184, 6, 0, 175, 29, 0, 8, 11, 1, 0, 0
120 | ]);
121 | const chunk1 = Buffer.from([
122 | 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0
123 | ]);
124 | const chunk2 = Buffer.from([
125 | 0, 0, 18, 184, 6, 0, 175, 29, 0, 8, 11, 1, 0, 0
126 | ]);
127 | const middle = buf.length / 2;
128 |
129 | assert.deepStrictEqual(buf.slice(0, middle), chunk1);
130 | assert.deepStrictEqual(buf.slice(middle), chunk2);
131 | }
132 |
133 |
--------------------------------------------------------------------------------
/test/node/test-buffer-swap.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 | require('./common');
5 | const assert = require('assert');
6 |
7 | // Test buffers small enough to use the JS implementation
8 | {
9 | const buf = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
10 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10]);
11 |
12 | assert.strictEqual(buf, buf.swap16());
13 | assert.deepStrictEqual(buf, Buffer.from([0x02, 0x01, 0x04, 0x03, 0x06, 0x05,
14 | 0x08, 0x07, 0x0a, 0x09, 0x0c, 0x0b,
15 | 0x0e, 0x0d, 0x10, 0x0f]));
16 | buf.swap16(); // restore
17 |
18 | assert.strictEqual(buf, buf.swap32());
19 | assert.deepStrictEqual(buf, Buffer.from([0x04, 0x03, 0x02, 0x01, 0x08, 0x07,
20 | 0x06, 0x05, 0x0c, 0x0b, 0x0a, 0x09,
21 | 0x10, 0x0f, 0x0e, 0x0d]));
22 | buf.swap32(); // restore
23 |
24 | assert.strictEqual(buf, buf.swap64());
25 | assert.deepStrictEqual(buf, Buffer.from([0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
26 | 0x02, 0x01, 0x10, 0x0f, 0x0e, 0x0d,
27 | 0x0c, 0x0b, 0x0a, 0x09]));
28 | }
29 |
30 | // Operates in-place
31 | {
32 | const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7]);
33 | buf.slice(1, 5).swap32();
34 | assert.deepStrictEqual(buf, Buffer.from([0x1, 0x5, 0x4, 0x3, 0x2, 0x6, 0x7]));
35 | buf.slice(1, 5).swap16();
36 | assert.deepStrictEqual(buf, Buffer.from([0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7]));
37 |
38 | // Length assertions
39 | const re16 = /Buffer size must be a multiple of 16-bits/;
40 | const re32 = /Buffer size must be a multiple of 32-bits/;
41 | const re64 = /Buffer size must be a multiple of 64-bits/;
42 |
43 | assert.throws(() => Buffer.from(buf).swap16(), re16);
44 | assert.throws(() => Buffer.alloc(1025).swap16(), re16);
45 | assert.throws(() => Buffer.from(buf).swap32(), re32);
46 | assert.throws(() => buf.slice(1, 3).swap32(), re32);
47 | assert.throws(() => Buffer.alloc(1025).swap32(), re32);
48 | assert.throws(() => buf.slice(1, 3).swap64(), re64);
49 | assert.throws(() => Buffer.alloc(1025).swap64(), re64);
50 | }
51 |
52 | {
53 | const buf = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
54 | 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
55 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
56 | 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10]);
57 |
58 | buf.slice(2, 18).swap64();
59 |
60 | assert.deepStrictEqual(buf, Buffer.from([0x01, 0x02, 0x0a, 0x09, 0x08, 0x07,
61 | 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
62 | 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b,
63 | 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
64 | 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
65 | 0x0f, 0x10]));
66 | }
67 |
68 | // Force use of native code (Buffer size above threshold limit for js impl)
69 | {
70 | const bufData = new Uint32Array(256).fill(0x04030201);
71 | const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
72 | const otherBufData = new Uint32Array(256).fill(0x03040102);
73 | const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset);
74 | buf.swap16();
75 | assert.deepStrictEqual(buf, otherBuf);
76 | }
77 |
78 | {
79 | const bufData = new Uint32Array(256).fill(0x04030201);
80 | const buf = Buffer.from(bufData.buffer);
81 | const otherBufData = new Uint32Array(256).fill(0x01020304);
82 | const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset);
83 | buf.swap32();
84 | assert.deepStrictEqual(buf, otherBuf);
85 | }
86 |
87 | {
88 | const bufData = new Uint8Array(256 * 8);
89 | const otherBufData = new Uint8Array(256 * 8);
90 | for (let i = 0; i < bufData.length; i++) {
91 | bufData[i] = i % 8;
92 | otherBufData[otherBufData.length - i - 1] = i % 8;
93 | }
94 | const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
95 | const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset);
96 | buf.swap64();
97 | assert.deepStrictEqual(buf, otherBuf);
98 | }
99 |
100 | // Test native code with buffers that are not memory-aligned
101 | {
102 | const bufData = new Uint8Array(256 * 8);
103 | const otherBufData = new Uint8Array(256 * 8 - 2);
104 | for (let i = 0; i < bufData.length; i++) {
105 | bufData[i] = i % 2;
106 | }
107 | for (let i = 1; i < otherBufData.length; i++) {
108 | otherBufData[otherBufData.length - i] = (i + 1) % 2;
109 | }
110 | const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
111 | // 0|1 0|1 0|1...
112 | const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset);
113 | // 0|0 1|0 1|0...
114 |
115 | buf.slice(1, buf.length - 1).swap16();
116 | assert.deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf);
117 | }
118 |
119 | {
120 | const bufData = new Uint8Array(256 * 8);
121 | const otherBufData = new Uint8Array(256 * 8 - 4);
122 | for (let i = 0; i < bufData.length; i++) {
123 | bufData[i] = i % 4;
124 | }
125 | for (let i = 1; i < otherBufData.length; i++) {
126 | otherBufData[otherBufData.length - i] = (i + 1) % 4;
127 | }
128 | const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
129 | // 0|1 2 3 0|1 2 3...
130 | const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset);
131 | // 0|0 3 2 1|0 3 2...
132 |
133 | buf.slice(1, buf.length - 3).swap32();
134 | assert.deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf);
135 | }
136 |
137 | {
138 | const bufData = new Uint8Array(256 * 8);
139 | const otherBufData = new Uint8Array(256 * 8 - 8);
140 | for (let i = 0; i < bufData.length; i++) {
141 | bufData[i] = i % 8;
142 | }
143 | for (let i = 1; i < otherBufData.length; i++) {
144 | otherBufData[otherBufData.length - i] = (i + 1) % 8;
145 | }
146 | const buf = Buffer.from(bufData.buffer, bufData.byteOffset);
147 | // 0|1 2 3 4 5 6 7 0|1 2 3 4...
148 | const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset);
149 | // 0|0 7 6 5 4 3 2 1|0 7 6 5...
150 |
151 | buf.slice(1, buf.length - 7).swap64();
152 | assert.deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf);
153 | }
154 |
155 |
--------------------------------------------------------------------------------
/test/to-string.js:
--------------------------------------------------------------------------------
1 | const B = require('../').Buffer
2 | const test = require('tape')
3 |
4 | test('utf8 buffer to base64', function (t) {
5 | t.equal(
6 | new B('Ձאab', 'utf8').toString('base64'),
7 | '1YHXkGFi'
8 | )
9 | t.end()
10 | })
11 |
12 | test('utf8 buffer to hex', function (t) {
13 | t.equal(
14 | new B('Ձאab', 'utf8').toString('hex'),
15 | 'd581d7906162'
16 | )
17 | t.end()
18 | })
19 |
20 | test('utf8 to utf8', function (t) {
21 | t.equal(
22 | new B('öäüõÖÄÜÕ', 'utf8').toString('utf8'),
23 | 'öäüõÖÄÜÕ'
24 | )
25 | t.end()
26 | })
27 |
28 | test('utf16le to utf16', function (t) {
29 | t.equal(
30 | new B(new B('abcd', 'utf8').toString('utf16le'), 'utf16le').toString('utf8'),
31 | 'abcd'
32 | )
33 | t.end()
34 | })
35 |
36 | test('utf16le to utf16 with odd byte length input', function (t) {
37 | t.equal(
38 | new B(new B('abcde', 'utf8').toString('utf16le'), 'utf16le').toString('utf8'),
39 | 'abcd'
40 | )
41 | t.end()
42 | })
43 |
44 | test('utf16le to hex', function (t) {
45 | t.equal(
46 | new B('abcd', 'utf16le').toString('hex'),
47 | '6100620063006400'
48 | )
49 | t.end()
50 | })
51 |
52 | test('ascii buffer to base64', function (t) {
53 | t.equal(
54 | new B('123456!@#$%^', 'ascii').toString('base64'),
55 | 'MTIzNDU2IUAjJCVe'
56 | )
57 | t.end()
58 | })
59 |
60 | test('ascii buffer to hex', function (t) {
61 | t.equal(
62 | new B('123456!@#$%^', 'ascii').toString('hex'),
63 | '31323334353621402324255e'
64 | )
65 | t.end()
66 | })
67 |
68 | test('base64 buffer to utf8', function (t) {
69 | t.equal(
70 | new B('1YHXkGFi', 'base64').toString('utf8'),
71 | 'Ձאab'
72 | )
73 | t.end()
74 | })
75 |
76 | test('hex buffer to utf8', function (t) {
77 | t.equal(
78 | new B('d581d7906162', 'hex').toString('utf8'),
79 | 'Ձאab'
80 | )
81 | t.end()
82 | })
83 |
84 | test('base64 buffer to ascii', function (t) {
85 | t.equal(
86 | new B('MTIzNDU2IUAjJCVe', 'base64').toString('ascii'),
87 | '123456!@#$%^'
88 | )
89 | t.end()
90 | })
91 |
92 | test('hex buffer to ascii', function (t) {
93 | t.equal(
94 | new B('31323334353621402324255e', 'hex').toString('ascii'),
95 | '123456!@#$%^'
96 | )
97 | t.end()
98 | })
99 |
100 | test('base64 buffer to binary', function (t) {
101 | t.equal(
102 | new B('MTIzNDU2IUAjJCVe', 'base64').toString('binary'),
103 | '123456!@#$%^'
104 | )
105 | t.end()
106 | })
107 |
108 | test('hex buffer to binary', function (t) {
109 | t.equal(
110 | new B('31323334353621402324255e', 'hex').toString('binary'),
111 | '123456!@#$%^'
112 | )
113 | t.end()
114 | })
115 |
116 | test('utf8 to binary', function (t) {
117 | /* jshint -W100 */
118 | t.equal(
119 | new B('öäüõÖÄÜÕ', 'utf8').toString('binary'),
120 | 'öäüõÃÃÃÃ'
121 | )
122 | /* jshint +W100 */
123 | t.end()
124 | })
125 |
126 | test('utf8 replacement chars (1 byte sequence)', function (t) {
127 | t.equal(
128 | new B([0x80]).toString(),
129 | '\uFFFD'
130 | )
131 | t.equal(
132 | new B([0x7F]).toString(),
133 | '\u007F'
134 | )
135 | t.end()
136 | })
137 |
138 | test('utf8 replacement chars (2 byte sequences)', function (t) {
139 | t.equal(
140 | new B([0xC7]).toString(),
141 | '\uFFFD'
142 | )
143 | t.equal(
144 | new B([0xC7, 0xB1]).toString(),
145 | '\u01F1'
146 | )
147 | t.equal(
148 | new B([0xC0, 0xB1]).toString(),
149 | '\uFFFD\uFFFD'
150 | )
151 | t.equal(
152 | new B([0xC1, 0xB1]).toString(),
153 | '\uFFFD\uFFFD'
154 | )
155 | t.end()
156 | })
157 |
158 | test('utf8 replacement chars (3 byte sequences)', function (t) {
159 | t.equal(
160 | new B([0xE0]).toString(),
161 | '\uFFFD'
162 | )
163 | t.equal(
164 | new B([0xE0, 0xAC]).toString(),
165 | '\uFFFD\uFFFD'
166 | )
167 | t.equal(
168 | new B([0xE0, 0xAC, 0xB9]).toString(),
169 | '\u0B39'
170 | )
171 | t.end()
172 | })
173 |
174 | test('utf8 replacement chars (4 byte sequences)', function (t) {
175 | t.equal(
176 | new B([0xF4]).toString(),
177 | '\uFFFD'
178 | )
179 | t.equal(
180 | new B([0xF4, 0x8F]).toString(),
181 | '\uFFFD\uFFFD'
182 | )
183 | t.equal(
184 | new B([0xF4, 0x8F, 0x80]).toString(),
185 | '\uFFFD\uFFFD\uFFFD'
186 | )
187 | t.equal(
188 | new B([0xF4, 0x8F, 0x80, 0x84]).toString(),
189 | '\uDBFC\uDC04'
190 | )
191 | t.equal(
192 | new B([0xFF]).toString(),
193 | '\uFFFD'
194 | )
195 | t.equal(
196 | new B([0xFF, 0x8F, 0x80, 0x84]).toString(),
197 | '\uFFFD\uFFFD\uFFFD\uFFFD'
198 | )
199 | t.end()
200 | })
201 |
202 | test('utf8 replacement chars on 256 random bytes', function (t) {
203 | t.equal(
204 | 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(),
205 | '\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'
206 | )
207 | t.end()
208 | })
209 |
210 | test('utf8 replacement chars for anything in the surrogate pair range', function (t) {
211 | t.equal(
212 | new B([0xED, 0x9F, 0xBF]).toString(),
213 | '\uD7FF'
214 | )
215 | t.equal(
216 | new B([0xED, 0xA0, 0x80]).toString(),
217 | '\uFFFD\uFFFD\uFFFD'
218 | )
219 | t.equal(
220 | new B([0xED, 0xBE, 0x8B]).toString(),
221 | '\uFFFD\uFFFD\uFFFD'
222 | )
223 | t.equal(
224 | new B([0xED, 0xBF, 0xBF]).toString(),
225 | '\uFFFD\uFFFD\uFFFD'
226 | )
227 | t.equal(
228 | new B([0xEE, 0x80, 0x80]).toString(),
229 | '\uE000'
230 | )
231 | t.end()
232 | })
233 |
234 | test('utf8 don\'t replace the replacement char', function (t) {
235 | t.equal(
236 | new B('\uFFFD').toString(),
237 | '\uFFFD'
238 | )
239 | t.end()
240 | })
241 |
--------------------------------------------------------------------------------
/test/node/test-buffer-fill.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 | const common = require('./common');
4 |
5 |
6 | var assert = require('assert');
7 | var os = require('os');
8 | var SIZE = 28;
9 |
10 | var buf1 = Buffer.allocUnsafe(SIZE);
11 | var buf2 = Buffer.allocUnsafe(SIZE);
12 |
13 |
14 | // Default encoding
15 | testBufs('abc');
16 | testBufs('\u0222aa');
17 | testBufs('a\u0234b\u0235c\u0236');
18 | testBufs('abc', 4);
19 | testBufs('abc', 5);
20 | testBufs('abc', SIZE);
21 | testBufs('\u0222aa', 2);
22 | testBufs('\u0222aa', 8);
23 | testBufs('a\u0234b\u0235c\u0236', 4);
24 | testBufs('a\u0234b\u0235c\u0236', 12);
25 | testBufs('abc', 4, -1);
26 | testBufs('abc', 4, 1);
27 | testBufs('abc', 5, 1);
28 | testBufs('\u0222aa', 2, -1);
29 | testBufs('\u0222aa', 8, 1);
30 | testBufs('a\u0234b\u0235c\u0236', 4, -1);
31 | testBufs('a\u0234b\u0235c\u0236', 4, 1);
32 | testBufs('a\u0234b\u0235c\u0236', 12, 1);
33 |
34 |
35 | // UTF8
36 | testBufs('abc', 'utf8');
37 | testBufs('\u0222aa', 'utf8');
38 | testBufs('a\u0234b\u0235c\u0236', 'utf8');
39 | testBufs('abc', 4, 'utf8');
40 | testBufs('abc', 5, 'utf8');
41 | testBufs('abc', SIZE, 'utf8');
42 | testBufs('\u0222aa', 2, 'utf8');
43 | testBufs('\u0222aa', 8, 'utf8');
44 | testBufs('a\u0234b\u0235c\u0236', 4, 'utf8');
45 | testBufs('a\u0234b\u0235c\u0236', 12, 'utf8');
46 | testBufs('abc', 4, -1, 'utf8');
47 | testBufs('abc', 4, 1, 'utf8');
48 | testBufs('abc', 5, 1, 'utf8');
49 | testBufs('\u0222aa', 2, -1, 'utf8');
50 | testBufs('\u0222aa', 8, 1, 'utf8');
51 | testBufs('a\u0234b\u0235c\u0236', 4, -1, 'utf8');
52 | testBufs('a\u0234b\u0235c\u0236', 4, 1, 'utf8');
53 | testBufs('a\u0234b\u0235c\u0236', 12, 1, 'utf8');
54 | assert.equal(Buffer.allocUnsafe(1).fill(0).fill('\u0222')[0], 0xc8);
55 |
56 |
57 | // BINARY
58 | testBufs('abc', 'binary');
59 | testBufs('\u0222aa', 'binary');
60 | testBufs('a\u0234b\u0235c\u0236', 'binary');
61 | testBufs('abc', 4, 'binary');
62 | testBufs('abc', 5, 'binary');
63 | testBufs('abc', SIZE, 'binary');
64 | testBufs('\u0222aa', 2, 'binary');
65 | testBufs('\u0222aa', 8, 'binary');
66 | testBufs('a\u0234b\u0235c\u0236', 4, 'binary');
67 | testBufs('a\u0234b\u0235c\u0236', 12, 'binary');
68 | testBufs('abc', 4, -1, 'binary');
69 | testBufs('abc', 4, 1, 'binary');
70 | testBufs('abc', 5, 1, 'binary');
71 | testBufs('\u0222aa', 2, -1, 'binary');
72 | testBufs('\u0222aa', 8, 1, 'binary');
73 | testBufs('a\u0234b\u0235c\u0236', 4, -1, 'binary');
74 | testBufs('a\u0234b\u0235c\u0236', 4, 1, 'binary');
75 | testBufs('a\u0234b\u0235c\u0236', 12, 1, 'binary');
76 |
77 |
78 | // LATIN1
79 | testBufs('abc', 'latin1');
80 | testBufs('\u0222aa', 'latin1');
81 | testBufs('a\u0234b\u0235c\u0236', 'latin1');
82 | testBufs('abc', 4, 'latin1');
83 | testBufs('abc', 5, 'latin1');
84 | testBufs('abc', SIZE, 'latin1');
85 | testBufs('\u0222aa', 2, 'latin1');
86 | testBufs('\u0222aa', 8, 'latin1');
87 | testBufs('a\u0234b\u0235c\u0236', 4, 'latin1');
88 | testBufs('a\u0234b\u0235c\u0236', 12, 'latin1');
89 | testBufs('abc', 4, -1, 'latin1');
90 | testBufs('abc', 4, 1, 'latin1');
91 | testBufs('abc', 5, 1, 'latin1');
92 | testBufs('\u0222aa', 2, -1, 'latin1');
93 | testBufs('\u0222aa', 8, 1, 'latin1');
94 | testBufs('a\u0234b\u0235c\u0236', 4, -1, 'latin1');
95 | testBufs('a\u0234b\u0235c\u0236', 4, 1, 'latin1');
96 | testBufs('a\u0234b\u0235c\u0236', 12, 1, 'latin1');
97 |
98 |
99 | // UCS2
100 | testBufs('abc', 'ucs2');
101 | testBufs('\u0222aa', 'ucs2');
102 | testBufs('a\u0234b\u0235c\u0236', 'ucs2');
103 | testBufs('abc', 4, 'ucs2');
104 | testBufs('abc', SIZE, 'ucs2');
105 | testBufs('\u0222aa', 2, 'ucs2');
106 | testBufs('\u0222aa', 8, 'ucs2');
107 | testBufs('a\u0234b\u0235c\u0236', 4, 'ucs2');
108 | testBufs('a\u0234b\u0235c\u0236', 12, 'ucs2');
109 | testBufs('abc', 4, -1, 'ucs2');
110 | testBufs('abc', 4, 1, 'ucs2');
111 | testBufs('abc', 5, 1, 'ucs2');
112 | testBufs('\u0222aa', 2, -1, 'ucs2');
113 | testBufs('\u0222aa', 8, 1, 'ucs2');
114 | testBufs('a\u0234b\u0235c\u0236', 4, -1, 'ucs2');
115 | testBufs('a\u0234b\u0235c\u0236', 4, 1, 'ucs2');
116 | testBufs('a\u0234b\u0235c\u0236', 12, 1, 'ucs2');
117 | assert.equal(Buffer.allocUnsafe(1).fill('\u0222', 'ucs2')[0],
118 | os.endianness() === 'LE' ? 0x22 : 0x02);
119 |
120 |
121 | // HEX
122 | testBufs('616263', 'hex');
123 | testBufs('c8a26161', 'hex');
124 | testBufs('61c8b462c8b563c8b6', 'hex');
125 | testBufs('616263', 4, 'hex');
126 | testBufs('616263', 5, 'hex');
127 | testBufs('616263', SIZE, 'hex');
128 | testBufs('c8a26161', 2, 'hex');
129 | testBufs('c8a26161', 8, 'hex');
130 | testBufs('61c8b462c8b563c8b6', 4, 'hex');
131 | testBufs('61c8b462c8b563c8b6', 12, 'hex');
132 | testBufs('616263', 4, -1, 'hex');
133 | testBufs('616263', 4, 1, 'hex');
134 | testBufs('616263', 5, 1, 'hex');
135 | testBufs('c8a26161', 2, -1, 'hex');
136 | testBufs('c8a26161', 8, 1, 'hex');
137 | testBufs('61c8b462c8b563c8b6', 4, -1, 'hex');
138 | testBufs('61c8b462c8b563c8b6', 4, 1, 'hex');
139 | testBufs('61c8b462c8b563c8b6', 12, 1, 'hex');
140 |
141 | common.expectsError(() => {
142 | const buf = Buffer.allocUnsafe(SIZE);
143 |
144 | buf.fill('yKJh', 'hex');
145 | }, {
146 | code: 'ERR_INVALID_ARG_VALUE',
147 | type: TypeError
148 | });
149 |
150 | common.expectsError(() => {
151 | const buf = Buffer.allocUnsafe(SIZE);
152 |
153 | buf.fill('\u0222', 'hex');
154 | }, {
155 | code: 'ERR_INVALID_ARG_VALUE',
156 | type: TypeError
157 | });
158 |
159 | // BASE64
160 | testBufs('YWJj', 'ucs2');
161 | testBufs('yKJhYQ==', 'ucs2');
162 | testBufs('Yci0Ysi1Y8i2', 'ucs2');
163 | testBufs('YWJj', 4, 'ucs2');
164 | testBufs('YWJj', SIZE, 'ucs2');
165 | testBufs('yKJhYQ==', 2, 'ucs2');
166 | testBufs('yKJhYQ==', 8, 'ucs2');
167 | testBufs('Yci0Ysi1Y8i2', 4, 'ucs2');
168 | testBufs('Yci0Ysi1Y8i2', 12, 'ucs2');
169 | testBufs('YWJj', 4, -1, 'ucs2');
170 | testBufs('YWJj', 4, 1, 'ucs2');
171 | testBufs('YWJj', 5, 1, 'ucs2');
172 | testBufs('yKJhYQ==', 2, -1, 'ucs2');
173 | testBufs('yKJhYQ==', 8, 1, 'ucs2');
174 | testBufs('Yci0Ysi1Y8i2', 4, -1, 'ucs2');
175 | testBufs('Yci0Ysi1Y8i2', 4, 1, 'ucs2');
176 | testBufs('Yci0Ysi1Y8i2', 12, 1, 'ucs2');
177 |
178 |
179 | // Buffer
180 | function deepStrictEqualValues(buf, arr) {
181 | for (var [index, value] of buf.entries()) {
182 | assert.deepStrictEqual(value, arr[index]);
183 | }
184 | }
185 |
186 |
187 | var buf2Fill = Buffer.allocUnsafe(1).fill(2);
188 | deepStrictEqualValues(genBuffer(4, [buf2Fill]), [2, 2, 2, 2]);
189 | deepStrictEqualValues(genBuffer(4, [buf2Fill, 1]), [0, 2, 2, 2]);
190 | deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, 3]), [0, 2, 2, 0]);
191 | deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, 1]), [0, 0, 0, 0]);
192 | deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, -1]), [0, 0, 0, 0]);
193 | var hexBufFill = Buffer.allocUnsafe(2).fill(0).fill('0102', 'hex');
194 | deepStrictEqualValues(genBuffer(4, [hexBufFill]), [1, 2, 1, 2]);
195 | deepStrictEqualValues(genBuffer(4, [hexBufFill, 1]), [0, 1, 2, 1]);
196 | deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, 3]), [0, 1, 2, 0]);
197 | deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, 1]), [0, 0, 0, 0]);
198 | deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, -1]), [0, 0, 0, 0]);
199 |
200 |
201 | // Check exceptions
202 | assert.throws(() => buf1.fill(0, -1));
203 | assert.throws(() => buf1.fill(0, 0, buf1.length + 1));
204 | assert.throws(() => buf1.fill('', -1));
205 | assert.throws(() => buf1.fill('', 0, buf1.length + 1));
206 | assert.throws(() => buf1.fill('a', 0, buf1.length, 'node rocks!'));
207 | assert.throws(() => buf1.fill('a', 0, 0, NaN));
208 | assert.throws(() => buf1.fill('a', 0, 0, null));
209 | assert.throws(() => buf1.fill('a', 0, 0, 'foo'));
210 |
211 |
212 | function genBuffer(size, args) {
213 | var b = Buffer.allocUnsafe(size);
214 | return b.fill(0).fill.apply(b, args);
215 | }
216 |
217 |
218 | function bufReset() {
219 | buf1.fill(0);
220 | buf2.fill(0);
221 | }
222 |
223 |
224 | // This is mostly accurate. Except write() won't write partial bytes to the
225 | // string while fill() blindly copies bytes into memory. To account for that an
226 | // error will be thrown if not all the data can be written, and the SIZE has
227 | // been massaged to work with the input characters.
228 | function writeToFill(string, offset, end, encoding) {
229 | if (typeof offset === 'string') {
230 | encoding = offset;
231 | offset = 0;
232 | end = buf2.length;
233 | } else if (typeof end === 'string') {
234 | encoding = end;
235 | end = buf2.length;
236 | } else if (end === undefined) {
237 | end = buf2.length;
238 | }
239 |
240 | if (offset < 0 || end > buf2.length)
241 | throw new RangeError('Out of range index');
242 |
243 | if (end <= offset)
244 | return buf2;
245 |
246 | offset >>>= 0;
247 | end >>>= 0;
248 | assert(offset <= buf2.length);
249 |
250 | // Convert "end" to "length" (which write understands).
251 | var length = end - offset < 0 ? 0 : end - offset;
252 |
253 | var wasZero = false;
254 | do {
255 | var written = buf2.write(string, offset, length, encoding);
256 | offset += written;
257 | // Safety check in case write falls into infinite loop.
258 | if (written === 0) {
259 | if (wasZero)
260 | throw new Error('Could not write all data to Buffer');
261 | else
262 | wasZero = true;
263 | }
264 | } while (offset < buf2.length);
265 |
266 | // Correction for UCS2 operations.
267 | if (os.endianness() === 'BE' && encoding === 'ucs2') {
268 | for (var i = 0; i < buf2.length; i += 2) {
269 | var tmp = buf2[i];
270 | buf2[i] = buf2[i + 1];
271 | buf2[i + 1] = tmp;
272 | }
273 | }
274 |
275 | return buf2;
276 | }
277 |
278 |
279 | function testBufs(string, offset, length, encoding) {
280 | bufReset();
281 | buf1.fill.apply(buf1, arguments);
282 | // Swap bytes on BE archs for ucs2 encoding.
283 | assert.deepStrictEqual(buf1.fill.apply(buf1, arguments),
284 | writeToFill.apply(null, arguments));
285 | }
286 |
287 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | export class Buffer extends Uint8Array {
2 | length: number
3 | write(string: string, offset?: number, length?: number, encoding?: string): number;
4 | toString(encoding?: string, start?: number, end?: number): string;
5 | toJSON(): { type: 'Buffer', data: any[] };
6 | equals(otherBuffer: Buffer): boolean;
7 | compare(otherBuffer: Uint8Array, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number;
8 | copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
9 | slice(start?: number, end?: number): Buffer;
10 | subarray(start?: number, end?: number): Buffer;
11 | writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
12 | writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
13 | writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
14 | writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
15 | readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
16 | readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
17 | readIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
18 | readIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
19 | readUInt8(offset: number, noAssert?: boolean): number;
20 | readUInt16LE(offset?: number, noAssert?: boolean): number;
21 | readUInt16BE(offset?: number, noAssert?: boolean): number;
22 | readUInt32LE(offset?: number, noAssert?: boolean): number;
23 | readUInt32BE(offset?: number, noAssert?: boolean): number;
24 | readBigUInt64LE(offset?: number): bigint;
25 | readBigUInt64BE(offset?: number): bigint;
26 | readInt8(offset?: number, noAssert?: boolean): number;
27 | readInt16LE(offset?: number, noAssert?: boolean): number;
28 | readInt16BE(offset?: number, noAssert?: boolean): number;
29 | readInt32LE(offset?: number, noAssert?: boolean): number;
30 | readInt32BE(offset?: number, noAssert?: boolean): number;
31 | readBigInt64LE(offset?: number): bigint;
32 | readBigInt64BE(offset?: number): bigint;
33 | readFloatLE(offset?: number, noAssert?: boolean): number;
34 | readFloatBE(offset?: number, noAssert?: boolean): number;
35 | readDoubleLE(offset?: number, noAssert?: boolean): number;
36 | readDoubleBE(offset?: number, noAssert?: boolean): number;
37 | reverse(): this;
38 | swap16(): Buffer;
39 | swap32(): Buffer;
40 | swap64(): Buffer;
41 | writeUInt8(value: number, offset?: number, noAssert?: boolean): number;
42 | writeUInt16LE(value: number, offset?: number, noAssert?: boolean): number;
43 | writeUInt16BE(value: number, offset?: number, noAssert?: boolean): number;
44 | writeUInt32LE(value: number, offset?: number, noAssert?: boolean): number;
45 | writeUInt32BE(value: number, offset?: number, noAssert?: boolean): number;
46 | writeBigUInt64LE(value: bigint, offset?: number): number;
47 | writeBigUInt64BE(value: bigint, offset?: number): number;
48 | writeInt8(value: number, offset?: number, noAssert?: boolean): number;
49 | writeInt16LE(value: number, offset?: number, noAssert?: boolean): number;
50 | writeInt16BE(value: number, offset?: number, noAssert?: boolean): number;
51 | writeInt32LE(value: number, offset?: number, noAssert?: boolean): number;
52 | writeInt32BE(value: number, offset?: number, noAssert?: boolean): number;
53 | writeBigInt64LE(value: bigint, offset?: number): number;
54 | writeBigInt64BE(value: bigint, offset?: number): number;
55 | writeFloatLE(value: number, offset?: number, noAssert?: boolean): number;
56 | writeFloatBE(value: number, offset?: number, noAssert?: boolean): number;
57 | writeDoubleLE(value: number, offset?: number, noAssert?: boolean): number;
58 | writeDoubleBE(value: number, offset?: number, noAssert?: boolean): number;
59 | fill(value: any, offset?: number, end?: number): this;
60 | indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
61 | lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
62 | includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean;
63 |
64 | /**
65 | * Allocates a new buffer containing the given {str}.
66 | *
67 | * @param str String to store in buffer.
68 | * @param encoding encoding to use, optional. Default is 'utf8'
69 | */
70 | constructor (str: string, encoding?: string);
71 | /**
72 | * Allocates a new buffer of {size} octets.
73 | *
74 | * @param size count of octets to allocate.
75 | */
76 | constructor (size: number);
77 | /**
78 | * Allocates a new buffer containing the given {array} of octets.
79 | *
80 | * @param array The octets to store.
81 | */
82 | constructor (array: Uint8Array);
83 | /**
84 | * Produces a Buffer backed by the same allocated memory as
85 | * the given {ArrayBuffer}.
86 | *
87 | *
88 | * @param arrayBuffer The ArrayBuffer with which to share memory.
89 | */
90 | constructor (arrayBuffer: ArrayBuffer);
91 | /**
92 | * Allocates a new buffer containing the given {array} of octets.
93 | *
94 | * @param array The octets to store.
95 | */
96 | constructor (array: any[]);
97 | /**
98 | * Copies the passed {buffer} data onto a new {Buffer} instance.
99 | *
100 | * @param buffer The buffer to copy.
101 | */
102 | constructor (buffer: Buffer);
103 | prototype: Buffer;
104 | /**
105 | * Allocates a new Buffer using an {array} of octets.
106 | *
107 | * @param array
108 | */
109 | static from(array: any[]): Buffer;
110 | /**
111 | * When passed a reference to the .buffer property of a TypedArray instance,
112 | * the newly created Buffer will share the same allocated memory as the TypedArray.
113 | * The optional {byteOffset} and {length} arguments specify a memory range
114 | * within the {arrayBuffer} that will be shared by the Buffer.
115 | *
116 | * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer()
117 | * @param byteOffset
118 | * @param length
119 | */
120 | static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer;
121 | /**
122 | * Copies the passed {buffer} data onto a new Buffer instance.
123 | *
124 | * @param buffer
125 | */
126 | static from(buffer: Buffer | Uint8Array): Buffer;
127 | /**
128 | * Creates a new Buffer containing the given JavaScript string {str}.
129 | * If provided, the {encoding} parameter identifies the character encoding.
130 | * If not provided, {encoding} defaults to 'utf8'.
131 | *
132 | * @param str
133 | */
134 | static from(str: string, encoding?: string): Buffer;
135 | /**
136 | * Returns true if {obj} is a Buffer
137 | *
138 | * @param obj object to test.
139 | */
140 | static isBuffer(obj: any): obj is Buffer;
141 | /**
142 | * Returns true if {encoding} is a valid encoding argument.
143 | * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex'
144 | *
145 | * @param encoding string to test.
146 | */
147 | static isEncoding(encoding: string): boolean;
148 | /**
149 | * Gives the actual byte length of a string. encoding defaults to 'utf8'.
150 | * This is not the same as String.prototype.length since that returns the number of characters in a string.
151 | *
152 | * @param string string to test.
153 | * @param encoding encoding used to evaluate (defaults to 'utf8')
154 | */
155 | static byteLength(string: string, encoding?: string): number;
156 | /**
157 | * Returns a buffer which is the result of concatenating all the buffers in the list together.
158 | *
159 | * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.
160 | * If the list has exactly one item, then the first item of the list is returned.
161 | * If the list has more than one item, then a new Buffer is created.
162 | *
163 | * @param list An array of Buffer objects to concatenate
164 | * @param totalLength Total length of the buffers when concatenated.
165 | * 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.
166 | */
167 | static concat(list: Uint8Array[], totalLength?: number): Buffer;
168 | /**
169 | * The same as buf1.compare(buf2).
170 | */
171 | static compare(buf1: Uint8Array, buf2: Uint8Array): number;
172 | /**
173 | * Allocates a new buffer of {size} octets.
174 | *
175 | * @param size count of octets to allocate.
176 | * @param fill if specified, buffer will be initialized by calling buf.fill(fill).
177 | * If parameter is omitted, buffer will be filled with zeros.
178 | * @param encoding encoding used for call to buf.fill while initializing
179 | */
180 | static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer;
181 | /**
182 | * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents
183 | * of the newly created Buffer are unknown and may contain sensitive data.
184 | *
185 | * @param size count of octets to allocate
186 | */
187 | static allocUnsafe(size: number): Buffer;
188 | /**
189 | * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents
190 | * of the newly created Buffer are unknown and may contain sensitive data.
191 | *
192 | * @param size count of octets to allocate
193 | */
194 | static allocUnsafeSlow(size: number): Buffer;
195 | }
196 |
--------------------------------------------------------------------------------
/test/node/test-buffer-includes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 |
5 | var assert = require('assert');
6 |
7 | var Buffer = require('../../').Buffer;
8 |
9 | var b = Buffer.from('abcdef');
10 | var buf_a = Buffer.from('a');
11 | var buf_bc = Buffer.from('bc');
12 | var buf_f = Buffer.from('f');
13 | var buf_z = Buffer.from('z');
14 | var buf_empty = Buffer.from('');
15 |
16 | assert(b.includes('a'));
17 | assert(!b.includes('a', 1));
18 | assert(!b.includes('a', -1));
19 | assert(!b.includes('a', -4));
20 | assert(b.includes('a', -b.length));
21 | assert(b.includes('a', NaN));
22 | assert(b.includes('a', -Infinity));
23 | assert(!b.includes('a', Infinity));
24 | assert(b.includes('bc'));
25 | assert(!b.includes('bc', 2));
26 | assert(!b.includes('bc', -1));
27 | assert(!b.includes('bc', -3));
28 | assert(b.includes('bc', -5));
29 | assert(b.includes('bc', NaN));
30 | assert(b.includes('bc', -Infinity));
31 | assert(!b.includes('bc', Infinity));
32 | assert(b.includes('f'), b.length - 1);
33 | assert(!b.includes('z'));
34 | assert(!b.includes(''));
35 | assert(!b.includes('', 1));
36 | assert(!b.includes('', b.length + 1));
37 | assert(!b.includes('', Infinity));
38 | assert(b.includes(buf_a));
39 | assert(!b.includes(buf_a, 1));
40 | assert(!b.includes(buf_a, -1));
41 | assert(!b.includes(buf_a, -4));
42 | assert(b.includes(buf_a, -b.length));
43 | assert(b.includes(buf_a, NaN));
44 | assert(b.includes(buf_a, -Infinity));
45 | assert(!b.includes(buf_a, Infinity));
46 | assert(b.includes(buf_bc));
47 | assert(!b.includes(buf_bc, 2));
48 | assert(!b.includes(buf_bc, -1));
49 | assert(!b.includes(buf_bc, -3));
50 | assert(b.includes(buf_bc, -5));
51 | assert(b.includes(buf_bc, NaN));
52 | assert(b.includes(buf_bc, -Infinity));
53 | assert(!b.includes(buf_bc, Infinity));
54 | assert(b.includes(buf_f), b.length - 1);
55 | assert(!b.includes(buf_z));
56 | assert(!b.includes(buf_empty));
57 | assert(!b.includes(buf_empty, 1));
58 | assert(!b.includes(buf_empty, b.length + 1));
59 | assert(!b.includes(buf_empty, Infinity));
60 | assert(b.includes(0x61));
61 | assert(!b.includes(0x61, 1));
62 | assert(!b.includes(0x61, -1));
63 | assert(!b.includes(0x61, -4));
64 | assert(b.includes(0x61, -b.length));
65 | assert(b.includes(0x61, NaN));
66 | assert(b.includes(0x61, -Infinity));
67 | assert(!b.includes(0x61, Infinity));
68 | assert(!b.includes(0x0));
69 |
70 | // test offsets
71 | assert(b.includes('d', 2));
72 | assert(b.includes('f', 5));
73 | assert(b.includes('f', -1));
74 | assert(!b.includes('f', 6));
75 |
76 | assert(b.includes(Buffer.from('d'), 2));
77 | assert(b.includes(Buffer.from('f'), 5));
78 | assert(b.includes(Buffer.from('f'), -1));
79 | assert(!b.includes(Buffer.from('f'), 6));
80 |
81 | assert(!Buffer.from('ff').includes(Buffer.from('f'), 1, 'ucs2'));
82 |
83 | // test hex encoding
84 | assert.strictEqual(
85 | Buffer.from(b.toString('hex'), 'hex')
86 | .includes('64', 0, 'hex'),
87 | true
88 | );
89 | assert.strictEqual(
90 | Buffer.from(b.toString('hex'), 'hex')
91 | .includes(Buffer.from('64', 'hex'), 0, 'hex'),
92 | true
93 | );
94 |
95 | // test base64 encoding
96 | assert.strictEqual(
97 | Buffer.from(b.toString('base64'), 'base64')
98 | .includes('ZA==', 0, 'base64'),
99 | true
100 | );
101 | assert.strictEqual(
102 | Buffer.from(b.toString('base64'), 'base64')
103 | .includes(Buffer.from('ZA==', 'base64'), 0, 'base64'),
104 | true
105 | );
106 |
107 | // test ascii encoding
108 | assert.strictEqual(
109 | Buffer.from(b.toString('ascii'), 'ascii')
110 | .includes('d', 0, 'ascii'),
111 | true
112 | );
113 | assert.strictEqual(
114 | Buffer.from(b.toString('ascii'), 'ascii')
115 | .includes(Buffer.from('d', 'ascii'), 0, 'ascii'),
116 | true
117 | );
118 |
119 | // test latin1 encoding
120 | assert.strictEqual(
121 | Buffer.from(b.toString('latin1'), 'latin1')
122 | .includes('d', 0, 'latin1'),
123 | true
124 | );
125 | assert.strictEqual(
126 | Buffer.from(b.toString('latin1'), 'latin1')
127 | .includes(Buffer.from('d', 'latin1'), 0, 'latin1'),
128 | true
129 | );
130 |
131 | // test binary encoding
132 | assert.strictEqual(
133 | Buffer.from(b.toString('binary'), 'binary')
134 | .includes('d', 0, 'binary'),
135 | true
136 | );
137 | assert.strictEqual(
138 | Buffer.from(b.toString('binary'), 'binary')
139 | .includes(Buffer.from('d', 'binary'), 0, 'binary'),
140 | true
141 | );
142 |
143 |
144 | // test usc2 encoding
145 | var twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
146 |
147 | assert(twoByteString.includes('\u0395', 4, 'ucs2'));
148 | assert(twoByteString.includes('\u03a3', -4, 'ucs2'));
149 | assert(twoByteString.includes('\u03a3', -6, 'ucs2'));
150 | assert(twoByteString.includes(
151 | Buffer.from('\u03a3', 'ucs2'), -6, 'ucs2'));
152 | assert(!twoByteString.includes('\u03a3', -2, 'ucs2'));
153 |
154 | var mixedByteStringUcs2 =
155 | Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395', 'ucs2');
156 | assert(mixedByteStringUcs2.includes('bc', 0, 'ucs2'));
157 | assert(mixedByteStringUcs2.includes('\u03a3', 0, 'ucs2'));
158 | assert(!mixedByteStringUcs2.includes('\u0396', 0, 'ucs2'));
159 |
160 | assert(
161 | 6, mixedByteStringUcs2.includes(Buffer.from('bc', 'ucs2'), 0, 'ucs2'));
162 | assert(
163 | 10, mixedByteStringUcs2.includes(Buffer.from('\u03a3', 'ucs2'),
164 | 0, 'ucs2'));
165 | assert(
166 | -1, mixedByteStringUcs2.includes(Buffer.from('\u0396', 'ucs2'),
167 | 0, 'ucs2'));
168 |
169 | twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
170 |
171 | // Test single char pattern
172 | assert(twoByteString.includes('\u039a', 0, 'ucs2'));
173 | assert(twoByteString.includes('\u0391', 0, 'ucs2'), 'Alpha');
174 | assert(twoByteString.includes('\u03a3', 0, 'ucs2'), 'First Sigma');
175 | assert(twoByteString.includes('\u03a3', 6, 'ucs2'), 'Second Sigma');
176 | assert(twoByteString.includes('\u0395', 0, 'ucs2'), 'Epsilon');
177 | assert(!twoByteString.includes('\u0392', 0, 'ucs2'), 'Not beta');
178 |
179 | // Test multi-char pattern
180 | assert(twoByteString.includes('\u039a\u0391', 0, 'ucs2'), 'Lambda Alpha');
181 | assert(twoByteString.includes('\u0391\u03a3', 0, 'ucs2'), 'Alpha Sigma');
182 | assert(twoByteString.includes('\u03a3\u03a3', 0, 'ucs2'), 'Sigma Sigma');
183 | assert(twoByteString.includes('\u03a3\u0395', 0, 'ucs2'), 'Sigma Epsilon');
184 |
185 | var mixedByteStringUtf8 = Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395');
186 | assert(mixedByteStringUtf8.includes('bc'));
187 | assert(mixedByteStringUtf8.includes('bc', 5));
188 | assert(mixedByteStringUtf8.includes('bc', -8));
189 | assert(mixedByteStringUtf8.includes('\u03a3'));
190 | assert(!mixedByteStringUtf8.includes('\u0396'));
191 |
192 |
193 | // Test complex string includes algorithms. Only trigger for long strings.
194 | // Long string that isn't a simple repeat of a shorter string.
195 | var longString = 'A';
196 | for (var i = 66; i < 76; i++) { // from 'B' to 'K'
197 | longString = longString + String.fromCharCode(i) + longString;
198 | }
199 |
200 | var longBufferString = Buffer.from(longString);
201 |
202 | // pattern of 15 chars, repeated every 16 chars in long
203 | var pattern = 'ABACABADABACABA';
204 | for (var i = 0; i < longBufferString.length - pattern.length; i += 7) {
205 | var includes = longBufferString.includes(pattern, i);
206 | assert(includes, 'Long ABACABA...-string at index ' + i);
207 | }
208 | assert(longBufferString.includes('AJABACA'), 'Long AJABACA, First J');
209 | assert(longBufferString.includes('AJABACA', 511), 'Long AJABACA, Second J');
210 |
211 | pattern = 'JABACABADABACABA';
212 | assert(longBufferString.includes(pattern), 'Long JABACABA..., First J');
213 | assert(longBufferString.includes(pattern, 512), 'Long JABACABA..., Second J');
214 |
215 | // Search for a non-ASCII string in a pure ASCII string.
216 | var asciiString = Buffer.from(
217 | 'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf');
218 | assert(!asciiString.includes('\x2061'));
219 | assert(asciiString.includes('leb', 0));
220 |
221 | // Search in string containing many non-ASCII chars.
222 | var allCodePoints = [];
223 | for (var i = 0; i < 65536; i++) allCodePoints[i] = i;
224 | var allCharsString = String.fromCharCode.apply(String, allCodePoints);
225 | var allCharsBufferUtf8 = Buffer.from(allCharsString);
226 | var allCharsBufferUcs2 = Buffer.from(allCharsString, 'ucs2');
227 |
228 | // Search for string long enough to trigger complex search with ASCII pattern
229 | // and UC16 subject.
230 | assert(!allCharsBufferUtf8.includes('notfound'));
231 | assert(!allCharsBufferUcs2.includes('notfound'));
232 |
233 | // Find substrings in Utf8.
234 | var lengths = [1, 3, 15]; // Single char, simple and complex.
235 | var indices = [0x5, 0x60, 0x400, 0x680, 0x7ee, 0xFF02, 0x16610, 0x2f77b];
236 | for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
237 | for (var i = 0; i < indices.length; i++) {
238 | var index = indices[i];
239 | var length = lengths[lengthIndex];
240 |
241 | if (index + length > 0x7F) {
242 | length = 2 * length;
243 | }
244 |
245 | if (index + length > 0x7FF) {
246 | length = 3 * length;
247 | }
248 |
249 | if (index + length > 0xFFFF) {
250 | length = 4 * length;
251 | }
252 |
253 | var patternBufferUtf8 = allCharsBufferUtf8.slice(index, index + length);
254 | assert(index, allCharsBufferUtf8.includes(patternBufferUtf8));
255 |
256 | var patternStringUtf8 = patternBufferUtf8.toString();
257 | assert(index, allCharsBufferUtf8.includes(patternStringUtf8));
258 | }
259 | }
260 |
261 | // Find substrings in Usc2.
262 | lengths = [2, 4, 16]; // Single char, simple and complex.
263 | indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0];
264 | for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
265 | for (var i = 0; i < indices.length; i++) {
266 | var index = indices[i] * 2;
267 | var length = lengths[lengthIndex];
268 |
269 | var patternBufferUcs2 =
270 | allCharsBufferUcs2.slice(index, index + length);
271 | assert(
272 | index, allCharsBufferUcs2.includes(patternBufferUcs2, 0, 'ucs2'));
273 |
274 | var patternStringUcs2 = patternBufferUcs2.toString('ucs2');
275 | assert(
276 | index, allCharsBufferUcs2.includes(patternStringUcs2, 0, 'ucs2'));
277 | }
278 | }
279 |
280 | assert.throws(function() {
281 | b.includes(function() { });
282 | });
283 | assert.throws(function() {
284 | b.includes({});
285 | });
286 | assert.throws(function() {
287 | b.includes([]);
288 | });
289 |
290 | // test truncation of Number arguments to uint8
291 | {
292 | var buf = Buffer.from('this is a test');
293 | assert.ok(buf.includes(0x6973));
294 | assert.ok(buf.includes(0x697320));
295 | assert.ok(buf.includes(0x69732069));
296 | assert.ok(buf.includes(0x697374657374));
297 | assert.ok(buf.includes(0x69737374));
298 | assert.ok(buf.includes(0x69737465));
299 | assert.ok(buf.includes(0x69737465));
300 | assert.ok(buf.includes(-140));
301 | assert.ok(buf.includes(-152));
302 | assert.ok(!buf.includes(0xff));
303 | assert.ok(!buf.includes(0xffff));
304 | }
305 |
306 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # buffer [![ci][ci-image]][ci-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]
2 |
3 | [ci-image]: https://img.shields.io/github/workflow/status/feross/buffer/ci/master
4 | [ci-url]: https://github.com/feross/buffer/actions
5 | [npm-image]: https://img.shields.io/npm/v/buffer.svg
6 | [npm-url]: https://npmjs.org/package/buffer
7 | [downloads-image]: https://img.shields.io/npm/dm/buffer.svg
8 | [downloads-url]: https://npmjs.org/package/buffer
9 | [standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
10 | [standard-url]: https://standardjs.com
11 |
12 | #### The buffer module from [node.js](https://nodejs.org), for the browser.
13 |
14 | [![saucelabs][saucelabs-image]][saucelabs-url]
15 |
16 | [saucelabs-image]: https://saucelabs.com/browser-matrix/buffer.svg
17 | [saucelabs-url]: https://saucelabs.com/u/buffer
18 |
19 | With [browserify](http://browserify.org), simply `require('buffer')` or use the `Buffer` global and you will get this module.
20 |
21 | The goal is to provide an API that is 100% identical to
22 | [node's Buffer API](https://nodejs.org/api/buffer.html). Read the
23 | [official docs](https://nodejs.org/api/buffer.html) for the full list of properties,
24 | instance methods, and class methods that are supported.
25 |
26 | ## features
27 |
28 | - Manipulate binary data like a boss, in all browsers!
29 | - Super fast. Backed by Typed Arrays (`Uint8Array`/`ArrayBuffer`, not `Object`)
30 | - Extremely small bundle size (**6.75KB minified + gzipped**, 51.9KB with comments)
31 | - Excellent browser support (Chrome, Firefox, Edge, Safari 11+, iOS 11+, Android, etc.)
32 | - Preserves Node API exactly
33 | - Square-bracket `buf[4]` notation works!
34 | - Does not modify any browser prototypes or put anything on `window`
35 | - Comprehensive test suite (including all buffer tests from node.js core)
36 |
37 | ## install
38 |
39 | To use this module directly (without browserify), install it:
40 |
41 | ```bash
42 | npm install buffer
43 | ```
44 |
45 | This module was previously called **native-buffer-browserify**, but please use **buffer**
46 | from now on.
47 |
48 | If you do not use a bundler, you can use the [standalone script](https://bundle.run/buffer).
49 |
50 | ## usage
51 |
52 | The module's API is identical to node's `Buffer` API. Read the
53 | [official docs](https://nodejs.org/api/buffer.html) for the full list of properties,
54 | instance methods, and class methods that are supported.
55 |
56 | As mentioned above, `require('buffer')` or use the `Buffer` global with
57 | [browserify](http://browserify.org) and this module will automatically be included
58 | in your bundle. Almost any npm module will work in the browser, even if it assumes that
59 | the node `Buffer` API will be available.
60 |
61 | To depend on this module explicitly (without browserify), require it like this:
62 |
63 | ```js
64 | var Buffer = require('buffer/').Buffer // note: the trailing slash is important!
65 | ```
66 |
67 | To require this module explicitly, use `require('buffer/')` which tells the node.js module
68 | lookup algorithm (also used by browserify) to use the **npm module** named `buffer`
69 | instead of the **node.js core** module named `buffer`!
70 |
71 |
72 | ## how does it work?
73 |
74 | The Buffer constructor returns instances of `Uint8Array` that have their prototype
75 | changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of `Uint8Array`,
76 | so the returned instances will have all the node `Buffer` methods and the
77 | `Uint8Array` methods. Square bracket notation works as expected -- it returns a
78 | single octet.
79 |
80 | The `Uint8Array` prototype remains unmodified.
81 |
82 |
83 | ## tracking the latest node api
84 |
85 | This module tracks the Buffer API in the latest (unstable) version of node.js. The Buffer
86 | API is considered **stable** in the
87 | [node stability index](https://nodejs.org/docs/latest/api/documentation.html#documentation_stability_index),
88 | so it is unlikely that there will ever be breaking changes.
89 | Nonetheless, when/if the Buffer API changes in node, this module's API will change
90 | accordingly.
91 |
92 | ## related packages
93 |
94 | - [`buffer-reverse`](https://www.npmjs.com/package/buffer-reverse) - Reverse a buffer
95 | - [`buffer-xor`](https://www.npmjs.com/package/buffer-xor) - Bitwise xor a buffer
96 | - [`is-buffer`](https://www.npmjs.com/package/is-buffer) - Determine if an object is a Buffer without including the whole `Buffer` package
97 |
98 | ## conversion packages
99 |
100 | ### convert typed array to buffer
101 |
102 | Use [`typedarray-to-buffer`](https://www.npmjs.com/package/typedarray-to-buffer) to convert any kind of typed array to a `Buffer`. Does not perform a copy, so it's super fast.
103 |
104 | ### convert buffer to typed array
105 |
106 | `Buffer` is a subclass of `Uint8Array` (which is a typed array). So there is no need to explicitly convert to typed array. Just use the buffer as a `Uint8Array`.
107 |
108 | ### convert blob to buffer
109 |
110 | Use [`blob-to-buffer`](https://www.npmjs.com/package/blob-to-buffer) to convert a `Blob` to a `Buffer`.
111 |
112 | ### convert buffer to blob
113 |
114 | To convert a `Buffer` to a `Blob`, use the `Blob` constructor:
115 |
116 | ```js
117 | var blob = new Blob([ buffer ])
118 | ```
119 |
120 | Optionally, specify a mimetype:
121 |
122 | ```js
123 | var blob = new Blob([ buffer ], { type: 'text/html' })
124 | ```
125 |
126 | ### convert arraybuffer to buffer
127 |
128 | To convert an `ArrayBuffer` to a `Buffer`, use the `Buffer.from` function. Does not perform a copy, so it's super fast.
129 |
130 | ```js
131 | var buffer = Buffer.from(arrayBuffer)
132 | ```
133 |
134 | ### convert buffer to arraybuffer
135 |
136 | To convert a `Buffer` to an `ArrayBuffer`, use the `.buffer` property (which is present on all `Uint8Array` objects):
137 |
138 | ```js
139 | var arrayBuffer = buffer.buffer.slice(
140 | buffer.byteOffset, buffer.byteOffset + buffer.byteLength
141 | )
142 | ```
143 |
144 | Alternatively, use the [`to-arraybuffer`](https://www.npmjs.com/package/to-arraybuffer) module.
145 |
146 | ## performance
147 |
148 | See perf tests in `/perf`.
149 |
150 | `BrowserBuffer` is the browser `buffer` module (this repo). `Uint8Array` is included as an
151 | additional check (since `BrowserBuffer` uses `Uint8Array` under the hood, `Uint8Array` will
152 | always be at least a bit faster). Finally, `NodeBuffer` is the node.js buffer module,
153 | which is included to compare against.
154 |
155 | NOTE: Performance has improved since these benchmarks were taken. PR welcome to update the README.
156 |
157 | ### Chrome 38
158 |
159 | | Method | Operations | Accuracy | Sampled | Fastest |
160 | |:-------|:-----------|:---------|:--------|:-------:|
161 | | BrowserBuffer#bracket-notation | 11,457,464 ops/sec | ±0.86% | 66 | ✓ |
162 | | Uint8Array#bracket-notation | 10,824,332 ops/sec | ±0.74% | 65 | |
163 | | | | | |
164 | | BrowserBuffer#concat | 450,532 ops/sec | ±0.76% | 68 | |
165 | | Uint8Array#concat | 1,368,911 ops/sec | ±1.50% | 62 | ✓ |
166 | | | | | |
167 | | BrowserBuffer#copy(16000) | 903,001 ops/sec | ±0.96% | 67 | |
168 | | Uint8Array#copy(16000) | 1,422,441 ops/sec | ±1.04% | 66 | ✓ |
169 | | | | | |
170 | | BrowserBuffer#copy(16) | 11,431,358 ops/sec | ±0.46% | 69 | |
171 | | Uint8Array#copy(16) | 13,944,163 ops/sec | ±1.12% | 68 | ✓ |
172 | | | | | |
173 | | BrowserBuffer#new(16000) | 106,329 ops/sec | ±6.70% | 44 | |
174 | | Uint8Array#new(16000) | 131,001 ops/sec | ±2.85% | 31 | ✓ |
175 | | | | | |
176 | | BrowserBuffer#new(16) | 1,554,491 ops/sec | ±1.60% | 65 | |
177 | | Uint8Array#new(16) | 6,623,930 ops/sec | ±1.66% | 65 | ✓ |
178 | | | | | |
179 | | BrowserBuffer#readDoubleBE | 112,830 ops/sec | ±0.51% | 69 | ✓ |
180 | | DataView#getFloat64 | 93,500 ops/sec | ±0.57% | 68 | |
181 | | | | | |
182 | | BrowserBuffer#readFloatBE | 146,678 ops/sec | ±0.95% | 68 | ✓ |
183 | | DataView#getFloat32 | 99,311 ops/sec | ±0.41% | 67 | |
184 | | | | | |
185 | | BrowserBuffer#readUInt32LE | 843,214 ops/sec | ±0.70% | 69 | ✓ |
186 | | DataView#getUint32 | 103,024 ops/sec | ±0.64% | 67 | |
187 | | | | | |
188 | | BrowserBuffer#slice | 1,013,941 ops/sec | ±0.75% | 67 | |
189 | | Uint8Array#subarray | 1,903,928 ops/sec | ±0.53% | 67 | ✓ |
190 | | | | | |
191 | | BrowserBuffer#writeFloatBE | 61,387 ops/sec | ±0.90% | 67 | |
192 | | DataView#setFloat32 | 141,249 ops/sec | ±0.40% | 66 | ✓ |
193 |
194 |
195 | ### Firefox 33
196 |
197 | | Method | Operations | Accuracy | Sampled | Fastest |
198 | |:-------|:-----------|:---------|:--------|:-------:|
199 | | BrowserBuffer#bracket-notation | 20,800,421 ops/sec | ±1.84% | 60 | |
200 | | Uint8Array#bracket-notation | 20,826,235 ops/sec | ±2.02% | 61 | ✓ |
201 | | | | | |
202 | | BrowserBuffer#concat | 153,076 ops/sec | ±2.32% | 61 | |
203 | | Uint8Array#concat | 1,255,674 ops/sec | ±8.65% | 52 | ✓ |
204 | | | | | |
205 | | BrowserBuffer#copy(16000) | 1,105,312 ops/sec | ±1.16% | 63 | |
206 | | Uint8Array#copy(16000) | 1,615,911 ops/sec | ±0.55% | 66 | ✓ |
207 | | | | | |
208 | | BrowserBuffer#copy(16) | 16,357,599 ops/sec | ±0.73% | 68 | |
209 | | Uint8Array#copy(16) | 31,436,281 ops/sec | ±1.05% | 68 | ✓ |
210 | | | | | |
211 | | BrowserBuffer#new(16000) | 52,995 ops/sec | ±6.01% | 35 | |
212 | | Uint8Array#new(16000) | 87,686 ops/sec | ±5.68% | 45 | ✓ |
213 | | | | | |
214 | | BrowserBuffer#new(16) | 252,031 ops/sec | ±1.61% | 66 | |
215 | | Uint8Array#new(16) | 8,477,026 ops/sec | ±0.49% | 68 | ✓ |
216 | | | | | |
217 | | BrowserBuffer#readDoubleBE | 99,871 ops/sec | ±0.41% | 69 | |
218 | | DataView#getFloat64 | 285,663 ops/sec | ±0.70% | 68 | ✓ |
219 | | | | | |
220 | | BrowserBuffer#readFloatBE | 115,540 ops/sec | ±0.42% | 69 | |
221 | | DataView#getFloat32 | 288,722 ops/sec | ±0.82% | 68 | ✓ |
222 | | | | | |
223 | | BrowserBuffer#readUInt32LE | 633,926 ops/sec | ±1.08% | 67 | ✓ |
224 | | DataView#getUint32 | 294,808 ops/sec | ±0.79% | 64 | |
225 | | | | | |
226 | | BrowserBuffer#slice | 349,425 ops/sec | ±0.46% | 69 | |
227 | | Uint8Array#subarray | 5,965,819 ops/sec | ±0.60% | 65 | ✓ |
228 | | | | | |
229 | | BrowserBuffer#writeFloatBE | 59,980 ops/sec | ±0.41% | 67 | |
230 | | DataView#setFloat32 | 317,634 ops/sec | ±0.63% | 68 | ✓ |
231 |
232 | ### Safari 8
233 |
234 | | Method | Operations | Accuracy | Sampled | Fastest |
235 | |:-------|:-----------|:---------|:--------|:-------:|
236 | | BrowserBuffer#bracket-notation | 10,279,729 ops/sec | ±2.25% | 56 | ✓ |
237 | | Uint8Array#bracket-notation | 10,030,767 ops/sec | ±2.23% | 59 | |
238 | | | | | |
239 | | BrowserBuffer#concat | 144,138 ops/sec | ±1.38% | 65 | |
240 | | Uint8Array#concat | 4,950,764 ops/sec | ±1.70% | 63 | ✓ |
241 | | | | | |
242 | | BrowserBuffer#copy(16000) | 1,058,548 ops/sec | ±1.51% | 64 | |
243 | | Uint8Array#copy(16000) | 1,409,666 ops/sec | ±1.17% | 65 | ✓ |
244 | | | | | |
245 | | BrowserBuffer#copy(16) | 6,282,529 ops/sec | ±1.88% | 58 | |
246 | | Uint8Array#copy(16) | 11,907,128 ops/sec | ±2.87% | 58 | ✓ |
247 | | | | | |
248 | | BrowserBuffer#new(16000) | 101,663 ops/sec | ±3.89% | 57 | |
249 | | Uint8Array#new(16000) | 22,050,818 ops/sec | ±6.51% | 46 | ✓ |
250 | | | | | |
251 | | BrowserBuffer#new(16) | 176,072 ops/sec | ±2.13% | 64 | |
252 | | Uint8Array#new(16) | 24,385,731 ops/sec | ±5.01% | 51 | ✓ |
253 | | | | | |
254 | | BrowserBuffer#readDoubleBE | 41,341 ops/sec | ±1.06% | 67 | |
255 | | DataView#getFloat64 | 322,280 ops/sec | ±0.84% | 68 | ✓ |
256 | | | | | |
257 | | BrowserBuffer#readFloatBE | 46,141 ops/sec | ±1.06% | 65 | |
258 | | DataView#getFloat32 | 337,025 ops/sec | ±0.43% | 69 | ✓ |
259 | | | | | |
260 | | BrowserBuffer#readUInt32LE | 151,551 ops/sec | ±1.02% | 66 | |
261 | | DataView#getUint32 | 308,278 ops/sec | ±0.94% | 67 | ✓ |
262 | | | | | |
263 | | BrowserBuffer#slice | 197,365 ops/sec | ±0.95% | 66 | |
264 | | Uint8Array#subarray | 9,558,024 ops/sec | ±3.08% | 58 | ✓ |
265 | | | | | |
266 | | BrowserBuffer#writeFloatBE | 17,518 ops/sec | ±1.03% | 63 | |
267 | | DataView#setFloat32 | 319,751 ops/sec | ±0.48% | 68 | ✓ |
268 |
269 |
270 | ### Node 0.11.14
271 |
272 | | Method | Operations | Accuracy | Sampled | Fastest |
273 | |:-------|:-----------|:---------|:--------|:-------:|
274 | | BrowserBuffer#bracket-notation | 10,489,828 ops/sec | ±3.25% | 90 | |
275 | | Uint8Array#bracket-notation | 10,534,884 ops/sec | ±0.81% | 92 | ✓ |
276 | | NodeBuffer#bracket-notation | 10,389,910 ops/sec | ±0.97% | 87 | |
277 | | | | | |
278 | | BrowserBuffer#concat | 487,830 ops/sec | ±2.58% | 88 | |
279 | | Uint8Array#concat | 1,814,327 ops/sec | ±1.28% | 88 | ✓ |
280 | | NodeBuffer#concat | 1,636,523 ops/sec | ±1.88% | 73 | |
281 | | | | | |
282 | | BrowserBuffer#copy(16000) | 1,073,665 ops/sec | ±0.77% | 90 | |
283 | | Uint8Array#copy(16000) | 1,348,517 ops/sec | ±0.84% | 89 | ✓ |
284 | | NodeBuffer#copy(16000) | 1,289,533 ops/sec | ±0.82% | 93 | |
285 | | | | | |
286 | | BrowserBuffer#copy(16) | 12,782,706 ops/sec | ±0.74% | 85 | |
287 | | Uint8Array#copy(16) | 14,180,427 ops/sec | ±0.93% | 92 | ✓ |
288 | | NodeBuffer#copy(16) | 11,083,134 ops/sec | ±1.06% | 89 | |
289 | | | | | |
290 | | BrowserBuffer#new(16000) | 141,678 ops/sec | ±3.30% | 67 | |
291 | | Uint8Array#new(16000) | 161,491 ops/sec | ±2.96% | 60 | |
292 | | NodeBuffer#new(16000) | 292,699 ops/sec | ±3.20% | 55 | ✓ |
293 | | | | | |
294 | | BrowserBuffer#new(16) | 1,655,466 ops/sec | ±2.41% | 82 | |
295 | | Uint8Array#new(16) | 14,399,926 ops/sec | ±0.91% | 94 | ✓ |
296 | | NodeBuffer#new(16) | 3,894,696 ops/sec | ±0.88% | 92 | |
297 | | | | | |
298 | | BrowserBuffer#readDoubleBE | 109,582 ops/sec | ±0.75% | 93 | ✓ |
299 | | DataView#getFloat64 | 91,235 ops/sec | ±0.81% | 90 | |
300 | | NodeBuffer#readDoubleBE | 88,593 ops/sec | ±0.96% | 81 | |
301 | | | | | |
302 | | BrowserBuffer#readFloatBE | 139,854 ops/sec | ±1.03% | 85 | ✓ |
303 | | DataView#getFloat32 | 98,744 ops/sec | ±0.80% | 89 | |
304 | | NodeBuffer#readFloatBE | 92,769 ops/sec | ±0.94% | 93 | |
305 | | | | | |
306 | | BrowserBuffer#readUInt32LE | 710,861 ops/sec | ±0.82% | 92 | |
307 | | DataView#getUint32 | 117,893 ops/sec | ±0.84% | 91 | |
308 | | NodeBuffer#readUInt32LE | 851,412 ops/sec | ±0.72% | 93 | ✓ |
309 | | | | | |
310 | | BrowserBuffer#slice | 1,673,877 ops/sec | ±0.73% | 94 | |
311 | | Uint8Array#subarray | 6,919,243 ops/sec | ±0.67% | 90 | ✓ |
312 | | NodeBuffer#slice | 4,617,604 ops/sec | ±0.79% | 93 | |
313 | | | | | |
314 | | BrowserBuffer#writeFloatBE | 66,011 ops/sec | ±0.75% | 93 | |
315 | | DataView#setFloat32 | 127,760 ops/sec | ±0.72% | 93 | ✓ |
316 | | NodeBuffer#writeFloatBE | 103,352 ops/sec | ±0.83% | 93 | |
317 |
318 | ### iojs 1.8.1
319 |
320 | | Method | Operations | Accuracy | Sampled | Fastest |
321 | |:-------|:-----------|:---------|:--------|:-------:|
322 | | BrowserBuffer#bracket-notation | 10,990,488 ops/sec | ±1.11% | 91 | |
323 | | Uint8Array#bracket-notation | 11,268,757 ops/sec | ±0.65% | 97 | |
324 | | NodeBuffer#bracket-notation | 11,353,260 ops/sec | ±0.83% | 94 | ✓ |
325 | | | | | |
326 | | BrowserBuffer#concat | 378,954 ops/sec | ±0.74% | 94 | |
327 | | Uint8Array#concat | 1,358,288 ops/sec | ±0.97% | 87 | |
328 | | NodeBuffer#concat | 1,934,050 ops/sec | ±1.11% | 78 | ✓ |
329 | | | | | |
330 | | BrowserBuffer#copy(16000) | 894,538 ops/sec | ±0.56% | 84 | |
331 | | Uint8Array#copy(16000) | 1,442,656 ops/sec | ±0.71% | 96 | |
332 | | NodeBuffer#copy(16000) | 1,457,898 ops/sec | ±0.53% | 92 | ✓ |
333 | | | | | |
334 | | BrowserBuffer#copy(16) | 12,870,457 ops/sec | ±0.67% | 95 | |
335 | | Uint8Array#copy(16) | 16,643,989 ops/sec | ±0.61% | 93 | ✓ |
336 | | NodeBuffer#copy(16) | 14,885,848 ops/sec | ±0.74% | 94 | |
337 | | | | | |
338 | | BrowserBuffer#new(16000) | 109,264 ops/sec | ±4.21% | 63 | |
339 | | Uint8Array#new(16000) | 138,916 ops/sec | ±1.87% | 61 | |
340 | | NodeBuffer#new(16000) | 281,449 ops/sec | ±3.58% | 51 | ✓ |
341 | | | | | |
342 | | BrowserBuffer#new(16) | 1,362,935 ops/sec | ±0.56% | 99 | |
343 | | Uint8Array#new(16) | 6,193,090 ops/sec | ±0.64% | 95 | ✓ |
344 | | NodeBuffer#new(16) | 4,745,425 ops/sec | ±1.56% | 90 | |
345 | | | | | |
346 | | BrowserBuffer#readDoubleBE | 118,127 ops/sec | ±0.59% | 93 | ✓ |
347 | | DataView#getFloat64 | 107,332 ops/sec | ±0.65% | 91 | |
348 | | NodeBuffer#readDoubleBE | 116,274 ops/sec | ±0.94% | 95 | |
349 | | | | | |
350 | | BrowserBuffer#readFloatBE | 150,326 ops/sec | ±0.58% | 95 | ✓ |
351 | | DataView#getFloat32 | 110,541 ops/sec | ±0.57% | 98 | |
352 | | NodeBuffer#readFloatBE | 121,599 ops/sec | ±0.60% | 87 | |
353 | | | | | |
354 | | BrowserBuffer#readUInt32LE | 814,147 ops/sec | ±0.62% | 93 | |
355 | | DataView#getUint32 | 137,592 ops/sec | ±0.64% | 90 | |
356 | | NodeBuffer#readUInt32LE | 931,650 ops/sec | ±0.71% | 96 | ✓ |
357 | | | | | |
358 | | BrowserBuffer#slice | 878,590 ops/sec | ±0.68% | 93 | |
359 | | Uint8Array#subarray | 2,843,308 ops/sec | ±1.02% | 90 | |
360 | | NodeBuffer#slice | 4,998,316 ops/sec | ±0.68% | 90 | ✓ |
361 | | | | | |
362 | | BrowserBuffer#writeFloatBE | 65,927 ops/sec | ±0.74% | 93 | |
363 | | DataView#setFloat32 | 139,823 ops/sec | ±0.97% | 89 | ✓ |
364 | | NodeBuffer#writeFloatBE | 135,763 ops/sec | ±0.65% | 96 | |
365 | | | | | |
366 |
367 | ## Testing the project
368 |
369 | First, install the project:
370 |
371 | npm install
372 |
373 | Then, to run tests in Node.js, run:
374 |
375 | npm run test-node
376 |
377 | To test locally in a browser, you can run:
378 |
379 | npm run test-browser-old-local # For ES5 browsers that don't support ES6
380 | npm run test-browser-new-local # For ES6 compliant browsers
381 |
382 | 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).
383 |
384 | To run automated browser tests using Saucelabs, ensure that your `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` environment variables are set, then run:
385 |
386 | npm test
387 |
388 | This is what's run in Travis, to check against various browsers. The list of browsers is kept in the `bin/airtap-es5.yml` and `bin/airtap-es6.yml` files.
389 |
390 | ## JavaScript Standard Style
391 |
392 | This module uses [JavaScript Standard Style](https://github.com/feross/standard).
393 |
394 | [](https://github.com/feross/standard)
395 |
396 | To test that the code conforms to the style, `npm install` and run:
397 |
398 | ./node_modules/.bin/standard
399 |
400 | ## credit
401 |
402 | This was originally forked from [buffer-browserify](https://github.com/toots/buffer-browserify).
403 |
404 | ## Security Policies and Procedures
405 |
406 | 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.
407 |
408 | ## license
409 |
410 | MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org), and other contributors. Originally forked from an MIT-licensed module by Romain Beauxis.
411 |
--------------------------------------------------------------------------------
/test/node/test-buffer-indexof.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Buffer = require('../../').Buffer;
3 |
4 |
5 | var assert = require('assert');
6 |
7 | var Buffer = require('../../').Buffer;
8 |
9 | var b = Buffer.from('abcdef');
10 | var buf_a = Buffer.from('a');
11 | var buf_bc = Buffer.from('bc');
12 | var buf_f = Buffer.from('f');
13 | var buf_z = Buffer.from('z');
14 | var buf_empty = Buffer.from('');
15 |
16 | assert.equal(b.indexOf('a'), 0);
17 | assert.equal(b.indexOf('a', 1), -1);
18 | assert.equal(b.indexOf('a', -1), -1);
19 | assert.equal(b.indexOf('a', -4), -1);
20 | assert.equal(b.indexOf('a', -b.length), 0);
21 | assert.equal(b.indexOf('a', NaN), 0);
22 | assert.equal(b.indexOf('a', -Infinity), 0);
23 | assert.equal(b.indexOf('a', Infinity), -1);
24 | assert.equal(b.indexOf('bc'), 1);
25 | assert.equal(b.indexOf('bc', 2), -1);
26 | assert.equal(b.indexOf('bc', -1), -1);
27 | assert.equal(b.indexOf('bc', -3), -1);
28 | assert.equal(b.indexOf('bc', -5), 1);
29 | assert.equal(b.indexOf('bc', NaN), 1);
30 | assert.equal(b.indexOf('bc', -Infinity), 1);
31 | assert.equal(b.indexOf('bc', Infinity), -1);
32 | assert.equal(b.indexOf('f'), b.length - 1);
33 | assert.equal(b.indexOf('z'), -1);
34 | assert.equal(b.indexOf(''), -1);
35 | assert.equal(b.indexOf('', 1), -1);
36 | assert.equal(b.indexOf('', b.length + 1), -1);
37 | assert.equal(b.indexOf('', Infinity), -1);
38 | assert.equal(b.indexOf(buf_a), 0);
39 | assert.equal(b.indexOf(buf_a, 1), -1);
40 | assert.equal(b.indexOf(buf_a, -1), -1);
41 | assert.equal(b.indexOf(buf_a, -4), -1);
42 | assert.equal(b.indexOf(buf_a, -b.length), 0);
43 | assert.equal(b.indexOf(buf_a, NaN), 0);
44 | assert.equal(b.indexOf(buf_a, -Infinity), 0);
45 | assert.equal(b.indexOf(buf_a, Infinity), -1);
46 | assert.equal(b.indexOf(buf_bc), 1);
47 | assert.equal(b.indexOf(buf_bc, 2), -1);
48 | assert.equal(b.indexOf(buf_bc, -1), -1);
49 | assert.equal(b.indexOf(buf_bc, -3), -1);
50 | assert.equal(b.indexOf(buf_bc, -5), 1);
51 | assert.equal(b.indexOf(buf_bc, NaN), 1);
52 | assert.equal(b.indexOf(buf_bc, -Infinity), 1);
53 | assert.equal(b.indexOf(buf_bc, Infinity), -1);
54 | assert.equal(b.indexOf(buf_f), b.length - 1);
55 | assert.equal(b.indexOf(buf_z), -1);
56 | assert.equal(b.indexOf(buf_empty), -1);
57 | assert.equal(b.indexOf(buf_empty, 1), -1);
58 | assert.equal(b.indexOf(buf_empty, b.length + 1), -1);
59 | assert.equal(b.indexOf(buf_empty, Infinity), -1);
60 | assert.equal(b.indexOf(0x61), 0);
61 | assert.equal(b.indexOf(0x61, 1), -1);
62 | assert.equal(b.indexOf(0x61, -1), -1);
63 | assert.equal(b.indexOf(0x61, -4), -1);
64 | assert.equal(b.indexOf(0x61, -b.length), 0);
65 | assert.equal(b.indexOf(0x61, NaN), 0);
66 | assert.equal(b.indexOf(0x61, -Infinity), 0);
67 | assert.equal(b.indexOf(0x61, Infinity), -1);
68 | assert.equal(b.indexOf(0x0), -1);
69 |
70 | // test offsets
71 | assert.equal(b.indexOf('d', 2), 3);
72 | assert.equal(b.indexOf('f', 5), 5);
73 | assert.equal(b.indexOf('f', -1), 5);
74 | assert.equal(b.indexOf('f', 6), -1);
75 |
76 | assert.equal(b.indexOf(Buffer.from('d'), 2), 3);
77 | assert.equal(b.indexOf(Buffer.from('f'), 5), 5);
78 | assert.equal(b.indexOf(Buffer.from('f'), -1), 5);
79 | assert.equal(b.indexOf(Buffer.from('f'), 6), -1);
80 |
81 | assert.equal(Buffer.from('ff').indexOf(Buffer.from('f'), 1, 'ucs2'), -1);
82 |
83 | // test hex encoding
84 | assert.strictEqual(
85 | Buffer.from(b.toString('hex'), 'hex')
86 | .indexOf('64', 0, 'hex'),
87 | 3
88 | );
89 | assert.strictEqual(
90 | Buffer.from(b.toString('hex'), 'hex')
91 | .indexOf(Buffer.from('64', 'hex'), 0, 'hex'),
92 | 3
93 | );
94 |
95 | // test base64 encoding
96 | assert.strictEqual(
97 | Buffer.from(b.toString('base64'), 'base64')
98 | .indexOf('ZA==', 0, 'base64'),
99 | 3
100 | );
101 | assert.strictEqual(
102 | Buffer.from(b.toString('base64'), 'base64')
103 | .indexOf(Buffer.from('ZA==', 'base64'), 0, 'base64'),
104 | 3
105 | );
106 |
107 | // test ascii encoding
108 | assert.strictEqual(
109 | Buffer.from(b.toString('ascii'), 'ascii')
110 | .indexOf('d', 0, 'ascii'),
111 | 3
112 | );
113 | assert.strictEqual(
114 | Buffer.from(b.toString('ascii'), 'ascii')
115 | .indexOf(Buffer.from('d', 'ascii'), 0, 'ascii'),
116 | 3
117 | );
118 |
119 | // test latin1 encoding
120 | assert.strictEqual(
121 | Buffer.from(b.toString('latin1'), 'latin1')
122 | .indexOf('d', 0, 'latin1'),
123 | 3
124 | );
125 | assert.strictEqual(
126 | Buffer.from(b.toString('latin1'), 'latin1')
127 | .indexOf(Buffer.from('d', 'latin1'), 0, 'latin1'),
128 | 3
129 | );
130 | assert.strictEqual(
131 | Buffer.from('aa\u00e8aa', 'latin1')
132 | .indexOf('\u00e8', 'latin1'),
133 | 2
134 | );
135 | assert.strictEqual(
136 | Buffer.from('\u00e8', 'latin1')
137 | .indexOf('\u00e8', 'latin1'),
138 | 0
139 | );
140 | assert.strictEqual(
141 | Buffer.from('\u00e8', 'latin1')
142 | .indexOf(Buffer.from('\u00e8', 'latin1'), 'latin1'),
143 | 0
144 | );
145 |
146 | // test binary encoding
147 | assert.strictEqual(
148 | Buffer.from(b.toString('binary'), 'binary')
149 | .indexOf('d', 0, 'binary'),
150 | 3
151 | );
152 | assert.strictEqual(
153 | Buffer.from(b.toString('binary'), 'binary')
154 | .indexOf(Buffer.from('d', 'binary'), 0, 'binary'),
155 | 3
156 | );
157 | assert.strictEqual(
158 | Buffer.from('aa\u00e8aa', 'binary')
159 | .indexOf('\u00e8', 'binary'),
160 | 2
161 | );
162 | assert.strictEqual(
163 | Buffer.from('\u00e8', 'binary')
164 | .indexOf('\u00e8', 'binary'),
165 | 0
166 | );
167 | assert.strictEqual(
168 | Buffer.from('\u00e8', 'binary')
169 | .indexOf(Buffer.from('\u00e8', 'binary'), 'binary'),
170 | 0
171 | );
172 |
173 |
174 | // test optional offset with passed encoding
175 | assert.equal(Buffer.from('aaaa0').indexOf('30', 'hex'), 4);
176 | assert.equal(Buffer.from('aaaa00a').indexOf('3030', 'hex'), 4);
177 |
178 | {
179 | // test usc2 encoding
180 | var twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
181 |
182 | assert.equal(8, twoByteString.indexOf('\u0395', 4, 'ucs2'));
183 | assert.equal(6, twoByteString.indexOf('\u03a3', -4, 'ucs2'));
184 | assert.equal(4, twoByteString.indexOf('\u03a3', -6, 'ucs2'));
185 | assert.equal(4, twoByteString.indexOf(
186 | Buffer.from('\u03a3', 'ucs2'), -6, 'ucs2'));
187 | assert.equal(-1, twoByteString.indexOf('\u03a3', -2, 'ucs2'));
188 | }
189 |
190 | var mixedByteStringUcs2 =
191 | Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395', 'ucs2');
192 | assert.equal(6, mixedByteStringUcs2.indexOf('bc', 0, 'ucs2'));
193 | assert.equal(10, mixedByteStringUcs2.indexOf('\u03a3', 0, 'ucs2'));
194 | assert.equal(-1, mixedByteStringUcs2.indexOf('\u0396', 0, 'ucs2'));
195 |
196 | assert.equal(
197 | 6, mixedByteStringUcs2.indexOf(Buffer.from('bc', 'ucs2'), 0, 'ucs2'));
198 | assert.equal(
199 | 10, mixedByteStringUcs2.indexOf(Buffer.from('\u03a3', 'ucs2'), 0, 'ucs2'));
200 | assert.equal(
201 | -1, mixedByteStringUcs2.indexOf(Buffer.from('\u0396', 'ucs2'), 0, 'ucs2'));
202 |
203 | {
204 | var twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2');
205 |
206 | // Test single char pattern
207 | assert.equal(0, twoByteString.indexOf('\u039a', 0, 'ucs2'));
208 | assert.equal(2, twoByteString.indexOf('\u0391', 0, 'ucs2'), 'Alpha');
209 | assert.equal(4, twoByteString.indexOf('\u03a3', 0, 'ucs2'), 'First Sigma');
210 | assert.equal(6, twoByteString.indexOf('\u03a3', 6, 'ucs2'), 'Second Sigma');
211 | assert.equal(8, twoByteString.indexOf('\u0395', 0, 'ucs2'), 'Epsilon');
212 | assert.equal(-1, twoByteString.indexOf('\u0392', 0, 'ucs2'), 'Not beta');
213 |
214 | // Test multi-char pattern
215 | assert.equal(
216 | 0, twoByteString.indexOf('\u039a\u0391', 0, 'ucs2'), 'Lambda Alpha');
217 | assert.equal(
218 | 2, twoByteString.indexOf('\u0391\u03a3', 0, 'ucs2'), 'Alpha Sigma');
219 | assert.equal(
220 | 4, twoByteString.indexOf('\u03a3\u03a3', 0, 'ucs2'), 'Sigma Sigma');
221 | assert.equal(
222 | 6, twoByteString.indexOf('\u03a3\u0395', 0, 'ucs2'), 'Sigma Epsilon');
223 | }
224 |
225 | var mixedByteStringUtf8 = Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395');
226 | assert.equal(5, mixedByteStringUtf8.indexOf('bc'));
227 | assert.equal(5, mixedByteStringUtf8.indexOf('bc', 5));
228 | assert.equal(5, mixedByteStringUtf8.indexOf('bc', -8));
229 | assert.equal(7, mixedByteStringUtf8.indexOf('\u03a3'));
230 | assert.equal(-1, mixedByteStringUtf8.indexOf('\u0396'));
231 |
232 |
233 | // Test complex string indexOf algorithms. Only trigger for long strings.
234 | // Long string that isn't a simple repeat of a shorter string.
235 | var longString = 'A';
236 | for (var i = 66; i < 76; i++) { // from 'B' to 'K'
237 | longString = longString + String.fromCharCode(i) + longString;
238 | }
239 |
240 | var longBufferString = Buffer.from(longString);
241 |
242 | // pattern of 15 chars, repeated every 16 chars in long
243 | var pattern = 'ABACABADABACABA';
244 | for (var i = 0; i < longBufferString.length - pattern.length; i += 7) {
245 | var index = longBufferString.indexOf(pattern, i);
246 | assert.equal((i + 15) & ~0xf, index, 'Long ABACABA...-string at index ' + i);
247 | }
248 | assert.equal(510, longBufferString.indexOf('AJABACA'), 'Long AJABACA, First J');
249 | assert.equal(
250 | 1534, longBufferString.indexOf('AJABACA', 511), 'Long AJABACA, Second J');
251 |
252 | pattern = 'JABACABADABACABA';
253 | assert.equal(
254 | 511, longBufferString.indexOf(pattern), 'Long JABACABA..., First J');
255 | assert.equal(
256 | 1535, longBufferString.indexOf(pattern, 512), 'Long JABACABA..., Second J');
257 |
258 | // Search for a non-ASCII string in a pure ASCII string.
259 | var asciiString = Buffer.from(
260 | 'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf');
261 | assert.equal(-1, asciiString.indexOf('\x2061'));
262 | assert.equal(3, asciiString.indexOf('leb', 0));
263 |
264 | // Search in string containing many non-ASCII chars.
265 | var allCodePoints = [];
266 | for (var i = 0; i < 65536; i++) allCodePoints[i] = i;
267 | var allCharsString = String.fromCharCode.apply(String, allCodePoints);
268 | var allCharsBufferUtf8 = Buffer.from(allCharsString);
269 | var allCharsBufferUcs2 = Buffer.from(allCharsString, 'ucs2');
270 |
271 | // Search for string long enough to trigger complex search with ASCII pattern
272 | // and UC16 subject.
273 | assert.equal(-1, allCharsBufferUtf8.indexOf('notfound'));
274 | assert.equal(-1, allCharsBufferUcs2.indexOf('notfound'));
275 |
276 | // Needle is longer than haystack, but only because it's encoded as UTF-16
277 | assert.strictEqual(Buffer.from('aaaa').indexOf('a'.repeat(4), 'ucs2'), -1);
278 |
279 | assert.strictEqual(Buffer.from('aaaa').indexOf('a'.repeat(4), 'utf8'), 0);
280 | assert.strictEqual(Buffer.from('aaaa').indexOf('你好', 'ucs2'), -1);
281 |
282 | // Haystack has odd length, but the needle is UCS2.
283 | // assert.strictEqual(Buffer.from('aaaaa').indexOf('b', 'ucs2'), -1);
284 |
285 | {
286 | // Find substrings in Utf8.
287 | var lengths = [1, 3, 15]; // Single char, simple and complex.
288 | var indices = [0x5, 0x60, 0x400, 0x680, 0x7ee, 0xFF02, 0x16610, 0x2f77b];
289 | for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
290 | for (var i = 0; i < indices.length; i++) {
291 | var index = indices[i];
292 | var length = lengths[lengthIndex];
293 |
294 | if (index + length > 0x7F) {
295 | length = 2 * length;
296 | }
297 |
298 | if (index + length > 0x7FF) {
299 | length = 3 * length;
300 | }
301 |
302 | if (index + length > 0xFFFF) {
303 | length = 4 * length;
304 | }
305 |
306 | var patternBufferUtf8 = allCharsBufferUtf8.slice(index, index + length);
307 | assert.equal(index, allCharsBufferUtf8.indexOf(patternBufferUtf8));
308 |
309 | var patternStringUtf8 = patternBufferUtf8.toString();
310 | assert.equal(index, allCharsBufferUtf8.indexOf(patternStringUtf8));
311 | }
312 | }
313 | }
314 |
315 | {
316 | // Find substrings in Usc2.
317 | var lengths = [2, 4, 16]; // Single char, simple and complex.
318 | var indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0];
319 | for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
320 | for (var i = 0; i < indices.length; i++) {
321 | var index = indices[i] * 2;
322 | var length = lengths[lengthIndex];
323 |
324 | var patternBufferUcs2 =
325 | allCharsBufferUcs2.slice(index, index + length);
326 | assert.equal(
327 | index, allCharsBufferUcs2.indexOf(patternBufferUcs2, 0, 'ucs2'));
328 |
329 | var patternStringUcs2 = patternBufferUcs2.toString('ucs2');
330 | assert.equal(
331 | index, allCharsBufferUcs2.indexOf(patternStringUcs2, 0, 'ucs2'));
332 | }
333 | }
334 | }
335 |
336 | assert.throws(function() {
337 | b.indexOf(function() { });
338 | });
339 | assert.throws(function() {
340 | b.indexOf({});
341 | });
342 | assert.throws(function() {
343 | b.indexOf([]);
344 | });
345 |
346 | // All code for handling encodings is shared between Buffer.indexOf and
347 | // Buffer.lastIndexOf, so only testing the separate lastIndexOf semantics.
348 |
349 | // Test lastIndexOf basic functionality; Buffer b contains 'abcdef'.
350 | // lastIndexOf string:
351 | assert.equal(b.lastIndexOf('a'), 0);
352 | assert.equal(b.lastIndexOf('a', 1), 0);
353 | assert.equal(b.lastIndexOf('b', 1), 1);
354 | assert.equal(b.lastIndexOf('c', 1), -1);
355 | assert.equal(b.lastIndexOf('a', -1), 0);
356 | assert.equal(b.lastIndexOf('a', -4), 0);
357 | assert.equal(b.lastIndexOf('a', -b.length), 0);
358 | assert.equal(b.lastIndexOf('a', -b.length - 1), -1);
359 | assert.equal(b.lastIndexOf('a', NaN), 0);
360 | assert.equal(b.lastIndexOf('a', -Infinity), -1);
361 | assert.equal(b.lastIndexOf('a', Infinity), 0);
362 | // lastIndexOf Buffer:
363 | assert.equal(b.lastIndexOf(buf_a), 0);
364 | assert.equal(b.lastIndexOf(buf_a, 1), 0);
365 | assert.equal(b.lastIndexOf(buf_a, -1), 0);
366 | assert.equal(b.lastIndexOf(buf_a, -4), 0);
367 | assert.equal(b.lastIndexOf(buf_a, -b.length), 0);
368 | assert.equal(b.lastIndexOf(buf_a, -b.length - 1), -1);
369 | assert.equal(b.lastIndexOf(buf_a, NaN), 0);
370 | assert.equal(b.lastIndexOf(buf_a, -Infinity), -1);
371 | assert.equal(b.lastIndexOf(buf_a, Infinity), 0);
372 | assert.equal(b.lastIndexOf(buf_bc), 1);
373 | assert.equal(b.lastIndexOf(buf_bc, 2), 1);
374 | assert.equal(b.lastIndexOf(buf_bc, -1), 1);
375 | assert.equal(b.lastIndexOf(buf_bc, -3), 1);
376 | assert.equal(b.lastIndexOf(buf_bc, -5), 1);
377 | assert.equal(b.lastIndexOf(buf_bc, -6), -1);
378 | assert.equal(b.lastIndexOf(buf_bc, NaN), 1);
379 | assert.equal(b.lastIndexOf(buf_bc, -Infinity), -1);
380 | assert.equal(b.lastIndexOf(buf_bc, Infinity), 1);
381 | assert.equal(b.lastIndexOf(buf_f), b.length - 1);
382 | assert.equal(b.lastIndexOf(buf_z), -1);
383 | assert.equal(b.lastIndexOf(buf_empty), -1);
384 | assert.equal(b.lastIndexOf(buf_empty, 1), -1);
385 | assert.equal(b.lastIndexOf(buf_empty, b.length + 1), -1);
386 | assert.equal(b.lastIndexOf(buf_empty, Infinity), -1);
387 | // lastIndexOf number:
388 | assert.equal(b.lastIndexOf(0x61), 0);
389 | assert.equal(b.lastIndexOf(0x61, 1), 0);
390 | assert.equal(b.lastIndexOf(0x61, -1), 0);
391 | assert.equal(b.lastIndexOf(0x61, -4), 0);
392 | assert.equal(b.lastIndexOf(0x61, -b.length), 0);
393 | assert.equal(b.lastIndexOf(0x61, -b.length - 1), -1);
394 | assert.equal(b.lastIndexOf(0x61, NaN), 0);
395 | assert.equal(b.lastIndexOf(0x61, -Infinity), -1);
396 | assert.equal(b.lastIndexOf(0x61, Infinity), 0);
397 | assert.equal(b.lastIndexOf(0x0), -1);
398 |
399 | // Test weird offset arguments.
400 | // Behaviour should match String.lastIndexOf:
401 | assert.equal(b.lastIndexOf('b', 0), -1);
402 | assert.equal(b.lastIndexOf('b', undefined), 1);
403 | assert.equal(b.lastIndexOf('b', null), -1);
404 | assert.equal(b.lastIndexOf('b', {}), 1);
405 | assert.equal(b.lastIndexOf('b', []), -1);
406 | assert.equal(b.lastIndexOf('b', [2]), 1);
407 |
408 | // Test needles longer than the haystack.
409 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'ucs2'), -1);
410 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'utf8'), -1);
411 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'latin1'), -1);
412 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'binary'), -1);
413 | assert.strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa')), -1);
414 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 2, 'ucs2'), -1);
415 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 3, 'utf8'), -1);
416 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 5, 'latin1'), -1);
417 | assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 5, 'binary'), -1);
418 | assert.strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa'), 7), -1);
419 |
420 | // 你好 expands to a total of 6 bytes using UTF-8 and 4 bytes using UTF-16
421 | assert.strictEqual(buf_bc.lastIndexOf('你好', 'ucs2'), -1);
422 | assert.strictEqual(buf_bc.lastIndexOf('你好', 'utf8'), -1);
423 | assert.strictEqual(buf_bc.lastIndexOf('你好', 'latin1'), -1);
424 | assert.strictEqual(buf_bc.lastIndexOf('你好', 'binary'), -1);
425 | assert.strictEqual(buf_bc.lastIndexOf(Buffer.from('你好')), -1);
426 | assert.strictEqual(buf_bc.lastIndexOf('你好', 2, 'ucs2'), -1);
427 | assert.strictEqual(buf_bc.lastIndexOf('你好', 3, 'utf8'), -1);
428 | assert.strictEqual(buf_bc.lastIndexOf('你好', 5, 'latin1'), -1);
429 | assert.strictEqual(buf_bc.lastIndexOf('你好', 5, 'binary'), -1);
430 | assert.strictEqual(buf_bc.lastIndexOf(Buffer.from('你好'), 7), -1);
431 |
432 | // Test lastIndexOf on a longer buffer:
433 | var bufferString = new Buffer('a man a plan a canal panama');
434 | assert.equal(15, bufferString.lastIndexOf('canal'));
435 | assert.equal(21, bufferString.lastIndexOf('panama'));
436 | assert.equal(0, bufferString.lastIndexOf('a man a plan a canal panama'));
437 | assert.equal(-1, bufferString.lastIndexOf('a man a plan a canal mexico'));
438 | assert.equal(-1, bufferString.lastIndexOf('a man a plan a canal mexico city'));
439 | assert.equal(-1, bufferString.lastIndexOf(Buffer.from('a'.repeat(1000))));
440 | assert.equal(0, bufferString.lastIndexOf('a man a plan', 4));
441 | assert.equal(13, bufferString.lastIndexOf('a '));
442 | assert.equal(13, bufferString.lastIndexOf('a ', 13));
443 | assert.equal(6, bufferString.lastIndexOf('a ', 12));
444 | assert.equal(0, bufferString.lastIndexOf('a ', 5));
445 | assert.equal(13, bufferString.lastIndexOf('a ', -1));
446 | assert.equal(0, bufferString.lastIndexOf('a ', -27));
447 | assert.equal(-1, bufferString.lastIndexOf('a ', -28));
448 |
449 | // Test lastIndexOf for the case that the first character can be found,
450 | // but in a part of the buffer that does not make search to search
451 | // due do length constraints.
452 | var abInUCS2 = Buffer.from('ab', 'ucs2');
453 | assert.strictEqual(-1, Buffer.from('µaaaa¶bbbb', 'latin1').lastIndexOf('µ'));
454 | assert.strictEqual(-1, Buffer.from('µaaaa¶bbbb', 'binary').lastIndexOf('µ'));
455 | assert.strictEqual(-1, Buffer.from('bc').lastIndexOf('ab'));
456 | assert.strictEqual(-1, Buffer.from('abc').lastIndexOf('qa'));
457 | assert.strictEqual(-1, Buffer.from('abcdef').lastIndexOf('qabc'));
458 | assert.strictEqual(-1, Buffer.from('bc').lastIndexOf(Buffer.from('ab')));
459 | assert.strictEqual(-1, Buffer.from('bc', 'ucs2').lastIndexOf('ab', 'ucs2'));
460 | assert.strictEqual(-1, Buffer.from('bc', 'ucs2').lastIndexOf(abInUCS2));
461 |
462 | assert.strictEqual(0, Buffer.from('abc').lastIndexOf('ab'));
463 | assert.strictEqual(0, Buffer.from('abc').lastIndexOf('ab', 1));
464 | assert.strictEqual(0, Buffer.from('abc').lastIndexOf('ab', 2));
465 | assert.strictEqual(0, Buffer.from('abc').lastIndexOf('ab', 3));
466 |
467 | // The above tests test the LINEAR and SINGLE-CHAR strategies.
468 | // Now, we test the BOYER-MOORE-HORSPOOL strategy.
469 | // Test lastIndexOf on a long buffer w multiple matches:
470 | pattern = 'JABACABADABACABA';
471 | assert.equal(1535, longBufferString.lastIndexOf(pattern));
472 | assert.equal(1535, longBufferString.lastIndexOf(pattern, 1535));
473 | assert.equal(511, longBufferString.lastIndexOf(pattern, 1534));
474 |
475 | // Finally, give it a really long input to trigger fallback from BMH to
476 | // regular BOYER-MOORE (which has better worst-case complexity).
477 |
478 | // Generate a really long Thue-Morse sequence of 'yolo' and 'swag',
479 | // "yolo swag swag yolo swag yolo yolo swag" ..., goes on for about 5MB.
480 | // This is hard to search because it all looks similar, but never repeats.
481 |
482 | // countBits returns the number of bits in the binary representation of n.
483 | function countBits(n) {
484 | for (var count = 0; n > 0; count++) {
485 | n = n & (n - 1); // remove top bit
486 | }
487 | return count;
488 | }
489 | var parts = [];
490 | for (var i = 0; i < 1000000; i++) {
491 | parts.push((countBits(i) % 2 === 0) ? 'yolo' : 'swag');
492 | }
493 | var reallyLong = new Buffer(parts.join(' '));
494 | assert.equal('yolo swag swag yolo', reallyLong.slice(0, 19).toString());
495 |
496 | // Expensive reverse searches. Stress test lastIndexOf:
497 | pattern = reallyLong.slice(0, 100000); // First 1/50th of the pattern.
498 | assert.equal(4751360, reallyLong.lastIndexOf(pattern));
499 | assert.equal(3932160, reallyLong.lastIndexOf(pattern, 4000000));
500 | assert.equal(2949120, reallyLong.lastIndexOf(pattern, 3000000));
501 | pattern = reallyLong.slice(100000, 200000); // Second 1/50th.
502 | assert.equal(4728480, reallyLong.lastIndexOf(pattern));
503 | pattern = reallyLong.slice(0, 1000000); // First 1/5th.
504 | assert.equal(3932160, reallyLong.lastIndexOf(pattern));
505 | pattern = reallyLong.slice(0, 2000000); // first 2/5ths.
506 | assert.equal(0, reallyLong.lastIndexOf(pattern));
507 |
508 | // test truncation of Number arguments to uint8
509 | {
510 | var buf = Buffer.from('this is a test');
511 | assert.strictEqual(buf.indexOf(0x6973), 3);
512 | assert.strictEqual(buf.indexOf(0x697320), 4);
513 | assert.strictEqual(buf.indexOf(0x69732069), 2);
514 | assert.strictEqual(buf.indexOf(0x697374657374), 0);
515 | assert.strictEqual(buf.indexOf(0x69737374), 0);
516 | assert.strictEqual(buf.indexOf(0x69737465), 11);
517 | assert.strictEqual(buf.indexOf(0x69737465), 11);
518 | assert.strictEqual(buf.indexOf(-140), 0);
519 | assert.strictEqual(buf.indexOf(-152), 1);
520 | assert.strictEqual(buf.indexOf(0xff), -1);
521 | assert.strictEqual(buf.indexOf(0xffff), -1);
522 | }
523 |
524 |
--------------------------------------------------------------------------------