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

Commit

Permalink
readline: use StringDecoder for decoding "normal" data
Browse files Browse the repository at this point in the history
The fix from #3059 was not handling multi-byte utf8 data properly.
  • Loading branch information
TooTallNate committed Apr 6, 2012
1 parent 8652c11 commit 78eb174
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
23 changes: 15 additions & 8 deletions lib/readline.js
Expand Up @@ -93,6 +93,8 @@ function Interface(input, output, completer, terminal) {
input.on('end', function() {
self.emit('end');
});
var StringDecoder = require('string_decoder').StringDecoder; // lazy load
this._decoder = new StringDecoder('utf8');

} else {

Expand Down Expand Up @@ -264,22 +266,27 @@ Interface.prototype.write = function(d, key) {
this.terminal ? this._ttyWrite(d, key) : this._normalWrite(d, key);
};

// telnet on windows sends every single keystroke seperately, so we need
// to buffer them and only fire the 'line' event when a \n is sent
Interface.prototype._line_buffer = '';

Interface.prototype._normalWrite = function(b) {
if (b === undefined) {
return;
}
this._line_buffer += b.toString();
if (this._line_buffer.indexOf('\n') !== -1) {
var lines = this._line_buffer.split('\n');
var string = this._decoder.write(b);
if (this._line_buffer) {
string = this._line_buffer + string;
this._line_buffer = null;
}
if (string.indexOf('\n') !== -1) {
// got one or more newlines; process into "line" events
var lines = string.split('\n');
// either '' or (concievably) the unfinished portion of the next line
this._line_buffer = lines.pop();
string = lines.pop();
this._line_buffer = string;
lines.forEach(function(line) {
this._onLine(line + '\n');
}, this);
} else if (string) {
// no newlines this time, save what we have for next time
this._line_buffer = string;
}
};

Expand Down
16 changes: 16 additions & 0 deletions test/simple/test-readline-interface.js
Expand Up @@ -104,3 +104,19 @@ rli.on('line', function(line) {
});
fi.emit('data', expectedLines.join(''));
assert.equal(callCount, expectedLines.length - 1);

// sending a multi-byte utf8 char over multiple writes
var buf = Buffer('☮', 'utf8');
fi = new FakeInput();
rli = new readline.Interface(fi, {});
callCount = 0;
rli.on('line', function(line) {
callCount++;
assert.equal(line, buf.toString('utf8') + '\n');
});
[].forEach.call(buf, function(i) {
fi.emit('data', Buffer([i]));
});
assert.equal(callCount, 0);
fi.emit('data', '\n');
assert.equal(callCount, 1);

0 comments on commit 78eb174

Please sign in to comment.