]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnslabeltext.rl
Merge pull request #8096 from mind04/pdns-notify-db-queries
[thirdparty/pdns.git] / pdns / dnslabeltext.rl
CommitLineData
bac8f21b
BH
1#include <stdlib.h>
2#include <string.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <string>
bae1b0a2 6#include "dnsname.hh"
bac8f21b
BH
7#include "namespaces.hh"
8
bac8f21b
BH
9namespace {
10void appendSplit(vector<string>& ret, string& segment, char c)
11{
12 if(segment.size()>254) {
13 ret.push_back(segment);
14 segment.clear();
15 }
16 segment.append(1, c);
17}
3c115e0f 18
bac8f21b
BH
19}
20
21vector<string> segmentDNSText(const string& input )
22{
fc634e87 23 // cerr<<"segmentDNSText("<<input<<")"<<endl;
2fa33bce
BH
24%%{
25 machine dnstext;
26 write data;
916a0fda 27 alphtype unsigned char;
2fa33bce 28}%%
f8499e52
BH
29 (void)dnstext_error; // silence warnings
30 (void)dnstext_en_main;
bac8f21b
BH
31 const char *p = input.c_str(), *pe = input.c_str() + input.length();
32 const char* eof = pe;
33 int cs;
34 char val = 0;
35
36 string segment;
37 vector<string> ret;
38
39 %%{
40 action segmentEnd {
41 ret.push_back(segment);
42 segment.clear();
43 }
44 action segmentBegin {
45 segment.clear();
46 }
47
48 action reportEscaped {
49 char c = *fpc;
50 appendSplit(ret, segment, c);
51 }
52 action reportEscapedNumber {
53 char c = *fpc;
54 val *= 10;
55 val += c-'0';
56
57 }
58 action doneEscapedNumber {
59 appendSplit(ret, segment, val);
60 val=0;
61 }
62
63 action reportPlain {
64 appendSplit(ret, segment, *(fpc));
65 }
66
35261869 67 escaped = '\\' (([^0-9]@reportEscaped) | ([0-9]{3}$reportEscapedNumber%doneEscapedNumber));
973efd35 68 plain = ((extend-'\\'-'"')|'\n'|'\t') $ reportPlain;
2fa33bce
BH
69 txtElement = escaped | plain;
70
71 main := (('"' txtElement* '"' space?) >segmentBegin %segmentEnd)+;
bac8f21b
BH
72
73 # Initialize and execute.
74 write init;
75 write exec;
76 }%%
77
78 if ( cs < dnstext_first_final ) {
79 throw runtime_error("Unable to parse DNS TXT '"+input+"'");
80 }
81
82 return ret;
83};
2fa33bce 84
bae1b0a2 85
beb9fad5 86DNSName::string_t segmentDNSNameRaw(const char* realinput, size_t inputlen)
3c115e0f 87{
88%%{
bae1b0a2 89 machine dnsnameraw;
3c115e0f 90 write data;
91 alphtype unsigned char;
92}%%
bae1b0a2 93 (void)dnsnameraw_error; // silence warnings
94 (void)dnsnameraw_en_main;
1f3151e8 95
bae1b0a2 96 DNSName::string_t ret;
1f3151e8 97
bae1b0a2 98 if(!*realinput || *realinput == '.') {
99 ret.append(1, (char)0);
100 return ret;
101 }
1f3151e8 102
bae1b0a2 103 ret.reserve(inputlen+1);
1f3151e8 104
bae1b0a2 105 const char *p = realinput, *pe = realinput + inputlen;
3c115e0f 106 const char* eof = pe;
107 int cs;
108 char val = 0;
bae1b0a2 109 char labellen=0;
110 unsigned int lenpos=0;
3c115e0f 111 %%{
112 action labelEnd {
d0a4a4bc
RG
113 if (labellen < 0 || labellen > 63) {
114 throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
115 }
bae1b0a2 116 ret[lenpos]=labellen;
117 labellen=0;
3c115e0f 118 }
119 action labelBegin {
bae1b0a2 120 lenpos=ret.size();
121 ret.append(1, (char)0);
122 labellen=0;
3c115e0f 123 }
124
125 action reportEscaped {
126 char c = *fpc;
bae1b0a2 127 ret.append(1, c);
128 labellen++;
3c115e0f 129 }
130 action reportEscapedNumber {
131 char c = *fpc;
132 val *= 10;
133 val += c-'0';
3c115e0f 134 }
135 action doneEscapedNumber {
bae1b0a2 136 ret.append(1, val);
137 labellen++;
3c115e0f 138 val=0;
139 }
140
141 action reportPlain {
bae1b0a2 142 ret.append(1, *(fpc));
143 labellen++;
3c115e0f 144 }
145
146 escaped = '\\' (([^0-9]@reportEscaped) | ([0-9]{3}$reportEscapedNumber%doneEscapedNumber));
564ec901 147 plain = (extend-'\\'-'.') $ reportPlain;
3c115e0f 148 labelElement = escaped | plain;
149
bae1b0a2 150 label = labelElement+ >labelBegin %labelEnd;
151
152 main:= label ('.' label )* '.'?;
153
154 #main := labelElement((labelElement+ '.') >labelBegin %labelEnd)+;
155
156 # label = (plain | escaped | escdecb)+ >label_init %label_fin;
157 # dnsname := '.'? label ('.' label >label_sep)* '.'?;
3c115e0f 158
159 # Initialize and execute.
160 write init;
161 write exec;
162 }%%
163
bae1b0a2 164 if ( cs < dnsnameraw_first_final ) {
165 throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': cs="+std::to_string(cs));
3c115e0f 166 }
bae1b0a2 167 ret.append(1, (char)0);
3c115e0f 168 return ret;
169};
170
171
bae1b0a2 172
bac8f21b
BH
173#if 0
174int main()
175{
176 //char blah[]="\"blah\" \"bleh\" \"bloeh\\\"bleh\" \"\\97enzo\"";
177 char blah[]="\"v=spf1 ip4:67.106.74.128/25 ip4:63.138.42.224/28 ip4:65.204.46.224/27 \\013\\010ip4:66.104.217.176/28 \\013\\010ip4:209.48.147.0/27 ~all\"";
178 //char blah[]="\"abc \\097\\098 def\"";
179 printf("Input: '%s'\n", blah);
180 vector<string> res=dnstext(blah);
181 cerr<<res.size()<<" segments"<<endl;
182 cerr<<res[0]<<endl;
183}
184#endif