Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit 4b40358

Browse files
committed
buffer: implement new fill behavior
Old fill would take the char code of the first character and wrap around the int to fit in the 127 range. Now fill will duplicate whatever string is given through the entirety of the buffer. Note: There is one bug around ending on a partial fill of any character outside the ASCII range.
1 parent f489649 commit 4b40358

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

src/node_buffer.cc

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -296,18 +296,42 @@ Handle<Value> Fill(const Arguments &args) {
296296
HandleScope scope(node_isolate);
297297

298298
ARGS_THIS(args.This())
299-
int value;
299+
SLICE_START_END(args[1], args[2], obj_length)
300300

301-
if (args[0]->IsString()) {
302-
String::AsciiValue at(args[0]);
303-
value = (*at)[0];
304-
} else {
305-
value = static_cast<char>(args[0]->Int32Value());
301+
if (args[0]->IsNumber()) {
302+
int value = args[0]->Uint32Value() & 255;
303+
memset(obj_data + start, value, length);
304+
return args.This();
306305
}
307306

308-
SLICE_START_END(args[1], args[2], obj_length)
307+
String::Utf8Value at(args[0]);
308+
size_t at_length = at.length();
309+
310+
// optimize single ascii character case
311+
if (at_length == 1) {
312+
int value = static_cast<int>((*at)[0]);
313+
memset(obj_data + start, value, length);
314+
return args.This();
315+
}
316+
317+
size_t in_there = at_length;
318+
char* ptr = obj_data + start + at_length;
309319

310-
memset(obj_data + start, value, length);
320+
memcpy(obj_data + start, *at, MIN(at_length, length));
321+
322+
if (at_length >= length)
323+
return args.This();
324+
325+
while (in_there < length - in_there) {
326+
memcpy(ptr, obj_data + start, in_there);
327+
ptr += in_there;
328+
in_there *= 2;
329+
}
330+
331+
if (in_there < length) {
332+
memcpy(ptr, obj_data + start, length - in_there);
333+
in_there = length;
334+
}
311335

312336
return args.This();
313337
}

test/simple/test-buffer.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ for (var i = 0; i < b.length; i++) {
120120
assert.strictEqual(cntr, b[i]);
121121
}
122122

123+
// copy string longer than buffer length (failure will segfault)
124+
var bb = new Buffer(10);
125+
bb.fill('hello crazy world');
126+
123127

124128
var caught_error = null;
125129

@@ -637,6 +641,12 @@ for (var i = 0; i < 16; i++) assert.equal(0, b[i]);
637641
for (; i < 32; i++) assert.equal(1, b[i]);
638642
for (; i < b.length; i++) assert.equal(0, b[i]);
639643

644+
var buf = new Buffer(10);
645+
buf.fill('abc');
646+
assert.equal(buf.toString(), 'abcabcabca');
647+
buf.fill('է');
648+
assert.equal(buf.toString(), 'էէէէէ');
649+
640650
['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach(function(encoding) {
641651
var b = new Buffer(10);
642652
b.write('あいうえお', encoding);

0 commit comments

Comments
 (0)