]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnslabeltext.rl
add a 'Ragel' based DNS TXT parser & hook it up. With this change we can finally...
[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>
6#include "namespaces.hh"
7
8%%{
9 machine dnstext;
10 write data;
11}%%
12
13namespace {
14void appendSplit(vector<string>& ret, string& segment, char c)
15{
16 if(segment.size()>254) {
17 ret.push_back(segment);
18 segment.clear();
19 }
20 segment.append(1, c);
21}
22}
23
24vector<string> segmentDNSText(const string& input )
25{
26 const char *p = input.c_str(), *pe = input.c_str() + input.length();
27 const char* eof = pe;
28 int cs;
29 char val = 0;
30
31 string segment;
32 vector<string> ret;
33
34 %%{
35 action segmentEnd {
36 ret.push_back(segment);
37 segment.clear();
38 }
39 action segmentBegin {
40 segment.clear();
41 }
42
43 action reportEscaped {
44 char c = *fpc;
45 appendSplit(ret, segment, c);
46 }
47 action reportEscapedNumber {
48 char c = *fpc;
49 val *= 10;
50 val += c-'0';
51
52 }
53 action doneEscapedNumber {
54 appendSplit(ret, segment, val);
55 val=0;
56 }
57
58 action reportPlain {
59 appendSplit(ret, segment, *(fpc));
60 }
61
62 escaped = '\\' ((["\\]@reportEscaped) | ([0-9]{3}$reportEscapedNumber%doneEscapedNumber));
63 plain = (print-'\\'-'"') $ reportPlain;
64 labelElement = escaped | plain;
65
66
67 main := (('"' labelElement* '"' space?) >segmentBegin %segmentEnd)+;
68
69 # Initialize and execute.
70 write init;
71 write exec;
72 }%%
73
74 if ( cs < dnstext_first_final ) {
75 throw runtime_error("Unable to parse DNS TXT '"+input+"'");
76 }
77
78 return ret;
79};
80
81#if 0
82int main()
83{
84 //char blah[]="\"blah\" \"bleh\" \"bloeh\\\"bleh\" \"\\97enzo\"";
85 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\"";
86 //char blah[]="\"abc \\097\\098 def\"";
87 printf("Input: '%s'\n", blah);
88 vector<string> res=dnstext(blah);
89 cerr<<res.size()<<" segments"<<endl;
90 cerr<<res[0]<<endl;
91}
92#endif