Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,8 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
Local<String> str_obj;
size_t str_length;
enum encoding enc;
CHECK(fill_length + start <= ts_obj_length);
THROW_AND_RETURN_IF_OOB(start <= end);
THROW_AND_RETURN_IF_OOB(fill_length + start <= ts_obj_length);

// First check if Buffer has been passed.
if (Buffer::HasInstance(args[1])) {
Expand Down
76 changes: 76 additions & 0 deletions test/parallel/test-buffer-fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,79 @@ Buffer.alloc(8, '');
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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: this can be just ctr === 0.

Copy link
Contributor Author

@trevnorris trevnorris Oct 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no. in case the internals change then cntr may be less than 0. if that's the case then the value needs to be updated. which is why i have the followup check below of

assert.ok(elseWasLast,
          'internal API changed, -1 no longer in correct location');

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);
});
// 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('');
});