Skip to content

Commit 9eaa721

Browse files
addaleaxMylesBorins
authored andcommitted
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 PR-URL: #9837 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
1 parent 60d5f6b commit 9eaa721

2 files changed

Lines changed: 42 additions & 12 deletions

File tree

‎lib/buffer.js‎

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -664,23 +664,27 @@ Buffer.prototype.fill = function fill(val, start, end, encoding) {
664664
encoding=end;
665665
end=this.length;
666666
}
667-
if(val.length===1){
668-
varcode=val.charCodeAt(0);
669-
if(code<256)
670-
val=code;
671-
}
672-
if(val.length===0){
673-
// Previously, if val === '', the Buffer would not fill,
674-
// which is rather surprising.
675-
val=0;
676-
}
667+
677668
if(encoding!==undefined&&typeofencoding!=='string'){
678669
thrownewTypeError('encoding must be a string');
679670
}
680-
if(typeofencoding==='string'&&!Buffer.isEncoding(encoding)){
671+
varnormalizedEncoding=internalUtil.normalizeEncoding(encoding);
672+
if(normalizedEncoding===undefined){
681673
thrownewTypeError('Unknown encoding: '+encoding);
682674
}
683675

676+
if(val.length===0){
677+
// Previously, if val === '', the Buffer would not fill,
678+
// which is rather surprising.
679+
val=0;
680+
}elseif(val.length===1){
681+
varcode=val.charCodeAt(0);
682+
if((normalizedEncoding==='utf8'&&code<128)||
683+
normalizedEncoding==='latin1'){
684+
// Fast path: If `val` fits into a single byte, use that numeric value.
685+
val=code;
686+
}
687+
}
684688
}elseif(typeofval==='number'){
685689
val=val&255;
686690
}

‎test/parallel/test-buffer-fill.js‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,11 +395,37 @@ assert.throws(() => {
395395
buf.fill('');
396396
},/^RangeError:outofrangeindex$/);
397397

398-
399398
assert.deepStrictEqual(
400399
Buffer.allocUnsafeSlow(16).fill('ab','utf16le'),
401400
Buffer.from('61006200610062006100620061006200','hex'));
402401

403402
assert.deepStrictEqual(
404403
Buffer.allocUnsafeSlow(15).fill('ab','utf16le'),
405404
Buffer.from('610062006100620061006200610062','hex'));
405+
406+
assert.deepStrictEqual(
407+
Buffer.allocUnsafeSlow(16).fill('ab','utf16le'),
408+
Buffer.from('61006200610062006100620061006200','hex'));
409+
assert.deepStrictEqual(
410+
Buffer.allocUnsafeSlow(16).fill('a','utf16le'),
411+
Buffer.from('61006100610061006100610061006100','hex'));
412+
413+
assert.strictEqual(
414+
Buffer.allocUnsafeSlow(16).fill('a','utf16le').toString('utf16le'),
415+
'a'.repeat(8));
416+
assert.strictEqual(
417+
Buffer.allocUnsafeSlow(16).fill('a','latin1').toString('latin1'),
418+
'a'.repeat(16));
419+
assert.strictEqual(
420+
Buffer.allocUnsafeSlow(16).fill('a','utf8').toString('utf8'),
421+
'a'.repeat(16));
422+
423+
assert.strictEqual(
424+
Buffer.allocUnsafeSlow(16).fill('Љ','utf16le').toString('utf16le'),
425+
'Љ'.repeat(8));
426+
assert.strictEqual(
427+
Buffer.allocUnsafeSlow(16).fill('Љ','latin1').toString('latin1'),
428+
'\t'.repeat(16));
429+
assert.strictEqual(
430+
Buffer.allocUnsafeSlow(16).fill('Љ','utf8').toString('utf8'),
431+
'Љ'.repeat(8));

0 commit comments

Comments
 (0)