Skip to content

Commit

Permalink
allow attachment filenames containing semicolons (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
DoobleD authored Sep 27, 2024
1 parent cf9fa09 commit 962680a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).

### Unreleased

### [1.2.4] - 2024-09-27
- allow attachment filenames containing semicolons https://github.com/haraka/email-message/issues/12

### [1.2.3] - 2024-04-24

- style(es6): replace forEach with for...of
Expand Down
9 changes: 6 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -438,17 +438,20 @@ class Body extends events.EventEmitter {
}
this.ct = ct;

const buildRegex = (key) => new RegExp(`${key}\\s*=\\s*"([^"]+)"|${key}\\s*=\\s*"?([^";]+)"?`, 'i');
const matchKey = (test, key) => test.match(buildRegex(key))?.filter(item => item);

let match;
if (/^(?:text|message)\//i.test(ct) && !/^attachment/i.test(cd)) {
this.state = 'body';
} else if (/^multipart\//i.test(ct)) {
match = ct.match(/boundary\s*=\s*"?([^";]+)"?/i);
match = matchKey(ct, 'boundary');
this.boundary = match ? match[1] : '';
this.state = 'multipart_preamble';
} else {
match = cd.match(/name\s*=\s*"?([^";]+)"?/i);
match = matchKey(cd, 'name');
if (!match) {
match = ct.match(/name\s*=\s*"?([^";]+)"?/i);
match = matchKey(ct, 'name');
}
const filename = match ? match[1] : '';
this.attachment_stream = exports.createAttachmentStream(this.header);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "haraka-email-message",
"version": "1.2.3",
"version": "1.2.4",
"description": "Haraka email message",
"main": "index.js",
"files": [
Expand Down
64 changes: 64 additions & 0 deletions test/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,4 +406,68 @@ describe('body', function () {
done();
});
});

describe('attachments', function () {
describe('content-type-name', function () {
it('with-quotes', function (done) {
const body = new Body();
body.on('attachment_start', (ct, filename) => {
assert.equal(filename, 'aaaa.zip');
done();
});
body.header.parse([
'Content-Type: application/zip; name="aaaa.zip"'
]);
body.parse_start('');
});

it('without-quotes', function (done) {
const body = new Body();
body.on('attachment_start', (ct, filename) => {
assert.equal(filename, 'aaaa.zip');
done();
});
body.header.parse([
'Content-Type: application/zip; name=aaaa.zip'
]);
body.parse_start('');
});

it('with-quotes-and-semicolons', function (done) {
const body = new Body();
body.on('attachment_start', (ct, filename) => {
assert.equal(filename, 'aaaa; bbb; cccc.zip');
done();
});
body.header.parse([
'Content-Type: application/zip; name="aaaa; bbb; cccc.zip"'
]);
body.parse_start('');
});

it('with-one-quote-left', function (done) {
const body = new Body();
body.on('attachment_start', (ct, filename) => {
assert.equal(filename, 'aaaa');
done();
});
body.header.parse([
'Content-Type: application/zip; name="aaaa; bbb; cccc.zip'
]);
body.parse_start('');
});

it('with-one-quote-right', function (done) {
const body = new Body();
body.on('attachment_start', (ct, filename) => {
assert.equal(filename, 'aaaa');
done();
});
body.header.parse([
'Content-Type: application/zip; name=aaaa; bbb; cccc.zip"'
]);
body.parse_start('');
});
});
});
});

0 comments on commit 962680a

Please sign in to comment.