diff --git a/lib/string_decoder.js b/lib/string_decoder.js index 6eb71efc07d803..932f31971606cc 100644 --- a/lib/string_decoder.js +++ b/lib/string_decoder.js @@ -122,24 +122,39 @@ function utf8CheckIncomplete(self, buf, i) { return 0; var nb = utf8CheckByte(buf[j--]); if (nb >= 0) { - if (nb > 0) + if (nb > 0) { self.lastNeed = nb + 1 - (buf.length - j); + if (self.lastNeed < 0) { + self.lastNeed = 0; + nb = 0; + } + } return nb; } if (j < i) return 0; nb = utf8CheckByte(buf[j--]); if (nb >= 0) { - if (nb > 0) + if (nb > 0) { self.lastNeed = nb + 1 - (buf.length - j); + if (self.lastNeed < 0) { + self.lastNeed = 0; + nb = 0; + } + } return nb; } if (j < i) return 0; nb = utf8CheckByte(buf[j--]); if (nb >= 0) { - if (nb > 0) + if (nb > 0) { self.lastNeed = nb + 1 - (buf.length - j); + if (self.lastNeed < 0) { + self.lastNeed = 0; + nb = 0; + } + } return nb; } return 0; diff --git a/test/parallel/test-string-decoder.js b/test/parallel/test-string-decoder.js index 14933c46fcd888..95ff3dbfa51aa3 100644 --- a/test/parallel/test-string-decoder.js +++ b/test/parallel/test-string-decoder.js @@ -55,9 +55,14 @@ assert.strictEqual(decoder.write(Buffer.from('\ufffd\ufffd\ufffd')), assert.strictEqual(decoder.end(), ''); decoder = new StringDecoder('utf8'); -assert.strictEqual(decoder.write(Buffer.from('efbfbde2', 'hex')), '\ufffd'); +assert.strictEqual(decoder.write(Buffer.from('EFBFBDE2', 'hex')), '\ufffd'); assert.strictEqual(decoder.end(), '\ufffd'); +decoder = new StringDecoder('utf8'); +assert.strictEqual(decoder.write(Buffer.from('C9B5A9', 'hex')), 'ɵ\ufffd'); +assert.strictEqual(decoder.write(Buffer.from('41', 'hex')), 'A'); +assert.strictEqual(decoder.end(), ''); + // Additional UTF-16LE surrogate pair tests decoder = new StringDecoder('utf16le');