Skip to content

Commit 629928b

Browse files
authored
fix: ZMS-47: Fix utf-8 header round-trip in Headers.add() (#46)
* ZMS-47: Fix utf-8 header round-trip in Headers.add() * bump deps
1 parent b4490c4 commit 629928b

4 files changed

Lines changed: 249 additions & 160 deletions

File tree

lib/headers.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class Headers {
4242
this._parseHeaders();
4343
}
4444
key = this._normalizeHeader(key);
45-
let lines = this.lines.filter(line => line.key === key).map(line => line.line);
45+
let lines = this.lines.filter(line => line.key === key).map(line => this._decodeHeaderValue(line.line));
4646

4747
return lines;
4848
}
@@ -62,7 +62,7 @@ class Headers {
6262
if (!header) {
6363
return '';
6464
}
65-
return ((this.libmime.decodeHeader(header.line) || {}).value || '').toString().trim();
65+
return ((this.libmime.decodeHeader(this._decodeHeaderValue(header.line)) || {}).value || '').toString().trim();
6666
}
6767

6868
getList() {
@@ -174,17 +174,27 @@ class Headers {
174174

175175
lineEnd = lineEnd || '\r\n';
176176

177-
let headers = this.lines.map(line => line.line.replace(/\r?\n/g, lineEnd)).join(lineEnd) + `${lineEnd}${lineEnd}`;
177+
let headers = this.lines
178+
.map(line => this._buildHeaderLine(line.line.replace(/\r?\n/g, lineEnd)))
179+
.reduce((joined, line, idx) => {
180+
if (idx) {
181+
joined.push(Buffer.from(lineEnd, 'binary'));
182+
}
183+
joined.push(line);
184+
return joined;
185+
}, []);
186+
187+
headers.push(Buffer.from(lineEnd + lineEnd, 'binary'));
178188

179189
if (this.mbox) {
180-
headers = this.mbox + lineEnd + headers;
190+
headers.unshift(Buffer.from(this.mbox + lineEnd, 'binary'));
181191
}
182192

183193
if (this.http) {
184-
headers = this.http + lineEnd + headers;
194+
headers.unshift(Buffer.from(this.http + lineEnd, 'binary'));
185195
}
186196

187-
return Buffer.from(headers, 'binary');
197+
return Buffer.concat(headers);
188198
}
189199

190200
_normalizeHeader(key) {
@@ -232,6 +242,20 @@ class Headers {
232242
this.lines = lines;
233243
this.parsed = true;
234244
}
245+
246+
_buildHeaderLine(line) {
247+
let value = this._decodeHeaderValue(line);
248+
return Buffer.from(value, value === line ? 'binary' : 'utf8');
249+
}
250+
251+
_decodeHeaderValue(str) {
252+
if (!str) {
253+
return str;
254+
}
255+
256+
let utf8 = Buffer.from(str, 'binary').toString('utf8');
257+
return utf8.includes('\uFFFD') ? str : utf8;
258+
}
235259
}
236260

237261
// expose to the world

0 commit comments

Comments
 (0)