mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
431 lines
13 KiB
431 lines
13 KiB
'use strict';
|
|
|
|
require('../common');
|
|
const assert = require('assert');
|
|
const SIZE = 28;
|
|
|
|
const buf1 = Buffer.allocUnsafe(SIZE);
|
|
const buf2 = Buffer.allocUnsafe(SIZE);
|
|
|
|
// Default encoding
|
|
testBufs('abc');
|
|
testBufs('\u0222aa');
|
|
testBufs('a\u0234b\u0235c\u0236');
|
|
testBufs('abc', 4);
|
|
testBufs('abc', 5);
|
|
testBufs('abc', SIZE);
|
|
testBufs('\u0222aa', 2);
|
|
testBufs('\u0222aa', 8);
|
|
testBufs('a\u0234b\u0235c\u0236', 4);
|
|
testBufs('a\u0234b\u0235c\u0236', 12);
|
|
testBufs('abc', 4, -1);
|
|
testBufs('abc', 4, 1);
|
|
testBufs('abc', 5, 1);
|
|
testBufs('\u0222aa', 2, -1);
|
|
testBufs('\u0222aa', 8, 1);
|
|
testBufs('a\u0234b\u0235c\u0236', 4, -1);
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 1);
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 1);
|
|
|
|
|
|
// UTF8
|
|
testBufs('abc', 'utf8');
|
|
testBufs('\u0222aa', 'utf8');
|
|
testBufs('a\u0234b\u0235c\u0236', 'utf8');
|
|
testBufs('abc', 4, 'utf8');
|
|
testBufs('abc', 5, 'utf8');
|
|
testBufs('abc', SIZE, 'utf8');
|
|
testBufs('\u0222aa', 2, 'utf8');
|
|
testBufs('\u0222aa', 8, 'utf8');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 'utf8');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 'utf8');
|
|
testBufs('abc', 4, -1, 'utf8');
|
|
testBufs('abc', 4, 1, 'utf8');
|
|
testBufs('abc', 5, 1, 'utf8');
|
|
testBufs('\u0222aa', 2, -1, 'utf8');
|
|
testBufs('\u0222aa', 8, 1, 'utf8');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, -1, 'utf8');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 1, 'utf8');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 1, 'utf8');
|
|
assert.strictEqual(Buffer.allocUnsafe(1).fill(0).fill('\u0222')[0], 0xc8);
|
|
|
|
|
|
// BINARY
|
|
testBufs('abc', 'binary');
|
|
testBufs('\u0222aa', 'binary');
|
|
testBufs('a\u0234b\u0235c\u0236', 'binary');
|
|
testBufs('abc', 4, 'binary');
|
|
testBufs('abc', 5, 'binary');
|
|
testBufs('abc', SIZE, 'binary');
|
|
testBufs('\u0222aa', 2, 'binary');
|
|
testBufs('\u0222aa', 8, 'binary');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 'binary');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 'binary');
|
|
testBufs('abc', 4, -1, 'binary');
|
|
testBufs('abc', 4, 1, 'binary');
|
|
testBufs('abc', 5, 1, 'binary');
|
|
testBufs('\u0222aa', 2, -1, 'binary');
|
|
testBufs('\u0222aa', 8, 1, 'binary');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, -1, 'binary');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 1, 'binary');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 1, 'binary');
|
|
|
|
|
|
// LATIN1
|
|
testBufs('abc', 'latin1');
|
|
testBufs('\u0222aa', 'latin1');
|
|
testBufs('a\u0234b\u0235c\u0236', 'latin1');
|
|
testBufs('abc', 4, 'latin1');
|
|
testBufs('abc', 5, 'latin1');
|
|
testBufs('abc', SIZE, 'latin1');
|
|
testBufs('\u0222aa', 2, 'latin1');
|
|
testBufs('\u0222aa', 8, 'latin1');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 'latin1');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 'latin1');
|
|
testBufs('abc', 4, -1, 'latin1');
|
|
testBufs('abc', 4, 1, 'latin1');
|
|
testBufs('abc', 5, 1, 'latin1');
|
|
testBufs('\u0222aa', 2, -1, 'latin1');
|
|
testBufs('\u0222aa', 8, 1, 'latin1');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, -1, 'latin1');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 1, 'latin1');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 1, 'latin1');
|
|
|
|
|
|
// UCS2
|
|
testBufs('abc', 'ucs2');
|
|
testBufs('\u0222aa', 'ucs2');
|
|
testBufs('a\u0234b\u0235c\u0236', 'ucs2');
|
|
testBufs('abc', 4, 'ucs2');
|
|
testBufs('abc', SIZE, 'ucs2');
|
|
testBufs('\u0222aa', 2, 'ucs2');
|
|
testBufs('\u0222aa', 8, 'ucs2');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 'ucs2');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 'ucs2');
|
|
testBufs('abc', 4, -1, 'ucs2');
|
|
testBufs('abc', 4, 1, 'ucs2');
|
|
testBufs('abc', 5, 1, 'ucs2');
|
|
testBufs('\u0222aa', 2, -1, 'ucs2');
|
|
testBufs('\u0222aa', 8, 1, 'ucs2');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, -1, 'ucs2');
|
|
testBufs('a\u0234b\u0235c\u0236', 4, 1, 'ucs2');
|
|
testBufs('a\u0234b\u0235c\u0236', 12, 1, 'ucs2');
|
|
assert.strictEqual(Buffer.allocUnsafe(1).fill('\u0222', 'ucs2')[0], 0x22);
|
|
|
|
|
|
// HEX
|
|
testBufs('616263', 'hex');
|
|
testBufs('c8a26161', 'hex');
|
|
testBufs('61c8b462c8b563c8b6', 'hex');
|
|
testBufs('616263', 4, 'hex');
|
|
testBufs('616263', 5, 'hex');
|
|
testBufs('616263', SIZE, 'hex');
|
|
testBufs('c8a26161', 2, 'hex');
|
|
testBufs('c8a26161', 8, 'hex');
|
|
testBufs('61c8b462c8b563c8b6', 4, 'hex');
|
|
testBufs('61c8b462c8b563c8b6', 12, 'hex');
|
|
testBufs('616263', 4, -1, 'hex');
|
|
testBufs('616263', 4, 1, 'hex');
|
|
testBufs('616263', 5, 1, 'hex');
|
|
testBufs('c8a26161', 2, -1, 'hex');
|
|
testBufs('c8a26161', 8, 1, 'hex');
|
|
testBufs('61c8b462c8b563c8b6', 4, -1, 'hex');
|
|
testBufs('61c8b462c8b563c8b6', 4, 1, 'hex');
|
|
testBufs('61c8b462c8b563c8b6', 12, 1, 'hex');
|
|
// Make sure this operation doesn't go on forever
|
|
buf1.fill('yKJh', 'hex');
|
|
assert.throws(() =>
|
|
buf1.fill('\u0222', 'hex'), /^TypeError: Invalid hex string$/);
|
|
|
|
|
|
// BASE64
|
|
testBufs('YWJj', 'ucs2');
|
|
testBufs('yKJhYQ==', 'ucs2');
|
|
testBufs('Yci0Ysi1Y8i2', 'ucs2');
|
|
testBufs('YWJj', 4, 'ucs2');
|
|
testBufs('YWJj', SIZE, 'ucs2');
|
|
testBufs('yKJhYQ==', 2, 'ucs2');
|
|
testBufs('yKJhYQ==', 8, 'ucs2');
|
|
testBufs('Yci0Ysi1Y8i2', 4, 'ucs2');
|
|
testBufs('Yci0Ysi1Y8i2', 12, 'ucs2');
|
|
testBufs('YWJj', 4, -1, 'ucs2');
|
|
testBufs('YWJj', 4, 1, 'ucs2');
|
|
testBufs('YWJj', 5, 1, 'ucs2');
|
|
testBufs('yKJhYQ==', 2, -1, 'ucs2');
|
|
testBufs('yKJhYQ==', 8, 1, 'ucs2');
|
|
testBufs('Yci0Ysi1Y8i2', 4, -1, 'ucs2');
|
|
testBufs('Yci0Ysi1Y8i2', 4, 1, 'ucs2');
|
|
testBufs('Yci0Ysi1Y8i2', 12, 1, 'ucs2');
|
|
|
|
|
|
// Buffer
|
|
function deepStrictEqualValues(buf, arr) {
|
|
for (const [index, value] of buf.entries()) {
|
|
assert.deepStrictEqual(value, arr[index]);
|
|
}
|
|
}
|
|
|
|
|
|
const buf2Fill = Buffer.allocUnsafe(1).fill(2);
|
|
deepStrictEqualValues(genBuffer(4, [buf2Fill]), [2, 2, 2, 2]);
|
|
deepStrictEqualValues(genBuffer(4, [buf2Fill, 1]), [0, 2, 2, 2]);
|
|
deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, 3]), [0, 2, 2, 0]);
|
|
deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, 1]), [0, 0, 0, 0]);
|
|
deepStrictEqualValues(genBuffer(4, [buf2Fill, 1, -1]), [0, 0, 0, 0]);
|
|
const hexBufFill = Buffer.allocUnsafe(2).fill(0).fill('0102', 'hex');
|
|
deepStrictEqualValues(genBuffer(4, [hexBufFill]), [1, 2, 1, 2]);
|
|
deepStrictEqualValues(genBuffer(4, [hexBufFill, 1]), [0, 1, 2, 1]);
|
|
deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, 3]), [0, 1, 2, 0]);
|
|
deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, 1]), [0, 0, 0, 0]);
|
|
deepStrictEqualValues(genBuffer(4, [hexBufFill, 1, -1]), [0, 0, 0, 0]);
|
|
|
|
|
|
// Check exceptions
|
|
assert.throws(() => buf1.fill(0, -1), /^RangeError: Out of range index$/);
|
|
assert.throws(() =>
|
|
buf1.fill(0, 0, buf1.length + 1),
|
|
/^RangeError: Out of range index$/);
|
|
assert.throws(() => buf1.fill('', -1), /^RangeError: Out of range index$/);
|
|
assert.throws(() =>
|
|
buf1.fill('', 0, buf1.length + 1),
|
|
/^RangeError: Out of range index$/);
|
|
assert.throws(() =>
|
|
buf1.fill('a', 0, buf1.length, 'node rocks!'),
|
|
/^TypeError: Unknown encoding: node rocks!$/);
|
|
assert.throws(() =>
|
|
buf1.fill('a', 0, 0, NaN),
|
|
/^TypeError: encoding must be a string$/);
|
|
assert.throws(() =>
|
|
buf1.fill('a', 0, 0, null),
|
|
/^TypeError: encoding must be a string$/);
|
|
assert.throws(() =>
|
|
buf1.fill('a', 0, 0, 'foo'), /^TypeError: Unknown encoding: foo$/);
|
|
|
|
|
|
function genBuffer(size, args) {
|
|
const b = Buffer.allocUnsafe(size);
|
|
return b.fill(0).fill.apply(b, args);
|
|
}
|
|
|
|
|
|
function bufReset() {
|
|
buf1.fill(0);
|
|
buf2.fill(0);
|
|
}
|
|
|
|
|
|
// This is mostly accurate. Except write() won't write partial bytes to the
|
|
// string while fill() blindly copies bytes into memory. To account for that an
|
|
// error will be thrown if not all the data can be written, and the SIZE has
|
|
// been massaged to work with the input characters.
|
|
function writeToFill(string, offset, end, encoding) {
|
|
if (typeof offset === 'string') {
|
|
encoding = offset;
|
|
offset = 0;
|
|
end = buf2.length;
|
|
} else if (typeof end === 'string') {
|
|
encoding = end;
|
|
end = buf2.length;
|
|
} else if (end === undefined) {
|
|
end = buf2.length;
|
|
}
|
|
|
|
if (offset < 0 || end > buf2.length)
|
|
throw new RangeError('Out of range index');
|
|
|
|
if (end <= offset)
|
|
return buf2;
|
|
|
|
offset >>>= 0;
|
|
end >>>= 0;
|
|
assert(offset <= buf2.length);
|
|
|
|
// Convert "end" to "length" (which write understands).
|
|
const length = end - offset < 0 ? 0 : end - offset;
|
|
|
|
var wasZero = false;
|
|
do {
|
|
const written = buf2.write(string, offset, length, encoding);
|
|
offset += written;
|
|
// Safety check in case write falls into infinite loop.
|
|
if (written === 0) {
|
|
if (wasZero)
|
|
throw new Error('Could not write all data to Buffer');
|
|
else
|
|
wasZero = true;
|
|
}
|
|
} while (offset < buf2.length);
|
|
|
|
return buf2;
|
|
}
|
|
|
|
|
|
function testBufs(string, offset, length, encoding) {
|
|
bufReset();
|
|
buf1.fill.apply(buf1, arguments);
|
|
// Swap bytes on BE archs for ucs2 encoding.
|
|
assert.deepStrictEqual(buf1.fill.apply(buf1, arguments),
|
|
writeToFill.apply(null, arguments));
|
|
}
|
|
|
|
// Make sure these throw.
|
|
assert.throws(() =>
|
|
Buffer.allocUnsafe(8).fill('a', -1),
|
|
/^RangeError: Out of range index$/);
|
|
assert.throws(() =>
|
|
Buffer.allocUnsafe(8).fill('a', 0, 9),
|
|
/^RangeError: Out of range index$/);
|
|
|
|
// Make sure this doesn't hang indefinitely.
|
|
Buffer.allocUnsafe(8).fill('');
|
|
Buffer.alloc(8, '');
|
|
|
|
{
|
|
const buf = Buffer.alloc(64, 10);
|
|
for (let i = 0; i < buf.length; i++)
|
|
assert.strictEqual(buf[i], 10);
|
|
|
|
buf.fill(11, 0, buf.length >> 1);
|
|
for (let i = 0; i < buf.length >> 1; i++)
|
|
assert.strictEqual(buf[i], 11);
|
|
for (let i = (buf.length >> 1) + 1; i < buf.length; i++)
|
|
assert.strictEqual(buf[i], 10);
|
|
|
|
buf.fill('h');
|
|
for (let i = 0; i < buf.length; i++)
|
|
assert.strictEqual('h'.charCodeAt(0), buf[i]);
|
|
|
|
buf.fill(0);
|
|
for (let i = 0; i < buf.length; i++)
|
|
assert.strictEqual(0, buf[i]);
|
|
|
|
buf.fill(null);
|
|
for (let i = 0; i < buf.length; i++)
|
|
assert.strictEqual(0, buf[i]);
|
|
|
|
buf.fill(1, 16, 32);
|
|
for (let i = 0; i < 16; i++)
|
|
assert.strictEqual(0, buf[i]);
|
|
for (let i = 16; i < 32; i++)
|
|
assert.strictEqual(1, buf[i]);
|
|
for (let i = 32; i < buf.length; i++)
|
|
assert.strictEqual(0, buf[i]);
|
|
}
|
|
|
|
{
|
|
const buf = Buffer.alloc(10, 'abc');
|
|
assert.strictEqual(buf.toString(), 'abcabcabca');
|
|
buf.fill('է');
|
|
assert.strictEqual(buf.toString(), 'էէէէէ');
|
|
}
|
|
|
|
// Testing public API. Make sure "start" is properly checked, even if it's
|
|
// magically mangled using Symbol.toPrimitive.
|
|
{
|
|
let elseWasLast = false;
|
|
assert.throws(() => {
|
|
var ctr = 0;
|
|
const start = {
|
|
[Symbol.toPrimitive]() {
|
|
// We use this condition to get around the check in lib/buffer.js
|
|
if (ctr <= 0) {
|
|
elseWasLast = false;
|
|
ctr = ctr + 1;
|
|
return 0;
|
|
} else {
|
|
elseWasLast = true;
|
|
// Once buffer.js calls the C++ implemenation of fill, return -1
|
|
return -1;
|
|
}
|
|
}
|
|
};
|
|
Buffer.alloc(1).fill(Buffer.alloc(1), start, 1);
|
|
}, /out of range index/);
|
|
// Make sure -1 is making it to Buffer::Fill().
|
|
assert.ok(elseWasLast,
|
|
'internal API changed, -1 no longer in correct location');
|
|
}
|
|
|
|
// Testing process.binding. Make sure "start" is properly checked for -1 wrap
|
|
// around.
|
|
assert.throws(() => {
|
|
process.binding('buffer').fill(Buffer.alloc(1), 1, -1, 0, 1);
|
|
}, /out of range index/);
|
|
|
|
// Make sure "end" is properly checked, even if it's magically mangled using
|
|
// Symbol.toPrimitive.
|
|
{
|
|
let elseWasLast = false;
|
|
assert.throws(() => {
|
|
var ctr = 0;
|
|
const end = {
|
|
[Symbol.toPrimitive]() {
|
|
// We use this condition to get around the check in lib/buffer.js
|
|
if (ctr <= 1) {
|
|
elseWasLast = false;
|
|
ctr = ctr + 1;
|
|
return 1;
|
|
} else {
|
|
elseWasLast = true;
|
|
// Once buffer.js calls the C++ implemenation of fill, return -1
|
|
return -1;
|
|
}
|
|
}
|
|
};
|
|
Buffer.alloc(1).fill(Buffer.alloc(1), 0, end);
|
|
}, /^RangeError: out of range index$/);
|
|
// Make sure -1 is making it to Buffer::Fill().
|
|
assert.ok(elseWasLast,
|
|
'internal API changed, -1 no longer in correct location');
|
|
}
|
|
|
|
// Testing process.binding. Make sure "end" is properly checked for -1 wrap
|
|
// around.
|
|
assert.throws(() => {
|
|
process.binding('buffer').fill(Buffer.alloc(1), 1, 1, -2, 1);
|
|
}, /out of range index/);
|
|
|
|
// Test that bypassing 'length' won't cause an abort.
|
|
assert.throws(() => {
|
|
const buf = new Buffer('w00t');
|
|
Object.defineProperty(buf, 'length', {
|
|
value: 1337,
|
|
enumerable: true
|
|
});
|
|
buf.fill('');
|
|
}, /^RangeError: out of range index$/);
|
|
|
|
assert.deepStrictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('ab', 'utf16le'),
|
|
Buffer.from('61006200610062006100620061006200', 'hex'));
|
|
|
|
assert.deepStrictEqual(
|
|
Buffer.allocUnsafeSlow(15).fill('ab', 'utf16le'),
|
|
Buffer.from('610062006100620061006200610062', 'hex'));
|
|
|
|
assert.deepStrictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('ab', 'utf16le'),
|
|
Buffer.from('61006200610062006100620061006200', 'hex'));
|
|
assert.deepStrictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('a', 'utf16le'),
|
|
Buffer.from('61006100610061006100610061006100', 'hex'));
|
|
|
|
assert.strictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('a', 'utf16le').toString('utf16le'),
|
|
'a'.repeat(8));
|
|
assert.strictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('a', 'latin1').toString('latin1'),
|
|
'a'.repeat(16));
|
|
assert.strictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('a', 'utf8').toString('utf8'),
|
|
'a'.repeat(16));
|
|
|
|
assert.strictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('Љ', 'utf16le').toString('utf16le'),
|
|
'Љ'.repeat(8));
|
|
assert.strictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('Љ', 'latin1').toString('latin1'),
|
|
'\t'.repeat(16));
|
|
assert.strictEqual(
|
|
Buffer.allocUnsafeSlow(16).fill('Љ', 'utf8').toString('utf8'),
|
|
'Љ'.repeat(8));
|
|
|