Skip to content
Closed
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
18 changes: 18 additions & 0 deletions doc/api/buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,11 @@ console.log(buf2.toString());
### Class Method: Buffer.alloc(size[, fill[, encoding]])
<!-- YAML
added: v5.10.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/17428
description: Specifying an invalid string for `fill` now results in a
zero-filled buffer.
-->

* `size` {integer} The desired length of the new `Buffer`.
Expand Down Expand Up @@ -1253,6 +1258,19 @@ Example: Fill a `Buffer` with a two-byte character
console.log(Buffer.allocUnsafe(3).fill('\u0222'));
```

If `value` contains invalid characters, it is truncated; if no valid
fill data remains, no filling is performed:

```js
const buf = Buffer.allocUnsafe(5);
// Prints: <Buffer 61 61 61 61 61>
console.log(buf.fill('a'));
// Prints: <Buffer aa aa aa aa aa>
console.log(buf.fill('aazz', 'hex'));
Copy link
Member

@fhinkel fhinkel Dec 6, 2017

Choose a reason for hiding this comment

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

I'm wondering if we should use something like bbzz here. With a it's unclear if no filling is performed or if the string was truncated. Also, should the last example have a // Prints: ...?

// Prints: <Buffer aa aa aa aa aa>
console.log(buf.fill('zz', 'hex'));
```

### buf.includes(value[, byteOffset][, encoding])
<!-- YAML
added: v5.3.0
Expand Down
25 changes: 15 additions & 10 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ Buffer.alloc = function(size, fill, encoding) {
// be interpreted as a start offset.
if (typeof encoding !== 'string')
encoding = undefined;
return createUnsafeBuffer(size).fill(fill, encoding);
const ret = createUnsafeBuffer(size);
if (fill_(ret, fill, encoding) > 0)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe leave a comment here?

// Invalid data, no filling.

return ret;
}
return new FastBuffer(size);
};
Expand Down Expand Up @@ -796,15 +798,20 @@ Buffer.prototype.includes = function includes(val, byteOffset, encoding) {
// buffer.fill(buffer[, offset[, end]])
// buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill(val, start, end, encoding) {
fill_(this, val, start, end, encoding);
return this;
};

function fill_(buf, val, start, end, encoding) {
// Handle string cases:
if (typeof val === 'string') {
if (typeof start === 'string') {
encoding = start;
start = 0;
end = this.length;
end = buf.length;
} else if (typeof end === 'string') {
encoding = end;
end = this.length;
end = buf.length;
}

if (encoding !== undefined && typeof encoding !== 'string') {
Expand Down Expand Up @@ -832,19 +839,17 @@ Buffer.prototype.fill = function fill(val, start, end, encoding) {
}

// Invalid ranges are not set to a default, so can range check early.
Copy link
Member

Choose a reason for hiding this comment

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

Should it say "so one can range check early."?

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe

// Early range check because invalid ranges are not set to a default.

if (start < 0 || end > this.length)
if (start < 0 || end > buf.length)
throw new RangeError('Out of range index');

if (end <= start)
return this;
return 0;

start = start >>> 0;
end = end === undefined ? this.length : end >>> 0;
end = end === undefined ? buf.length : end >>> 0;

binding.fill(this, val, start, end, encoding);

return this;
};
return binding.fill(buf, val, start, end, encoding);
}


Buffer.prototype.write = function(string, offset, length, encoding) {
Expand Down
8 changes: 6 additions & 2 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,8 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_IF_OOB(start <= end);
THROW_AND_RETURN_IF_OOB(fill_length + start <= ts_obj_length);

args.GetReturnValue().Set(static_cast<double>(fill_length));

// First check if Buffer has been passed.
if (Buffer::HasInstance(args[1])) {
SPREAD_BUFFER_ARG(args[1], fill_obj);
Expand All @@ -612,8 +614,10 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
enc == UTF8 ? str_obj->Utf8Length() :
enc == UCS2 ? str_obj->Length() * sizeof(uint16_t) : str_obj->Length();

if (str_length == 0)
if (str_length == 0) {
args.GetReturnValue().Set(0);
return;
}

// Can't use StringBytes::Write() in all cases. For example if attempting
// to write a two byte character into a one byte Buffer.
Expand Down Expand Up @@ -643,7 +647,7 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
// TODO(trevnorris): Should this throw? Because of the string length was
// greater than 0 but couldn't be written then the string was invalid.
if (str_length == 0)
return;
return args.GetReturnValue().Set(0);
}

start_fill:
Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-buffer-alloc.js
Original file line number Diff line number Diff line change
Expand Up @@ -993,3 +993,14 @@ assert.strictEqual(Buffer.prototype.toLocaleString, Buffer.prototype.toString);
const buf = Buffer.from('test');
assert.strictEqual(buf.toLocaleString(), buf.toString());
}

{
// Ref: https://github.com/nodejs/node/issues/17423
const buf = Buffer.alloc(0x1000, 'This is not correctly encoded', 'hex');
assert(buf.every((byte) => byte === 0), `Buffer was not zeroed out: ${buf}`);
}

{
const buf = Buffer.alloc(0x1000, 'c', 'hex');
assert(buf.every((byte) => byte === 0), `Buffer was not zeroed out: ${buf}`);
}
6 changes: 6 additions & 0 deletions test/parallel/test-buffer-fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,9 @@ assert.strictEqual(
assert.strictEqual(
Buffer.allocUnsafeSlow(16).fill('Љ', 'utf8').toString('utf8'),
'Љ'.repeat(8));

{
const buf = Buffer.from('a'.repeat(1000));
buf.fill('This is not correctly encoded', 'hex');
assert.strictEqual(buf.toString(), 'a'.repeat(1000));
}
1 change: 1 addition & 0 deletions test/sequential/sequential.status
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ prefix sequential
test-inspector-async-call-stack : PASS, FLAKY
test-inspector-bindings : PASS, FLAKY
test-inspector-debug-end : PASS, FLAKY
test-inspector-async-hook-setup-at-signal: PASS, FLAKY
Copy link
Member

Choose a reason for hiding this comment

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

Hm, is this related to the change here?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, this snuck its way in here because v8.x-staging was rebased.

The commits should still apply cleanly; I can rebase this PR if @gibfahn likes.


[$system==linux]

Expand Down