Browse Source

[Feature] Add parsers for SMTP address in ragel

tags/1.3.0
Vsevolod Stakhov 8 years ago
parent
commit
6832271dbc
3 changed files with 146 additions and 0 deletions
  1. 77
    0
      src/ragel/smtp_addr_parser.rl
  2. 50
    0
      src/ragel/smtp_address.rl
  3. 19
    0
      src/ragel/smtp_ip.rl

+ 77
- 0
src/ragel/smtp_addr_parser.rl View File

@@ -0,0 +1,77 @@
%%{

machine smtp_addr_parser;

action User_start {
addr->user = p;
addr->addr = p;
}

action User_end {
if (addr->user) {
addr->user_len = p - addr->user;
}
}

action Domain_start {
addr->domain = p;
}

action Domain_end {
if (addr->domain) {
addr->domain_len = p - addr->domain;
}
}

action Domain_addr_start {
addr->domain = p;
addr->flags |= RSPAMD_EMAIL_ADDR_IP;
}

action Domain_addr_end {
if (addr->domain) {
addr->domain_len = p - addr->domain;
}
}

action Quoted_addr {
addr->flags |= RSPAMD_EMAIL_ADDR_QUOTED;
}

action Empty_addr {
addr->flags |= RSPAMD_EMAIL_ADDR_EMPTY;
addr->addr = "";
}

action Valid_addr {
addr->flags |= RSPAMD_EMAIL_ADDR_VALID;
}

action Angled_addr {
addr->flags |= RSPAMD_EMAIL_ADDR_BRACED;
}

include smtp_address "smtp_address.rl";

main := SMTPAddr;
}%%

%% write data;

static int
rspamd_smtp_addr_parse (const char *data, size_t len, struct rspamd_email_address *addr)
{
const char *p = data, *pe = data + len, *eof;
int cs;

g_assert (addr != NULL);
memset (addr, 0, sizeof (*addr));
addr->raw = data;
addr->raw_len = len;
eof = pe;

%% write init;
%% write exec;

return cs;
}

+ 50
- 0
src/ragel/smtp_address.rl View File

@@ -0,0 +1,50 @@
%%{
machine smtp_address;

include smtp_ip "smtp_ip.rl";

# SMTP address spec
# Obtained from: https://tools.ietf.org/html/rfc5321#section-4.1.2

LF = "\n";
CR = "\r";
CRLF = "\r\n";
DQUOTE = '"';

atext = alpha | digit | "!" | "#" | "$" | "%" | "&" |
"'" | "*" | "+" | "_" | "/" | "=" | "?" | "^" |
"_" | "`" | "{" | "|" | "}" | "~";

dcontent = 33..90 | 94..126;
Let_dig = alpha | digit;
Ldh_str = ( alpha | digit | "_" )* Let_dig;

quoted_pairSMTP = "\\" 32..126;
qtextSMTP = 32..33 | 35..91 | 93..126;
Atom = atext+;
Dot_string = Atom ("." Atom)*;

QcontentSMTP = qtextSMTP | quoted_pairSMTP;
Quoted_string = ( DQUOTE QcontentSMTP* DQUOTE ) %Quoted_addr;
Local_part = ( Dot_string | Quoted_string ) >User_start %User_end;
String = Atom | Quoted_string;

Standardized_tag = Ldh_str;
General_address_literal = Standardized_tag ":" dcontent+;
address_literal = "[" ( IPv4_address_literal |
IPv6_address_literal |
General_address_literal ) >Domain_addr_start %Domain_addr_end "]";


sub_domain = Let_dig Ldh_str?;
Domain = sub_domain ("." sub_domain)*;
Atdomain = "@" Domain;
Adl = Atdomain ( "," Atdomain )*;

Mailbox = Local_part "@" (address_literal | Domain >Domain_start %Domain_end);
UnangledPath = ( Adl ":" )? Mailbox;
AngledPath = "<" UnangledPath ">";
Path = AngledPath %Angled_addr | UnangledPath;
SMTPAddr = space* (Path | "<>" %Empty_addr ) %Valid_addr space*;

}%%

+ 19
- 0
src/ragel/smtp_ip.rl View File

@@ -0,0 +1,19 @@
%%{
machine smtp_ip;

# Parses IPv4/IPv6 address
# Source: https://tools.ietf.org/html/rfc5321#section-4.1.3

Snum = digit{1,3};
IPv4_address_literal = Snum ("." Snum){3};
IPv6_hex = xdigit{1,4};
IPv6_full = IPv6_hex (":" IPv6_hex){7};
IPv6_comp = (IPv6_hex (":" IPv6_hex){0,5})? "::"
(IPv6_hex (":" IPv6_hex){0,5})?;
IPv6v4_full = IPv6_hex (":" IPv6_hex){5} ":" IPv4_address_literal;
IPv6v4_comp = (IPv6_hex (":" IPv6_hex){0,3})? "::"
(IPv6_hex (":" IPv6_hex){0,3} ":")?
IPv4_address_literal;
IPv6_addr = IPv6_full | IPv6_comp | IPv6v4_full | IPv6v4_comp;
IPv6_address_literal = "IPv6:" IPv6_addr;
}%%

Loading…
Cancel
Save