Skip to content

Commit

Permalink
buffer: validate args to compare
Browse files Browse the repository at this point in the history
  • Loading branch information
refack committed Oct 25, 2018
1 parent aeaa698 commit 3fc87b4
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 96 deletions.
31 changes: 10 additions & 21 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ function validateOffsetType(val, name) {
Buffer.prototype.copy = function(target, targetStart, sourceStart, sourceEnd) {
if (!isUint8Array(target)) {
throw new ERR_INVALID_ARG_TYPE(
'otherBuffer', ['Buffer', 'Uint8Array'], target);
'target', ['Buffer', 'Uint8Array'], target);
}
targetStart = validateOffsetType(targetStart, 'targetStart');
sourceStart = validateOffsetType(sourceStart, 'sourceStart');
Expand Down Expand Up @@ -714,33 +714,22 @@ Buffer.prototype.compare = function compare(target,
if (arguments.length === 1)
return _compare(this, target);

if (targetStart === undefined)
targetStart = 0;
else if (targetStart < 0)
targetStart = validateOffsetType(targetStart, 'targetStart');
targetEnd = validateOffsetType(targetEnd, 'targetEnd') || target.length;
sourceStart = validateOffsetType(sourceStart, 'sourceStart');
sourceEnd = validateOffsetType(sourceEnd, 'sourceEnd') || this.length;

if (targetStart < 0)
throw new ERR_OUT_OF_RANGE('targetStart', '>= 0', targetStart);
else
targetStart >>>= 0;

if (targetEnd === undefined)
targetEnd = target.length;
else if (targetEnd > target.length)
if (targetEnd > target.length)
throw new ERR_OUT_OF_RANGE('targetEnd', `<= ${target.length}`, targetEnd);
else
targetEnd >>>= 0;

if (sourceStart === undefined)
sourceStart = 0;
else if (sourceStart < 0)
if (sourceStart < 0)
throw new ERR_OUT_OF_RANGE('sourceStart', '>= 0', sourceStart);
else
sourceStart >>>= 0;

if (sourceEnd === undefined)
sourceEnd = this.length;
else if (sourceEnd > this.length)
if (sourceEnd > this.length)
throw new ERR_OUT_OF_RANGE('sourceEnd', `<= ${this.length}`, sourceEnd);
else
sourceEnd >>>= 0;

if (sourceStart >= sourceEnd)
return (targetStart >= targetEnd ? 0 : -1);
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-buffer-alloc.js
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ common.expectsError(
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "otherBuffer" argument must be one of type Buffer or ' +
message: 'The "target" argument must be one of type Buffer or ' +
'Uint8Array. Received type undefined'
});

Expand Down
74 changes: 0 additions & 74 deletions test/parallel/test-buffer-compare-offset.js

This file was deleted.

136 changes: 136 additions & 0 deletions test/parallel/test-buffer-compare.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,139 @@ common.expectsError(() => Buffer.alloc(1).compare('abc'), {
message: 'The "target" argument must be one of ' +
'type Buffer or Uint8Array. Received type string'
});


// Test compare with offset
{
const a = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
const b = Buffer.from([5, 6, 7, 8, 9, 0, 1, 2, 3, 4]);

assert.strictEqual(a.compare(b), -1);

// Equivalent to a.compare(b).
assert.strictEqual(a.compare(b, 0), -1);
assert.strictEqual(a.compare(b, '0'), -1);
assert.strictEqual(a.compare(b, undefined), -1);

// Equivalent to a.compare(b).
assert.strictEqual(a.compare(b, 0, undefined, 0), -1);

// Zero-length target, return 1
assert.strictEqual(a.compare(b, 0, 0, 0), 1);
assert.strictEqual(a.compare(b, '0', '0', '0'), 1);

// Equivalent to Buffer.compare(a, b.slice(6, 10))
assert.strictEqual(a.compare(b, 6, 10), 1);

// Zero-length source, return -1
assert.strictEqual(a.compare(b, 6, 10, 0, 0), -1);

// Zero-length source and target, return 0
assert.strictEqual(a.compare(b, 0, 0, 0, 0), 0);
assert.strictEqual(a.compare(b, 1, 1, 2, 2), 0);

// Equivalent to Buffer.compare(a.slice(4), b.slice(0, 5))
assert.strictEqual(a.compare(b, 0, 5, 4), 1);

// Equivalent to Buffer.compare(a.slice(1), b.slice(5))
assert.strictEqual(a.compare(b, 5, undefined, 1), 1);

// Equivalent to Buffer.compare(a.slice(2), b.slice(2, 4))
assert.strictEqual(a.compare(b, 2, 4, 2), -1);

// Equivalent to Buffer.compare(a.slice(4), b.slice(0, 7))
assert.strictEqual(a.compare(b, 0, 7, 4), -1);

// Equivalent to Buffer.compare(a.slice(4, 6), b.slice(0, 7));
assert.strictEqual(a.compare(b, 0, 7, 4, 6), -1);

// zero length target
assert.strictEqual(a.compare(b, 0, null), 1);

// coerces to targetEnd == 5
assert.strictEqual(a.compare(b, 0, { valueOf: () => 5 }), -1);

// zero length target
assert.strictEqual(a.compare(b, Infinity, -Infinity), 1);

// zero length target because default for targetEnd <= targetSource
assert.strictEqual(a.compare(b, '0xff'), 1);

const oor = common.expectsError({ code: 'ERR_OUT_OF_RANGE' }, 7);

assert.throws(() => a.compare(b, 0, 100, 0), oor);
assert.throws(() => a.compare(b, 0, 1, 0, 100), oor);
assert.throws(() => a.compare(b, -1), oor);
assert.throws(() => a.compare(b, 0, '0xff'), oor);
assert.throws(() => a.compare(b, 0, Infinity), oor);
assert.throws(() => a.compare(b, 0, 1, -1), oor);
assert.throws(() => a.compare(b, -Infinity, Infinity), oor);
common.expectsError(() => a.compare(), {
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "target" argument must be one of ' +
'type Buffer or Uint8Array. Received type undefined'
});

// Validate arg type checking.
// Refs: https://github.com/nodejs/node/issues/23668
{
common.expectsError(
() => b.compare(c, '1'),
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "targetStart" argument must be of type ' +
'Number. Received type string'
}
);
common.expectsError(
() => b.compare(c, 0, '1'),
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "targetEnd" argument must be of type ' +
'Number. Received type string'
}
);
common.expectsError(
() => b.compare(c, 0, 0, '1'),
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "sourceStart" argument must be of type ' +
'Number. Received type string'
}
);
common.expectsError(
() => b.compare(c, 0, 0, 0, '1'),
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "sourceEnd" argument must be of type ' +
'Number. Received type string'
}
);
}

// Validate arg range checking.
// Refs: https://github.com/nodejs/node/issues/23668
{
common.expectsError(
() => b.copy(c, -1),
oor
);
common.expectsError(
() => b.copy(c, 0, -1),
oor
);
common.expectsError(
() => b.copy(c, 0, 0, -1),
oor
);
common.expectsError(
() => b.copy(c, 0, 0, 0, -1),
oor
);
}
}

0 comments on commit 3fc87b4

Please sign in to comment.