Comparing version 2.1.0 to 2.1.1
# Changelog | ||
## [2.1.1](https://github.com/nodemailer/libqp/compare/v2.1.0...v2.1.1) (2024-11-29) | ||
### Bug Fixes | ||
* **decode-stream:** Fix issue where some whitespace characters were lost ([2231159](https://github.com/nodemailer/libqp/commit/2231159f38e865ef8cf4f7f8bf28cabc00217ffe)) | ||
## [2.1.0](https://github.com/nodemailer/libqp/compare/v2.0.1...v2.1.0) (2024-02-23) | ||
@@ -4,0 +11,0 @@ |
@@ -258,2 +258,3 @@ /* eslint no-useless-escape: 0 */ | ||
* Creates a transform stream for decoding Quoted-Printable encoded strings | ||
* The input is not actually processed as a stream but concatted and processed as a single input | ||
* | ||
@@ -274,9 +275,7 @@ * @constructor | ||
this.outputBytes = 0; | ||
this.qpChunks = []; | ||
} | ||
_transform(chunk, encoding, done) { | ||
let qp, buf; | ||
chunk = chunk.toString('ascii'); | ||
if (!chunk || !chunk.length) { | ||
@@ -286,17 +285,9 @@ return done(); | ||
if (typeof chunk === 'string') { | ||
chunk = Buffer.from(chunk, encoding); | ||
} | ||
this.qpChunks.push(chunk); | ||
this.inputBytes += chunk.length; | ||
qp = this._curLine + chunk; | ||
this._curLine = ''; | ||
qp = qp.replace(/\=[^\n]?$/, lastLine => { | ||
this._curLine = lastLine; | ||
return ''; | ||
}); | ||
if (qp) { | ||
buf = decode(qp); | ||
this.outputBytes += buf.length; | ||
this.push(buf); | ||
} | ||
done(); | ||
@@ -306,8 +297,8 @@ } | ||
_flush(done) { | ||
let buf; | ||
if (this._curLine) { | ||
buf = decode(this._curLine); | ||
if (this.inputBytes) { | ||
let buf = decode(Buffer.concat(this.qpChunks, this.inputBytes).toString()); | ||
this.outputBytes += buf.length; | ||
this.push(buf); | ||
} | ||
done(); | ||
@@ -314,0 +305,0 @@ } |
{ | ||
"name": "libqp", | ||
"version": "2.1.0", | ||
"version": "2.1.1", | ||
"description": "Encode and decode quoted-printable strings according to rfc2045", | ||
@@ -5,0 +5,0 @@ "main": "lib/libqp.js", |
@@ -42,1 +42,161 @@ 'use strict'; | ||
}); | ||
test('Decoding tests', async t => { | ||
// Example taken from RFC2045 section 6.7 | ||
const encoded = | ||
"Now's the time =\r\n" + | ||
"for all folk to come=\r\n" + | ||
" to the aid of their country." | ||
const expectedDecoded = | ||
"Now's the time for all folk to come to the aid of their country." | ||
await t.test('simple string', async () => { | ||
const decoded = libqp.decode(encoded).toString(); | ||
assert.strictEqual(decoded, expectedDecoded); | ||
}); | ||
await t.test('stream', async () => { | ||
const decoder = new libqp.Decoder(); | ||
const decoded = await new Promise((resolve, reject) => { | ||
const chunks = []; | ||
decoder.on('readable', () => { | ||
let chunk; | ||
while ((chunk = decoder.read()) !== null) { | ||
chunks.push(chunk); | ||
} | ||
}); | ||
decoder.on('end', () => { | ||
resolve(Buffer.concat(chunks).toString()); | ||
}); | ||
decoder.on('Error', err => { | ||
reject(err); | ||
}); | ||
decoder.end(Buffer.from(encoded)); | ||
}); | ||
assert.strictEqual(decoded, expectedDecoded); | ||
}); | ||
await t.test('stream, multiple chunks', async () => { | ||
const encodedChunk1Length = 3; | ||
const encodedChunk1 = encoded.substring(0, encodedChunk1Length) | ||
const encodedChunk2 = encoded.substring(encodedChunk1Length) | ||
const decoder = new libqp.Decoder(); | ||
const decoded = await new Promise((resolve, reject) => { | ||
const chunks = []; | ||
decoder.on('readable', () => { | ||
let chunk; | ||
while ((chunk = decoder.read()) !== null) { | ||
chunks.push(chunk); | ||
} | ||
}); | ||
decoder.on('end', () => { | ||
resolve(Buffer.concat(chunks).toString()); | ||
}); | ||
decoder.on('Error', err => { | ||
reject(err); | ||
}); | ||
decoder.write(Buffer.from(encodedChunk1)); | ||
decoder.end(Buffer.from(encodedChunk2)); | ||
}); | ||
assert.strictEqual(decoded, expectedDecoded); | ||
}); | ||
await t.test('stream, space at end of chunk', async () => { | ||
const encodedChunk1Length = encoded.indexOf(' ') + 1; | ||
const encodedChunk1 = encoded.substring(0, encodedChunk1Length) | ||
const encodedChunk2 = encoded.substring(encodedChunk1Length) | ||
const decoder = new libqp.Decoder(); | ||
const decoded = await new Promise((resolve, reject) => { | ||
const chunks = []; | ||
decoder.on('readable', () => { | ||
let chunk; | ||
while ((chunk = decoder.read()) !== null) { | ||
chunks.push(chunk); | ||
} | ||
}); | ||
decoder.on('end', () => { | ||
resolve(Buffer.concat(chunks).toString()); | ||
}); | ||
decoder.on('Error', err => { | ||
reject(err); | ||
}); | ||
decoder.write(Buffer.from(encodedChunk1)); | ||
decoder.end(Buffer.from(encodedChunk2)); | ||
}); | ||
assert.strictEqual(decoded, expectedDecoded); | ||
}); | ||
await t.test('stream, soft line break equals sign at end of chunk', async () => { | ||
const encodedChunk1Length = encoded.indexOf('=') + 1; | ||
const encodedChunk1 = encoded.substring(0, encodedChunk1Length) | ||
const encodedChunk2 = encoded.substring(encodedChunk1Length) | ||
const decoder = new libqp.Decoder(); | ||
const decoded = await new Promise((resolve, reject) => { | ||
const chunks = []; | ||
decoder.on('readable', () => { | ||
let chunk; | ||
while ((chunk = decoder.read()) !== null) { | ||
chunks.push(chunk); | ||
} | ||
}); | ||
decoder.on('end', () => { | ||
resolve(Buffer.concat(chunks).toString()); | ||
}); | ||
decoder.on('Error', err => { | ||
reject(err); | ||
}); | ||
decoder.write(Buffer.from(encodedChunk1)); | ||
decoder.end(Buffer.from(encodedChunk2)); | ||
}); | ||
assert.strictEqual(decoded, expectedDecoded); | ||
}); | ||
await t.test('stream, CR at end of chunk', async () => { | ||
const encodedChunk1Length = encoded.indexOf('\r') + 1; | ||
const encodedChunk1 = encoded.substring(0, encodedChunk1Length) | ||
const encodedChunk2 = encoded.substring(encodedChunk1Length) | ||
const decoder = new libqp.Decoder(); | ||
const decoded = await new Promise((resolve, reject) => { | ||
const chunks = []; | ||
decoder.on('readable', () => { | ||
let chunk; | ||
while ((chunk = decoder.read()) !== null) { | ||
chunks.push(chunk); | ||
} | ||
}); | ||
decoder.on('end', () => { | ||
resolve(Buffer.concat(chunks).toString()); | ||
}); | ||
decoder.on('Error', err => { | ||
reject(err); | ||
}); | ||
decoder.write(Buffer.from(encodedChunk1)); | ||
decoder.end(Buffer.from(encodedChunk2)); | ||
}); | ||
assert.strictEqual(decoded, expectedDecoded); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22312
433