-
Notifications
You must be signed in to change notification settings - Fork 0
/
dnsparse.hpp.rl
88 lines (73 loc) · 2.07 KB
/
dnsparse.hpp.rl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
%%{
machine escaped_dnsname;
alphtype char;
# Invoked at the beginning of every label
action label_init {
llen = 0;
}
# Invoked at the beginning of every 3 character decimal escape sequence
# (e.g. "\126")
action dec_init { decb = fc - '0'; }
# Arithmetic decoding of the decimal escape sequence
action dec_add { decb += fc - '0'; }
action dec_mul10 { decb *= 10; }
# Invoked at the end of every decimal escape sequence
action dec_fin {
++llen;
commit ({decb});
}
# Invoked on every printable and/or escaped byte in a label (but not inside
# decimal escape sequences)
action label_char {
++llen;
commit ({fc});
}
# Invoked on label separators e.g. for the two inner periods in ".x.y.z.",
# but not the first or the last
action label_sep {
++nlen;
}
# Invoked at the end of every label
action label_fin {
nlen += llen;
commit_label ({llen});
}
raw = any - digit;
plain = ((0x21 .. 0x7e) - [.\\]) >label_char;
escaped = '\\' (raw >label_char);
escdecb = '\\' ((([01] digit{2}) | ('2' [0-4] digit) | ('2' '5' [0-5]))
>dec_init
<>*dec_mul10
<>*dec_add
%dec_fin
);
label = (plain | escaped | escdecb)+ >label_init %label_fin;
dnsname := '.'? label ('.' label >label_sep)* '.'?;
}%%
namespace {
template <typename Iterator, typename CommitFun, typename CommitLabelFun>
auto
parse_dnsname (
Iterator p,
Iterator const pe,
CommitFun&& commit,
CommitLabelFun&& commit_label
){
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#pragma clang diagnostic ignored "-Wunused-variable"
%% write data;
int cs;
auto const eof = pe;
%% write init;
unsigned nlen = 0;
unsigned llen = 0;
char decb = 0;
%% write exec;
#pragma clang diagnostic pop
if (cs < %%{ write first_final; }%%) {
throw BadDNSName();
}
return nlen;
}
}