Skip to content

Commit 641cfa2

Browse files
committed
buffer: fix single-character string filling
Fix the fast path for `buffer.fill()` with a single-character string. The fast path only works for strings that are equivalent to a single-byte buffer, but that condition was not checked properly for the `utf8` or `utf16le` encodings and is always true for the `latin1` encoding. This change fixes these problems. Fixes: #9836
1 parent 0ab2182 commit 641cfa2

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

lib/buffer.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -672,23 +672,27 @@ Buffer.prototype.fill = function fill(val, start, end, encoding) {
672672
encoding = end;
673673
end = this.length;
674674
}
675-
if (val.length === 1) {
676-
var code = val.charCodeAt(0);
677-
if (code < 256)
678-
val = code;
679-
}
680-
if (val.length === 0) {
681-
// Previously, if val === '', the Buffer would not fill,
682-
// which is rather surprising.
683-
val = 0;
684-
}
675+
685676
if (encoding !== undefined && typeof encoding !== 'string') {
686677
throw new TypeError('encoding must be a string');
687678
}
688-
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
679+
var normalizedEncoding = internalUtil.normalizeEncoding(encoding);
680+
if (normalizedEncoding === undefined) {
689681
throw new TypeError('Unknown encoding: ' + encoding);
690682
}
691683

684+
if (val.length === 0) {
685+
// Previously, if val === '', the Buffer would not fill,
686+
// which is rather surprising.
687+
val = 0;
688+
} else if (val.length === 1) {
689+
var code = val.charCodeAt(0);
690+
if ((normalizedEncoding === 'utf8' && code < 128) ||
691+
normalizedEncoding === 'latin1') {
692+
// Fast path: If `val` fits into a single byte, use that numeric value.
693+
val = code;
694+
}
695+
}
692696
} else if (typeof val === 'number') {
693697
val = val & 255;
694698
}

test/parallel/test-buffer-fill.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,3 +390,23 @@ assert.throws(() => {
390390
});
391391
buf.fill('');
392392
});
393+
394+
assert.strictEqual(
395+
Buffer.allocUnsafeSlow(16).fill('a', 'utf16le').toString('utf16le'),
396+
'aaaaaaaa');
397+
assert.strictEqual(
398+
Buffer.allocUnsafeSlow(16).fill('a', 'latin1').toString('latin1'),
399+
'aaaaaaaaaaaaaaaa');
400+
assert.strictEqual(
401+
Buffer.allocUnsafeSlow(16).fill('a', 'utf8').toString('utf8'),
402+
'aaaaaaaaaaaaaaaa');
403+
404+
assert.strictEqual(
405+
Buffer.allocUnsafeSlow(16).fill('Љ', 'utf16le').toString('utf16le'),
406+
'ЉЉЉЉЉЉЉЉ');
407+
assert.strictEqual(
408+
Buffer.allocUnsafeSlow(16).fill('Љ', 'latin1').toString('latin1'),
409+
'\t'.repeat(16));
410+
assert.strictEqual(
411+
Buffer.allocUnsafeSlow(16).fill('Љ', 'utf8').toString('utf8'),
412+
'ЉЉЉЉЉЉЉЉ');

0 commit comments

Comments
 (0)