Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

smtp-address-parser

Package Overview
Dependencies
Maintainers
0
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

smtp-address-parser - npm Package Compare versions

Comparing version 1.0.10 to 1.1.0

26

dist/lib/index.js

@@ -14,2 +14,7 @@ "use strict";

function parse(address) {
// An insane length, to protect the parsing code from huge input. SMTP line limit, minus command size.
const insane_length = 1000 - "MAIL FROM:<>\r\n".length;
if (address.length > insane_length) {
throw new Error("address too long");
}
const parser = new nearley.Parser(grammar);

@@ -20,2 +25,23 @@ parser.feed(address);

}
// Domain checks
const at_idx = address.lastIndexOf('@'); // must be found, since parse was successful
const domain = address.substring(at_idx + 1);
if (domain[0] !== '[') { // Not an address literal
if (domain.length > 253) {
throw new Error("domain too long");
}
const labels = domain.split(".");
if (labels.length < 2) {
throw new Error("domain not fully qualified");
}
if (labels[labels.length - 1].length < 2) {
throw new Error("top level domain label too short");
}
labels.sort(function (a, b) {
return b.length - a.length;
});
if (labels[0].length > 63) {
throw new Error("domain label too long");
}
}
return parser.results[0];

@@ -22,0 +48,0 @@ }

29

dist/test/addresses.test.js

@@ -25,5 +25,2 @@ "use strict";

});
it("local domain name with no TLD", function () {
_check("admin@mailserver1", "admin", undefined, "mailserver1", undefined);
});
it("space between the quotes", function () {

@@ -35,2 +32,8 @@ _check('" "@example.org', undefined, '" "', "example.org", undefined);

});
it("quoted string with angle brackets", function () {
_check('"<john-doe>"@example.org', undefined, '"<john-doe>"', "example.org", undefined);
});
it("quoted string with backslash escape", function () {
_check('"\\<john-doe\\>"@example.org', undefined, '"\\<john-doe\\>"', "example.org", undefined);
});
it('address in quoted local-part "john.doe@example.org"@example.org', function () {

@@ -74,2 +77,7 @@ _check('"john.doe@example.org"@example.org', undefined, '"john.doe@example.org"', "example.org", undefined);

describe("bad addresses fail", function () {
it("local domain name with no TLD", function () {
assert.throws(function () {
parse("admin@mailserver1"); // Now fails.
});
});
it('"foo@example.com+bob@attacker.com" is not an address', function () {

@@ -167,2 +175,17 @@ assert.throws(function () {

});
it("domain too long", function () {
assert.throws(function () {
parse("local-part@XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.xyz");
});
});
it("tld too short", function () {
assert.throws(function () {
parse("tld-too-short@foo.x");
});
});
it("label too long", function () {
assert.throws(function () {
parse("local-part@label_too_long_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.xyz");
});
});
});

@@ -169,0 +192,0 @@ describe("test normalize", function () {

@@ -13,2 +13,10 @@ "use strict";

export function parse(address: string) {
// An insane length, to protect the parsing code from huge input. SMTP line limit, minus command size.
const insane_length = 1000 - "MAIL FROM:<>\r\n".length;
if (address.length > insane_length) {
throw new Error("address too long");
}
const parser = new nearley.Parser(grammar);

@@ -21,2 +29,25 @@ parser.feed(address);

// Domain checks
const at_idx = address.lastIndexOf('@'); // must be found, since parse was successful
const domain = address.substring(at_idx + 1);
if (domain[0] !== '[') { // Not an address literal
if (domain.length > 253) {
throw new Error("domain too long");
}
const labels = domain.split(".");
if (labels.length < 2) {
throw new Error("domain not fully qualified");
}
if (labels[labels.length - 1].length < 2) {
throw new Error("top level domain label too short");
}
labels.sort(function(a: string, b: string) {
return b.length - a.length;
});
if (labels[0].length > 63) {
throw new Error("domain label too long");
}
}
return parser.results[0];

@@ -23,0 +54,0 @@ }

2

package.json
{
"name": "smtp-address-parser",
"version": "1.0.10",
"version": "1.1.0",
"description": "Parse an SMTP (RFC-5321) address",

@@ -5,0 +5,0 @@ "main": "dist/lib/index.js",

@@ -9,17 +9,23 @@ # smtp-address-parser

Length limitations are not checked.
** Changes in version 1.1.0: **
Technically a local-part of a Mailbox address is limited to 64 octets
or less, see: <https://tools.ietf.org/html/rfc5321#section-4.5.3.1.1>
** Domains are now checked beyond RFC-5321 syntax only **
Also, domain names are limited to 255 octets, see:
<https://tools.ietf.org/html/rfc5321#section-4.5.3.1.2>
Domain names must be fully qualified; that is with at least two labels. The top-level domain must have at least two octets.
And individual labels within a domain name are limited to 63
octets or less, see:
<https://tools.ietf.org/html/rfc1035> section 2.3.4. Size limits
** Length limitations are now checked **
However, RFC-5321 section 4.5.3.1. “Size Limits and Minimums” says:
Total length limit of an address is 986 octets; based on a 1,000 octet SMTP line length.
See <https://tools.ietf.org/html/rfc1035> section 2.3.4. Size limits:
Domain names are limited to 255 octets, when encoded with a length byte before each label, and including the top-level zero length label. So, the effctive limit with interstitial dots is 253 octets.
Labels within a domain name are limited to 63 octets.
The above are limits of the DNS protocol, not any particular implementation.
RFC-5321 section 4.5.3.1. “Size Limits and Minimums” still says:
“To the maximum extent possible, implementation techniques that impose
no limits on the length of these objects should be used.”

@@ -42,5 +42,2 @@ "use strict";

});
it("local domain name with no TLD", function () {
_check("admin@mailserver1", "admin", undefined, "mailserver1", undefined);
});
it("space between the quotes", function () {

@@ -52,2 +49,8 @@ _check('" "@example.org', undefined, '" "', "example.org", undefined);

});
it("quoted string with angle brackets", function () {
_check('"<john-doe>"@example.org', undefined, '"<john-doe>"', "example.org", undefined);
});
it("quoted string with backslash escape", function () {
_check('"\\<john-doe\\>"@example.org', undefined, '"\\<john-doe\\>"', "example.org", undefined);
});
it('address in quoted local-part "john.doe@example.org"@example.org', function () {

@@ -92,2 +95,7 @@ _check('"john.doe@example.org"@example.org', undefined, '"john.doe@example.org"', "example.org", undefined);

describe("bad addresses fail", function () {
it("local domain name with no TLD", function () {
assert.throws(function () {
parse("admin@mailserver1"); // Now fails.
});
});
it('"foo@example.com+bob@attacker.com" is not an address', function () {

@@ -185,2 +193,17 @@ assert.throws(function () {

});
it("domain too long", function () {
assert.throws(function () {
parse("local-part@XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.xyz");
});
});
it("tld too short", function () {
assert.throws(function () {
parse("tld-too-short@foo.x");
});
});
it("label too long", function () {
assert.throws(function () {
parse("local-part@label_too_long_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.xyz");
});
});
});

@@ -187,0 +210,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc