Skip to content

Commit 9af1e4b

Browse files
jridgewellMylesBorins
authored andcommitted
string_decoder: reset decoder on end
This resets the StringDecoder's state after calling `#end`. Further writes to the decoder will act as if it were a brand new instance, allowing simple reuse. PR-URL: #18494Fixes: #16564 Refs: #16594 Reviewed-By: Tiancheng "Timothy" Gu <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 25a7bde commit 9af1e4b

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

‎lib/string_decoder.js‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,11 @@ function utf8Text(buf, i){
210210
// character.
211211
functionutf8End(buf){
212212
constr=(buf&&buf.length ? this.write(buf) : '');
213-
if(this.lastNeed)
213+
if(this.lastNeed){
214+
this.lastNeed=0;
215+
this.lastTotal=0;
214216
returnr+'\ufffd';
217+
}
215218
returnr;
216219
}
217220

@@ -246,6 +249,8 @@ function utf16End(buf){
246249
constr=(buf&&buf.length ? this.write(buf) : '');
247250
if(this.lastNeed){
248251
constend=this.lastTotal-this.lastNeed;
252+
this.lastNeed=0;
253+
this.lastTotal=0;
249254
returnr+this.lastChar.toString('utf16le',0,end);
250255
}
251256
returnr;
@@ -269,8 +274,12 @@ function base64Text(buf, i){
269274

270275
functionbase64End(buf){
271276
constr=(buf&&buf.length ? this.write(buf) : '');
272-
if(this.lastNeed)
273-
returnr+this.lastChar.toString('base64',0,3-this.lastNeed);
277+
if(this.lastNeed){
278+
constend=3-this.lastNeed;
279+
this.lastNeed=0;
280+
this.lastTotal=0;
281+
returnr+this.lastChar.toString('base64',0,end);
282+
}
274283
returnr;
275284
}
276285

‎test/parallel/test-string-decoder-end.js‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,46 @@ for (let i = 1; i <= 16; i++){
3939

4040
encodings.forEach(testEncoding);
4141

42+
testEnd('utf8',Buffer.of(0xE2),Buffer.of(0x61),'\uFFFDa');
43+
testEnd('utf8',Buffer.of(0xE2),Buffer.of(0x82),'\uFFFD\uFFFD');
44+
testEnd('utf8',Buffer.of(0xE2),Buffer.of(0xE2),'\uFFFD\uFFFD');
45+
testEnd('utf8',Buffer.of(0xE2,0x82),Buffer.of(0x61),'\uFFFDa');
46+
testEnd('utf8',Buffer.of(0xE2,0x82),Buffer.of(0xAC),'\uFFFD\uFFFD');
47+
testEnd('utf8',Buffer.of(0xE2,0x82),Buffer.of(0xE2),'\uFFFD\uFFFD');
48+
testEnd('utf8',Buffer.of(0xE2,0x82,0xAC),Buffer.of(0x61),'€a');
49+
50+
testEnd('utf16le',Buffer.of(0x3D),Buffer.of(0x61,0x00),'a');
51+
testEnd('utf16le',Buffer.of(0x3D),Buffer.of(0xD8,0x4D,0xDC),'\u4DD8');
52+
testEnd('utf16le',Buffer.of(0x3D,0xD8),Buffer.of(),'\uD83D');
53+
testEnd('utf16le',Buffer.of(0x3D,0xD8),Buffer.of(0x61,0x00),'\uD83Da');
54+
testEnd(
55+
'utf16le',
56+
Buffer.of(0x3D,0xD8),
57+
Buffer.of(0x4D,0xDC),
58+
'\uD83D\uDC4D'
59+
);
60+
testEnd('utf16le',Buffer.of(0x3D,0xD8,0x4D),Buffer.of(),'\uD83D');
61+
testEnd(
62+
'utf16le',
63+
Buffer.of(0x3D,0xD8,0x4D),
64+
Buffer.of(0x61,0x00),
65+
'\uD83Da'
66+
);
67+
testEnd('utf16le',Buffer.of(0x3D,0xD8,0x4D),Buffer.of(0xDC),'\uD83D');
68+
testEnd(
69+
'utf16le',
70+
Buffer.of(0x3D,0xD8,0x4D,0xDC),
71+
Buffer.of(0x61,0x00),
72+
'👍a'
73+
);
74+
75+
testEnd('base64',Buffer.of(0x61),Buffer.of(),'YQ==');
76+
testEnd('base64',Buffer.of(0x61),Buffer.of(0x61),'YQ==YQ==');
77+
testEnd('base64',Buffer.of(0x61,0x61),Buffer.of(),'YWE=');
78+
testEnd('base64',Buffer.of(0x61,0x61),Buffer.of(0x61),'YWE=YQ==');
79+
testEnd('base64',Buffer.of(0x61,0x61,0x61),Buffer.of(),'YWFh');
80+
testEnd('base64',Buffer.of(0x61,0x61,0x61),Buffer.of(0x61),'YWFhYQ==');
81+
4282
functiontestEncoding(encoding){
4383
bufs.forEach((buf)=>{
4484
testBuf(encoding,buf);
@@ -66,3 +106,14 @@ function testBuf(encoding, buf){
66106
assert.strictEqual(res1,res3,'one byte at a time should match toString');
67107
assert.strictEqual(res2,res3,'all bytes at once should match toString');
68108
}
109+
110+
functiontestEnd(encoding,incomplete,next,expected){
111+
letres='';
112+
consts=newSD(encoding);
113+
res+=s.write(incomplete);
114+
res+=s.end();
115+
res+=s.write(next);
116+
res+=s.end();
117+
118+
assert.strictEqual(res,expected);
119+
}

0 commit comments

Comments
(0)