Skip to content

Commit ce39700

Browse files
committed
Fix utf8-decode on CombinedBuffers for nodejs.
1 parent a203f50 commit ce39700

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

lib/internal/utf8.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
// with the Buffer API defined in buf.js
2222

2323
import buf from "./buf";
24+
import {StringDecoder} from 'string_decoder';
2425
let platformObj = {};
2526

27+
2628
try {
2729
// This will throw an exception is 'buffer' is not available
2830
require.resolve("buffer");
29-
31+
let decoder = new StringDecoder('utf8');
3032
let node = require("buffer");
3133

3234
platformObj = {
@@ -39,7 +41,27 @@ try {
3941
end = start + length;
4042
buffer.position = end;
4143
return buffer._buffer.toString( 'utf8', start, end );
42-
} else {
44+
}
45+
else if( buffer instanceof buf.CombinedBuffer ) {
46+
let remainingBytesToRead = length;
47+
// Reduce CombinedBuffers to a decoded string
48+
let out = buffer._buffers.reduce(function(last, partBuffer){
49+
if(remainingBytesToRead <= 0) {
50+
return last;
51+
}
52+
if(partBuffer.length > remainingBytesToRead) { // When we don't want the whole buffer
53+
let lastSlice = partBuffer.readSlice(remainingBytesToRead);
54+
partBuffer._updatePos(remainingBytesToRead);
55+
remainingBytesToRead = 0;
56+
return last + decoder.write(lastSlice._buffer);
57+
}
58+
remainingBytesToRead -= partBuffer.length;
59+
return last + decoder.write(partBuffer._buffer);
60+
}, '');
61+
out += decoder.end();
62+
return out;
63+
}
64+
else {
4365
throw new Error( "Don't know how to decode strings from `" + buffer + "`.");
4466
}
4567
}

test/internal/utf8.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
var utf8 = require('../../build/node/internal/utf8');
3+
var buffers = require('../../build/node/internal/buf');
34

45
describe('utf8', function() {
56
it('should have a nice clean buffer position after serializing', function() {
@@ -14,6 +15,40 @@ describe('utf8', function() {
1415
expect( packAndUnpack( "" ) ).toBe( "" );
1516
expect( packAndUnpack( "åäö123" ) ).toBe( "åäö123" );
1617
});
18+
19+
it('should read/write utf8 from a complete combined buffer', function() {
20+
// Given
21+
var msg = "asåfqwer";
22+
var buf = utf8.encode(msg);
23+
var bufa = buf.readSlice(3);
24+
var bufb = buf.readSlice(3);
25+
var bufc = buf.readSlice(3);
26+
var combined = new buffers.CombinedBuffer( [bufa, bufb, bufc] );
27+
28+
// When
29+
var decoded = utf8.decode(combined, combined.length);
30+
31+
// Then
32+
expect(decoded).toBe(msg);
33+
});
34+
35+
it('should read/write utf8 from part of a combined buffer', function() {
36+
// Given
37+
var msg = "asåfq";
38+
var expectMsg = msg.substring(0, msg.length-1);
39+
var buf = utf8.encode(msg);
40+
var bufa = buf.readSlice(3);
41+
var bufb = buf.readSlice(3);
42+
var unrelatedData = buffers.alloc(3);
43+
var combined = new buffers.CombinedBuffer( [bufa, bufb, unrelatedData] );
44+
45+
// When
46+
// We read all but the unrelatedData and the last character of bufb
47+
var decoded = utf8.decode(combined, combined.length - 1 - unrelatedData.length );
48+
49+
// Then
50+
expect(decoded).toBe(expectMsg);
51+
});
1752
});
1853

1954
function packAndUnpack( str ) {

0 commit comments

Comments
 (0)