Coverage Report

Created: 2026-07-24 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pdns/pdns/dnsdistdist/build/libdnsdist-common.a.p/dnslabeltext.cc
Line
Count
Source
1
2
#line 1 ".././dnslabeltext.rl"
3
#include <stdlib.h>
4
#include <string.h>
5
#include <stdio.h>
6
#include <unistd.h>
7
#include <string>
8
#include <string_view>
9
#include "dnsname.hh"
10
#include "namespaces.hh"
11
#include "dnswriter.hh"
12
#include "misc.hh"
13
14
namespace {
15
void appendSplit(vector<string>& ret, string& segment, char c)
16
2.44M
{
17
2.44M
  if(segment.size()>254) {
18
8.73k
    ret.push_back(segment);
19
8.73k
    segment.clear();
20
8.73k
  }
21
2.44M
  segment.append(1, c);
22
2.44M
}
23
24
}
25
26
vector<string> segmentDNSText(const string& input )
27
787
{
28
  // cerr<<"segmentDNSText("<<input<<")"<<endl; 
29
30
787
#line 31 "libdnsdist-common.a.p/dnslabeltext.cc"
31
787
static const char _dnstext_actions[] = {
32
787
  0, 1, 0, 1, 1, 1, 2, 1, 
33
787
  3, 1, 4, 1, 5, 2, 0, 1, 
34
787
  2, 4, 5
35
787
};
36
37
787
static const char _dnstext_key_offsets[] = {
38
787
  0, 0, 1, 3, 5, 7, 9, 11, 
39
787
  15
40
787
};
41
42
787
static const unsigned char _dnstext_trans_keys[] = {
43
787
  34u, 34u, 92u, 48u, 57u, 48u, 57u, 48u, 
44
787
  57u, 34u, 92u, 32u, 34u, 9u, 13u, 34u, 
45
787
  0
46
787
};
47
48
787
static const char _dnstext_single_lengths[] = {
49
787
  0, 1, 2, 0, 0, 0, 2, 2, 
50
787
  1
51
787
};
52
53
787
static const char _dnstext_range_lengths[] = {
54
787
  0, 0, 0, 1, 1, 1, 0, 1, 
55
787
  0
56
787
};
57
58
787
static const char _dnstext_index_offsets[] = {
59
787
  0, 0, 2, 5, 7, 9, 11, 14, 
60
787
  18
61
787
};
62
63
787
static const char _dnstext_trans_targs[] = {
64
787
  2, 0, 7, 3, 2, 4, 2, 5, 
65
787
  0, 6, 0, 7, 3, 2, 8, 2, 
66
787
  8, 0, 2, 0, 0
67
787
};
68
69
787
static const char _dnstext_trans_actions[] = {
70
787
  3, 0, 0, 0, 11, 7, 5, 7, 
71
787
  0, 7, 0, 9, 9, 16, 0, 13, 
72
787
  0, 0, 13, 0, 0
73
787
};
74
75
787
static const char _dnstext_eof_actions[] = {
76
787
  0, 0, 0, 0, 0, 0, 0, 1, 
77
787
  1
78
787
};
79
80
787
static const int dnstext_start = 1;
81
787
static const int dnstext_first_final = 7;
82
787
static const int dnstext_error = 0;
83
84
787
static const int dnstext_en_main = 1;
85
86
87
787
#line 31 ".././dnslabeltext.rl"
88
89
787
  (void)dnstext_error;  // silence warnings
90
787
  (void)dnstext_en_main;
91
787
        const char *p = input.c_str(), *pe = input.c_str() + input.length();
92
787
        const char* eof = pe;
93
787
        int cs;
94
787
        char val = 0;
95
96
787
        string segment;
97
787
        vector<string> ret;
98
99
        
100
787
#line 101 "libdnsdist-common.a.p/dnslabeltext.cc"
101
787
  {
102
787
  cs = dnstext_start;
103
787
  }
104
105
787
#line 106 "libdnsdist-common.a.p/dnslabeltext.cc"
106
787
  {
107
787
  int _klen;
108
787
  unsigned int _trans;
109
787
  const char *_acts;
110
787
  unsigned int _nacts;
111
787
  const unsigned char *_keys;
112
113
787
  if ( p == pe )
114
0
    goto _test_eof;
115
787
  if ( cs == 0 )
116
0
    goto _out;
117
2.82M
_resume:
118
2.82M
  _keys = _dnstext_trans_keys + _dnstext_key_offsets[cs];
119
2.82M
  _trans = _dnstext_index_offsets[cs];
120
121
2.82M
  _klen = _dnstext_single_lengths[cs];
122
2.82M
  if ( _klen > 0 ) {
123
2.76M
    const unsigned char *_lower = _keys;
124
2.76M
    const unsigned char *_mid;
125
2.76M
    const unsigned char *_upper = _keys + _klen - 1;
126
6.38M
    while (1) {
127
6.38M
      if ( _upper < _lower )
128
2.39M
        break;
129
130
3.99M
      _mid = _lower + ((_upper-_lower) >> 1);
131
3.99M
      if ( (*p) < *_mid )
132
1.77M
        _upper = _mid - 1;
133
2.21M
      else if ( (*p) > *_mid )
134
1.84M
        _lower = _mid + 1;
135
369k
      else {
136
369k
        _trans += (unsigned int)(_mid - _keys);
137
369k
        goto _match;
138
369k
      }
139
3.99M
    }
140
2.39M
    _keys += _klen;
141
2.39M
    _trans += _klen;
142
2.39M
  }
143
144
2.45M
  _klen = _dnstext_range_lengths[cs];
145
2.45M
  if ( _klen > 0 ) {
146
61.3k
    const unsigned char *_lower = _keys;
147
61.3k
    const unsigned char *_mid;
148
61.3k
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
149
113k
    while (1) {
150
113k
      if ( _upper < _lower )
151
52.6k
        break;
152
153
61.3k
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
154
61.3k
      if ( (*p) < _mid[0] )
155
3.45k
        _upper = _mid - 2;
156
57.8k
      else if ( (*p) > _mid[1] )
157
49.2k
        _lower = _mid + 2;
158
8.65k
      else {
159
8.65k
        _trans += (unsigned int)((_mid - _keys)>>1);
160
8.65k
        goto _match;
161
8.65k
      }
162
61.3k
    }
163
52.6k
    _trans += _klen;
164
52.6k
  }
165
166
2.82M
_match:
167
2.82M
  cs = _dnstext_trans_targs[_trans];
168
169
2.82M
  if ( _dnstext_trans_actions[_trans] == 0 )
170
263k
    goto _again;
171
172
2.55M
  _acts = _dnstext_actions + _dnstext_trans_actions[_trans];
173
2.55M
  _nacts = (unsigned int) *_acts++;
174
5.22M
  while ( _nacts-- > 0 )
175
2.66M
  {
176
2.66M
    switch ( *_acts++ )
177
2.66M
    {
178
104k
  case 0:
179
104k
#line 43 ".././dnslabeltext.rl"
180
104k
  { 
181
104k
                        ret.push_back(segment);
182
104k
                        segment.clear();
183
104k
                }
184
104k
  break;
185
105k
  case 1:
186
105k
#line 47 ".././dnslabeltext.rl"
187
105k
  { 
188
105k
                        segment.clear();
189
105k
                }
190
105k
  break;
191
52.6k
  case 2:
192
52.6k
#line 51 ".././dnslabeltext.rl"
193
52.6k
  {
194
52.6k
                  char c = *p;
195
52.6k
                  appendSplit(ret, segment, c);
196
52.6k
                }
197
52.6k
  break;
198
8.65k
  case 3:
199
8.65k
#line 55 ".././dnslabeltext.rl"
200
8.65k
  {
201
8.65k
                  char c = *p;
202
8.65k
                  val *= 10;
203
8.65k
                  val += c-'0';
204
                  
205
8.65k
                }
206
8.65k
  break;
207
2.88k
  case 4:
208
2.88k
#line 61 ".././dnslabeltext.rl"
209
2.88k
  {
210
2.88k
                  appendSplit(ret, segment, val);
211
2.88k
                  val=0;
212
2.88k
                }
213
2.88k
  break;
214
2.39M
  case 5:
215
2.39M
#line 66 ".././dnslabeltext.rl"
216
2.39M
  {
217
2.39M
                  appendSplit(ret, segment, *(p));
218
2.39M
                }
219
2.39M
  break;
220
2.66M
#line 221 "libdnsdist-common.a.p/dnslabeltext.cc"
221
2.66M
    }
222
2.66M
  }
223
224
2.82M
_again:
225
2.82M
  if ( cs == 0 )
226
2
    goto _out;
227
2.82M
  if ( ++p != pe )
228
2.82M
    goto _resume;
229
785
  _test_eof: {}
230
785
  if ( p == eof )
231
785
  {
232
785
  const char *__acts = _dnstext_actions + _dnstext_eof_actions[cs];
233
785
  unsigned int __nacts = (unsigned int) *__acts++;
234
1.53k
  while ( __nacts-- > 0 ) {
235
748
    switch ( *__acts++ ) {
236
748
  case 0:
237
748
#line 43 ".././dnslabeltext.rl"
238
748
  { 
239
748
                        ret.push_back(segment);
240
748
                        segment.clear();
241
748
                }
242
748
  break;
243
748
#line 244 "libdnsdist-common.a.p/dnslabeltext.cc"
244
748
    }
245
748
  }
246
785
  }
247
248
787
  _out: {}
249
787
  }
250
251
0
#line 79 ".././dnslabeltext.rl"
252
253
254
787
        if ( cs < dnstext_first_final ) {
255
39
                throw runtime_error("Unable to parse DNS TXT '"+input+"'");
256
39
        }
257
258
748
        return ret;
259
787
};
260
261
262
DNSName::string_t segmentDNSNameRaw(const char* realinput, size_t inputlen)
263
27.1k
{
264
265
27.1k
#line 266 "libdnsdist-common.a.p/dnslabeltext.cc"
266
27.1k
static const char _dnsnameraw_actions[] = {
267
27.1k
  0, 1, 0, 1, 1, 1, 2, 1, 
268
27.1k
  3, 1, 4, 1, 5, 2, 1, 5, 
269
27.1k
  2, 4, 0, 2, 4, 5
270
27.1k
};
271
272
27.1k
static const char _dnsnameraw_key_offsets[] = {
273
27.1k
  0, 0, 2, 4, 6, 8, 10, 12
274
27.1k
};
275
276
27.1k
static const unsigned char _dnsnameraw_trans_keys[] = {
277
27.1k
  46u, 92u, 48u, 57u, 48u, 57u, 48u, 57u, 
278
27.1k
  46u, 92u, 46u, 92u, 46u, 92u, 0
279
27.1k
};
280
281
27.1k
static const char _dnsnameraw_single_lengths[] = {
282
27.1k
  0, 2, 0, 0, 0, 2, 2, 2
283
27.1k
};
284
285
27.1k
static const char _dnsnameraw_range_lengths[] = {
286
27.1k
  0, 0, 1, 1, 1, 0, 0, 0
287
27.1k
};
288
289
27.1k
static const char _dnsnameraw_index_offsets[] = {
290
27.1k
  0, 0, 3, 5, 7, 9, 12, 15
291
27.1k
};
292
293
27.1k
static const char _dnsnameraw_trans_targs[] = {
294
27.1k
  0, 2, 5, 3, 5, 4, 0, 7, 
295
27.1k
  0, 6, 2, 5, 0, 2, 5, 6, 
296
27.1k
  2, 5, 0
297
27.1k
};
298
299
27.1k
static const char _dnsnameraw_trans_actions[] = {
300
27.1k
  0, 3, 13, 7, 5, 7, 0, 7, 
301
27.1k
  0, 1, 0, 11, 0, 3, 13, 16, 
302
27.1k
  9, 19, 0
303
27.1k
};
304
305
27.1k
static const char _dnsnameraw_eof_actions[] = {
306
27.1k
  0, 0, 0, 0, 0, 1, 0, 16
307
27.1k
};
308
309
27.1k
static const int dnsnameraw_start = 1;
310
27.1k
static const int dnsnameraw_first_final = 5;
311
27.1k
static const int dnsnameraw_error = 0;
312
313
27.1k
static const int dnsnameraw_en_main = 1;
314
315
316
27.1k
#line 95 ".././dnslabeltext.rl"
317
318
27.1k
  (void)dnsnameraw_error;  // silence warnings
319
27.1k
  (void)dnsnameraw_en_main;
320
321
27.1k
        DNSName::string_t ret;
322
323
27.1k
        if(!*realinput || *realinput == '.') {
324
1.20k
          ret.append(1, (char)0);
325
1.20k
          return ret;
326
1.20k
        }
327
328
25.9k
        ret.reserve(inputlen+1);
329
330
25.9k
        const char *p = realinput, *pe = realinput + inputlen;
331
25.9k
        const char* eof = pe;
332
25.9k
        int cs;
333
25.9k
        char val = 0;
334
25.9k
        unsigned char labellen=0;
335
25.9k
        unsigned int lenpos=0;
336
        
337
25.9k
#line 338 "libdnsdist-common.a.p/dnslabeltext.cc"
338
25.9k
  {
339
25.9k
  cs = dnsnameraw_start;
340
25.9k
  }
341
342
25.9k
#line 343 "libdnsdist-common.a.p/dnslabeltext.cc"
343
25.9k
  {
344
25.9k
  int _klen;
345
25.9k
  unsigned int _trans;
346
25.9k
  const char *_acts;
347
25.9k
  unsigned int _nacts;
348
25.9k
  const unsigned char *_keys;
349
350
25.9k
  if ( p == pe )
351
0
    goto _test_eof;
352
25.9k
  if ( cs == 0 )
353
0
    goto _out;
354
420M
_resume:
355
420M
  _keys = _dnsnameraw_trans_keys + _dnsnameraw_key_offsets[cs];
356
420M
  _trans = _dnsnameraw_index_offsets[cs];
357
358
420M
  _klen = _dnsnameraw_single_lengths[cs];
359
420M
  if ( _klen > 0 ) {
360
420M
    const unsigned char *_lower = _keys;
361
420M
    const unsigned char *_mid;
362
420M
    const unsigned char *_upper = _keys + _klen - 1;
363
1.26G
    while (1) {
364
1.26G
      if ( _upper < _lower )
365
420M
        break;
366
367
840M
      _mid = _lower + ((_upper-_lower) >> 1);
368
840M
      if ( (*p) < *_mid )
369
420M
        _upper = _mid - 1;
370
420M
      else if ( (*p) > *_mid )
371
420M
        _lower = _mid + 1;
372
72.6k
      else {
373
72.6k
        _trans += (unsigned int)(_mid - _keys);
374
72.6k
        goto _match;
375
72.6k
      }
376
840M
    }
377
420M
    _keys += _klen;
378
420M
    _trans += _klen;
379
420M
  }
380
381
420M
  _klen = _dnsnameraw_range_lengths[cs];
382
420M
  if ( _klen > 0 ) {
383
71.8k
    const unsigned char *_lower = _keys;
384
71.8k
    const unsigned char *_mid;
385
71.8k
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
386
111k
    while (1) {
387
111k
      if ( _upper < _lower )
388
40.1k
        break;
389
390
71.8k
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
391
71.8k
      if ( (*p) < _mid[0] )
392
13.5k
        _upper = _mid - 2;
393
58.3k
      else if ( (*p) > _mid[1] )
394
26.6k
        _lower = _mid + 2;
395
31.7k
      else {
396
31.7k
        _trans += (unsigned int)((_mid - _keys)>>1);
397
31.7k
        goto _match;
398
31.7k
      }
399
71.8k
    }
400
40.1k
    _trans += _klen;
401
40.1k
  }
402
403
420M
_match:
404
420M
  cs = _dnsnameraw_trans_targs[_trans];
405
406
420M
  if ( _dnsnameraw_trans_actions[_trans] == 0 )
407
44.2k
    goto _again;
408
409
420M
  _acts = _dnsnameraw_actions + _dnsnameraw_trans_actions[_trans];
410
420M
  _nacts = (unsigned int) *_acts++;
411
841M
  while ( _nacts-- > 0 )
412
420M
  {
413
420M
    switch ( *_acts++ )
414
420M
    {
415
21.7k
  case 0:
416
21.7k
#line 115 ".././dnslabeltext.rl"
417
21.7k
  { 
418
21.7k
                        if (labellen > 63) {
419
94
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
420
94
                        }
421
21.6k
                        ret[lenpos]=labellen;
422
21.6k
                        labellen=0;
423
21.6k
                }
424
0
  break;
425
38.8k
  case 1:
426
38.8k
#line 122 ".././dnslabeltext.rl"
427
38.8k
  { 
428
38.8k
                        lenpos=ret.size();
429
38.8k
                        ret.append(1, (char)0);
430
38.8k
                        labellen=0;
431
38.8k
                }
432
38.8k
  break;
433
40.1k
  case 2:
434
40.1k
#line 128 ".././dnslabeltext.rl"
435
40.1k
  {
436
40.1k
                  char c = *p;
437
40.1k
                  ret.append(1, c);
438
40.1k
                  labellen++;
439
40.1k
                }
440
40.1k
  break;
441
31.7k
  case 3:
442
31.7k
#line 133 ".././dnslabeltext.rl"
443
31.7k
  {
444
31.7k
                  char c = *p;
445
31.7k
                  val *= 10;
446
31.7k
                  val += c-'0';
447
31.7k
                }
448
31.7k
  break;
449
9.38k
  case 4:
450
9.38k
#line 138 ".././dnslabeltext.rl"
451
9.38k
  {
452
9.38k
                  ret.append(1, val);
453
9.38k
                  labellen++;
454
9.38k
                  val=0;
455
9.38k
                }
456
9.38k
  break;
457
420M
  case 5:
458
420M
#line 144 ".././dnslabeltext.rl"
459
420M
  {
460
420M
                  ret.append(1, *(p));
461
420M
                  labellen++;
462
420M
                }
463
420M
  break;
464
420M
#line 465 "libdnsdist-common.a.p/dnslabeltext.cc"
465
420M
    }
466
420M
  }
467
468
420M
_again:
469
420M
  if ( cs == 0 )
470
27
    goto _out;
471
420M
  if ( ++p != pe )
472
420M
    goto _resume;
473
25.8k
  _test_eof: {}
474
25.8k
  if ( p == eof )
475
25.8k
  {
476
25.8k
  const char *__acts = _dnsnameraw_actions + _dnsnameraw_eof_actions[cs];
477
25.8k
  unsigned int __nacts = (unsigned int) *__acts++;
478
43.8k
  while ( __nacts-- > 0 ) {
479
18.1k
    switch ( *__acts++ ) {
480
16.9k
  case 0:
481
16.9k
#line 115 ".././dnslabeltext.rl"
482
16.9k
  { 
483
16.9k
                        if (labellen > 63) {
484
98
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
485
98
                        }
486
16.8k
                        ret[lenpos]=labellen;
487
16.8k
                        labellen=0;
488
16.8k
                }
489
0
  break;
490
1.17k
  case 4:
491
1.17k
#line 138 ".././dnslabeltext.rl"
492
1.17k
  {
493
1.17k
                  ret.append(1, val);
494
1.17k
                  labellen++;
495
1.17k
                  val=0;
496
1.17k
                }
497
1.17k
  break;
498
18.1k
#line 499 "libdnsdist-common.a.p/dnslabeltext.cc"
499
18.1k
    }
500
18.1k
  }
501
25.8k
  }
502
503
25.7k
  _out: {}
504
25.7k
  }
505
506
0
#line 165 ".././dnslabeltext.rl"
507
508
509
25.7k
        if ( cs < dnsnameraw_first_final ) {
510
187
                throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': cs="+std::to_string(cs));
511
187
        }
512
25.5k
        ret.append(1, (char)0);
513
25.5k
        return ret;
514
25.7k
};
515
516
// Reads an RFC 1035 character string from 'in', puts the resulting bytes in 'out'.
517
// Returns the amount of bytes read from 'in'
518
16.1k
size_t parseRFC1035CharString(std::string_view in, std::string &val) {
519
520
16.1k
  val.clear();
521
16.1k
  val.reserve(in.size());
522
16.1k
  const char *p = in.data();
523
16.1k
  const char *pe = p + in.size();
524
16.1k
  int cs = 0;
525
16.1k
  uint8_t escaped_octet = 0;
526
  // Keeps track of how many chars we read from the source string
527
16.1k
  size_t counter=0;
528
529
/* This parses an RFC 1035 char-string.
530
 * It was created from the ABNF in draft-ietf-dnsop-svcb-https-02 with
531
 * https://github.com/zinid/abnfc and modified to put all the characters in the
532
 * right place.
533
 */
534
535
16.1k
#line 536 "libdnsdist-common.a.p/dnslabeltext.cc"
536
16.1k
static const char _dns_text_to_string_actions[] = {
537
16.1k
  0, 1, 0, 1, 2, 1, 3, 2, 
538
16.1k
  0, 1
539
16.1k
};
540
541
16.1k
static const char _dns_text_to_string_key_offsets[] = {
542
16.1k
  0, 0, 8, 15, 17, 19, 22, 24, 
543
16.1k
  33, 41, 43, 45, 48, 50, 58
544
16.1k
};
545
546
16.1k
static const char _dns_text_to_string_trans_keys[] = {
547
16.1k
  34, 92, 33, 39, 42, 58, 60, 126, 
548
16.1k
  50, 33, 47, 48, 49, 58, 126, 48, 
549
16.1k
  57, 48, 57, 53, 48, 52, 48, 53, 
550
16.1k
  9, 34, 92, 32, 39, 42, 58, 60, 
551
16.1k
  126, 9, 50, 32, 47, 48, 49, 58, 
552
16.1k
  126, 48, 57, 48, 57, 53, 48, 52, 
553
16.1k
  48, 53, 33, 92, 35, 39, 42, 58, 
554
16.1k
  60, 126, 0
555
16.1k
};
556
557
16.1k
static const char _dns_text_to_string_single_lengths[] = {
558
16.1k
  0, 2, 1, 0, 0, 1, 0, 3, 
559
16.1k
  2, 0, 0, 1, 0, 2, 0
560
16.1k
};
561
562
16.1k
static const char _dns_text_to_string_range_lengths[] = {
563
16.1k
  0, 3, 3, 1, 1, 1, 1, 3, 
564
16.1k
  3, 1, 1, 1, 1, 3, 0
565
16.1k
};
566
567
16.1k
static const char _dns_text_to_string_index_offsets[] = {
568
16.1k
  0, 0, 6, 11, 13, 15, 18, 20, 
569
16.1k
  27, 33, 35, 37, 40, 42, 48
570
16.1k
};
571
572
16.1k
static const char _dns_text_to_string_indicies[] = {
573
16.1k
  2, 3, 0, 0, 0, 1, 5, 0, 
574
16.1k
  4, 0, 1, 6, 1, 7, 1, 8, 
575
16.1k
  6, 1, 7, 1, 9, 10, 11, 9, 
576
16.1k
  9, 9, 1, 9, 13, 9, 12, 9, 
577
16.1k
  1, 14, 1, 15, 1, 16, 14, 1, 
578
16.1k
  15, 1, 0, 3, 0, 0, 0, 1, 
579
16.1k
  1, 0
580
16.1k
};
581
582
16.1k
static const char _dns_text_to_string_trans_targs[] = {
583
16.1k
  13, 0, 7, 2, 3, 5, 4, 13, 
584
16.1k
  6, 7, 14, 8, 9, 11, 10, 7, 
585
16.1k
  12
586
16.1k
};
587
588
16.1k
static const char _dns_text_to_string_trans_actions[] = {
589
16.1k
  3, 0, 5, 5, 1, 1, 1, 7, 
590
16.1k
  1, 3, 5, 5, 1, 1, 1, 7, 
591
16.1k
  1
592
16.1k
};
593
594
16.1k
static const int dns_text_to_string_start = 1;
595
16.1k
static const int dns_text_to_string_first_final = 13;
596
16.1k
static const int dns_text_to_string_error = 0;
597
598
16.1k
static const int dns_text_to_string_en_main = 1;
599
600
601
16.1k
#line 602 "libdnsdist-common.a.p/dnslabeltext.cc"
602
16.1k
  {
603
16.1k
  cs = dns_text_to_string_start;
604
16.1k
  }
605
606
16.1k
#line 233 ".././dnslabeltext.rl"
607
608
609
  // silence warnings
610
16.1k
  (void) dns_text_to_string_first_final;
611
16.1k
  (void) dns_text_to_string_error;
612
16.1k
  (void) dns_text_to_string_en_main;
613
  
614
16.1k
#line 615 "libdnsdist-common.a.p/dnslabeltext.cc"
615
16.1k
  {
616
16.1k
  int _klen;
617
16.1k
  unsigned int _trans;
618
16.1k
  const char *_acts;
619
16.1k
  unsigned int _nacts;
620
16.1k
  const char *_keys;
621
622
16.1k
  if ( p == pe )
623
191
    goto _test_eof;
624
15.9k
  if ( cs == 0 )
625
0
    goto _out;
626
6.86M
_resume:
627
6.86M
  _keys = _dns_text_to_string_trans_keys + _dns_text_to_string_key_offsets[cs];
628
6.86M
  _trans = _dns_text_to_string_index_offsets[cs];
629
630
6.86M
  _klen = _dns_text_to_string_single_lengths[cs];
631
6.86M
  if ( _klen > 0 ) {
632
6.86M
    const char *_lower = _keys;
633
6.86M
    const char *_mid;
634
6.86M
    const char *_upper = _keys + _klen - 1;
635
20.4M
    while (1) {
636
20.4M
      if ( _upper < _lower )
637
6.81M
        break;
638
639
13.6M
      _mid = _lower + ((_upper-_lower) >> 1);
640
13.6M
      if ( (*p) < *_mid )
641
3.55M
        _upper = _mid - 1;
642
10.1M
      else if ( (*p) > *_mid )
643
10.0M
        _lower = _mid + 1;
644
49.0k
      else {
645
49.0k
        _trans += (unsigned int)(_mid - _keys);
646
49.0k
        goto _match;
647
49.0k
      }
648
13.6M
    }
649
6.81M
    _keys += _klen;
650
6.81M
    _trans += _klen;
651
6.81M
  }
652
653
6.81M
  _klen = _dns_text_to_string_range_lengths[cs];
654
6.81M
  if ( _klen > 0 ) {
655
6.81M
    const char *_lower = _keys;
656
6.81M
    const char *_mid;
657
6.81M
    const char *_upper = _keys + (_klen<<1) - 2;
658
11.9M
    while (1) {
659
11.9M
      if ( _upper < _lower )
660
14.1k
        break;
661
662
11.9M
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
663
11.9M
      if ( (*p) < _mid[0] )
664
144k
        _upper = _mid - 2;
665
11.8M
      else if ( (*p) > _mid[1] )
666
4.99M
        _lower = _mid + 2;
667
6.80M
      else {
668
6.80M
        _trans += (unsigned int)((_mid - _keys)>>1);
669
6.80M
        goto _match;
670
6.80M
      }
671
11.9M
    }
672
14.1k
    _trans += _klen;
673
14.1k
  }
674
675
6.86M
_match:
676
6.86M
  _trans = _dns_text_to_string_indicies[_trans];
677
6.86M
  cs = _dns_text_to_string_trans_targs[_trans];
678
679
6.86M
  if ( _dns_text_to_string_trans_actions[_trans] == 0 )
680
14.3k
    goto _again;
681
682
6.85M
  _acts = _dns_text_to_string_actions + _dns_text_to_string_trans_actions[_trans];
683
6.85M
  _nacts = (unsigned int) *_acts++;
684
13.7M
  while ( _nacts-- > 0 )
685
6.85M
  {
686
6.85M
    switch ( *_acts++ )
687
6.85M
    {
688
4.53k
  case 0:
689
4.53k
#line 195 ".././dnslabeltext.rl"
690
4.53k
  {
691
4.53k
    escaped_octet *= 10;
692
4.53k
    escaped_octet += (*p)-'0';
693
4.53k
    counter++;
694
4.53k
  }
695
4.53k
  break;
696
1.49k
  case 1:
697
1.49k
#line 201 ".././dnslabeltext.rl"
698
1.49k
  {
699
1.49k
    val += escaped_octet;
700
1.49k
    escaped_octet = 0;
701
1.49k
  }
702
1.49k
  break;
703
6.84M
  case 2:
704
6.84M
#line 206 ".././dnslabeltext.rl"
705
6.84M
  {
706
6.84M
    val += (*p);
707
6.84M
    counter++;
708
6.84M
  }
709
6.84M
  break;
710
5.67k
  case 3:
711
5.67k
#line 211 ".././dnslabeltext.rl"
712
5.67k
  {
713
5.67k
    counter++;
714
5.67k
  }
715
5.67k
  break;
716
6.85M
#line 717 "libdnsdist-common.a.p/dnslabeltext.cc"
717
6.85M
    }
718
6.85M
  }
719
720
6.86M
_again:
721
6.86M
  if ( cs == 0 )
722
14.3k
    goto _out;
723
6.85M
  if ( ++p != pe )
724
6.85M
    goto _resume;
725
1.79k
  _test_eof: {}
726
16.1k
  _out: {}
727
16.1k
  }
728
729
0
#line 240 ".././dnslabeltext.rl"
730
731
0
  return counter;
732
1.79k
}
733
734
// Similar to above, but allows ( ) ; within quoted parts.
735
0
size_t parseRFC1035CharStringRelaxed(std::string_view in, std::string &val) {
736
737
0
  val.clear();
738
0
  val.reserve(in.size());
739
0
  const char *p = in.data();
740
0
  const char *pe = p + in.size();
741
0
  int cs = 0;
742
0
  uint8_t escaped_octet = 0;
743
  // Keeps track of how many chars we read from the source string
744
0
  size_t counter=0;
745
746
/* This parses an RFC 1035 char-string, but allows ( ) and ; to occur in
747
 * quoted parts.
748
 */
749
750
0
#line 751 "libdnsdist-common.a.p/dnslabeltext.cc"
751
0
static const char _dns_text_to_string_r_actions[] = {
752
0
  0, 1, 0, 1, 2, 1, 3, 2, 
753
0
  0, 1
754
0
};
755
756
0
static const char _dns_text_to_string_r_key_offsets[] = {
757
0
  0, 0, 8, 15, 17, 19, 22, 24, 
758
0
  29, 37, 39, 41, 44, 46, 54
759
0
};
760
761
0
static const char _dns_text_to_string_r_trans_keys[] = {
762
0
  34, 92, 33, 39, 42, 58, 60, 126, 
763
0
  50, 33, 47, 48, 49, 58, 126, 48, 
764
0
  57, 48, 57, 53, 48, 52, 48, 53, 
765
0
  9, 34, 92, 32, 126, 9, 50, 32, 
766
0
  47, 48, 49, 58, 126, 48, 57, 48, 
767
0
  57, 53, 48, 52, 48, 53, 33, 92, 
768
0
  35, 39, 42, 58, 60, 126, 0
769
0
};
770
771
0
static const char _dns_text_to_string_r_single_lengths[] = {
772
0
  0, 2, 1, 0, 0, 1, 0, 3, 
773
0
  2, 0, 0, 1, 0, 2, 0
774
0
};
775
776
0
static const char _dns_text_to_string_r_range_lengths[] = {
777
0
  0, 3, 3, 1, 1, 1, 1, 1, 
778
0
  3, 1, 1, 1, 1, 3, 0
779
0
};
780
781
0
static const char _dns_text_to_string_r_index_offsets[] = {
782
0
  0, 0, 6, 11, 13, 15, 18, 20, 
783
0
  25, 31, 33, 35, 38, 40, 46
784
0
};
785
786
0
static const char _dns_text_to_string_r_indicies[] = {
787
0
  2, 3, 0, 0, 0, 1, 5, 0, 
788
0
  4, 0, 1, 6, 1, 7, 1, 8, 
789
0
  6, 1, 7, 1, 9, 10, 11, 9, 
790
0
  1, 9, 13, 9, 12, 9, 1, 14, 
791
0
  1, 15, 1, 16, 14, 1, 15, 1, 
792
0
  0, 3, 0, 0, 0, 1, 1, 0
793
0
};
794
795
0
static const char _dns_text_to_string_r_trans_targs[] = {
796
0
  13, 0, 7, 2, 3, 5, 4, 13, 
797
0
  6, 7, 14, 8, 9, 11, 10, 7, 
798
0
  12
799
0
};
800
801
0
static const char _dns_text_to_string_r_trans_actions[] = {
802
0
  3, 0, 5, 5, 1, 1, 1, 7, 
803
0
  1, 3, 5, 5, 1, 1, 1, 7, 
804
0
  1
805
0
};
806
807
0
static const int dns_text_to_string_r_start = 1;
808
0
static const int dns_text_to_string_r_first_final = 13;
809
0
static const int dns_text_to_string_r_error = 0;
810
811
0
static const int dns_text_to_string_r_en_main = 1;
812
813
814
0
#line 815 "libdnsdist-common.a.p/dnslabeltext.cc"
815
0
  {
816
0
  cs = dns_text_to_string_r_start;
817
0
  }
818
819
0
#line 303 ".././dnslabeltext.rl"
820
821
822
  // silence warnings
823
0
  (void) dns_text_to_string_r_first_final;
824
0
  (void) dns_text_to_string_r_error;
825
0
  (void) dns_text_to_string_r_en_main;
826
  
827
0
#line 828 "libdnsdist-common.a.p/dnslabeltext.cc"
828
0
  {
829
0
  int _klen;
830
0
  unsigned int _trans;
831
0
  const char *_acts;
832
0
  unsigned int _nacts;
833
0
  const char *_keys;
834
835
0
  if ( p == pe )
836
0
    goto _test_eof;
837
0
  if ( cs == 0 )
838
0
    goto _out;
839
0
_resume:
840
0
  _keys = _dns_text_to_string_r_trans_keys + _dns_text_to_string_r_key_offsets[cs];
841
0
  _trans = _dns_text_to_string_r_index_offsets[cs];
842
843
0
  _klen = _dns_text_to_string_r_single_lengths[cs];
844
0
  if ( _klen > 0 ) {
845
0
    const char *_lower = _keys;
846
0
    const char *_mid;
847
0
    const char *_upper = _keys + _klen - 1;
848
0
    while (1) {
849
0
      if ( _upper < _lower )
850
0
        break;
851
852
0
      _mid = _lower + ((_upper-_lower) >> 1);
853
0
      if ( (*p) < *_mid )
854
0
        _upper = _mid - 1;
855
0
      else if ( (*p) > *_mid )
856
0
        _lower = _mid + 1;
857
0
      else {
858
0
        _trans += (unsigned int)(_mid - _keys);
859
0
        goto _match;
860
0
      }
861
0
    }
862
0
    _keys += _klen;
863
0
    _trans += _klen;
864
0
  }
865
866
0
  _klen = _dns_text_to_string_r_range_lengths[cs];
867
0
  if ( _klen > 0 ) {
868
0
    const char *_lower = _keys;
869
0
    const char *_mid;
870
0
    const char *_upper = _keys + (_klen<<1) - 2;
871
0
    while (1) {
872
0
      if ( _upper < _lower )
873
0
        break;
874
875
0
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
876
0
      if ( (*p) < _mid[0] )
877
0
        _upper = _mid - 2;
878
0
      else if ( (*p) > _mid[1] )
879
0
        _lower = _mid + 2;
880
0
      else {
881
0
        _trans += (unsigned int)((_mid - _keys)>>1);
882
0
        goto _match;
883
0
      }
884
0
    }
885
0
    _trans += _klen;
886
0
  }
887
888
0
_match:
889
0
  _trans = _dns_text_to_string_r_indicies[_trans];
890
0
  cs = _dns_text_to_string_r_trans_targs[_trans];
891
892
0
  if ( _dns_text_to_string_r_trans_actions[_trans] == 0 )
893
0
    goto _again;
894
895
0
  _acts = _dns_text_to_string_r_actions + _dns_text_to_string_r_trans_actions[_trans];
896
0
  _nacts = (unsigned int) *_acts++;
897
0
  while ( _nacts-- > 0 )
898
0
  {
899
0
    switch ( *_acts++ )
900
0
    {
901
0
  case 0:
902
0
#line 262 ".././dnslabeltext.rl"
903
0
  {
904
0
    escaped_octet *= 10;
905
0
    escaped_octet += (*p)-'0';
906
0
    counter++;
907
0
  }
908
0
  break;
909
0
  case 1:
910
0
#line 268 ".././dnslabeltext.rl"
911
0
  {
912
0
    val += escaped_octet;
913
0
    escaped_octet = 0;
914
0
  }
915
0
  break;
916
0
  case 2:
917
0
#line 273 ".././dnslabeltext.rl"
918
0
  {
919
0
    val += (*p);
920
0
    counter++;
921
0
  }
922
0
  break;
923
0
  case 3:
924
0
#line 278 ".././dnslabeltext.rl"
925
0
  {
926
0
    counter++;
927
0
  }
928
0
  break;
929
0
#line 930 "libdnsdist-common.a.p/dnslabeltext.cc"
930
0
    }
931
0
  }
932
933
0
_again:
934
0
  if ( cs == 0 )
935
0
    goto _out;
936
0
  if ( ++p != pe )
937
0
    goto _resume;
938
0
  _test_eof: {}
939
0
  _out: {}
940
0
  }
941
942
0
#line 310 ".././dnslabeltext.rl"
943
944
0
  return counter;
945
0
}
946
947
5.19k
size_t parseSVCBValueListFromParsedRFC1035CharString(const std::string &in, std::vector<std::string> &val) {
948
5.19k
  val.clear();
949
5.19k
  const char *p = in.c_str();
950
5.19k
  const char *pe = p + in.size();
951
5.19k
  int cs = 0;
952
5.19k
  const char* eof = pe;
953
  // Keeps track of how many chars we read from the source string
954
5.19k
  size_t counter=0;
955
956
  // Here we store the parsed value until we hit a comma or are done
957
5.19k
  std::string tmp;
958
959
960
5.19k
#line 961 "libdnsdist-common.a.p/dnslabeltext.cc"
961
5.19k
static const char _dns_text_to_value_list_actions[] = {
962
5.19k
  0, 1, 0, 1, 2, 1, 3, 2, 
963
5.19k
  2, 3, 2, 3, 1
964
5.19k
};
965
966
5.19k
static const char _dns_text_to_value_list_key_offsets[] = {
967
5.19k
  0, 0, 2, 4, 6
968
5.19k
};
969
970
5.19k
static const unsigned char _dns_text_to_value_list_trans_keys[] = {
971
5.19k
  44u, 92u, 44u, 92u, 44u, 92u, 44u, 92u, 
972
5.19k
  0
973
5.19k
};
974
975
5.19k
static const char _dns_text_to_value_list_single_lengths[] = {
976
5.19k
  0, 2, 2, 2, 2
977
5.19k
};
978
979
5.19k
static const char _dns_text_to_value_list_range_lengths[] = {
980
5.19k
  0, 0, 0, 0, 0
981
5.19k
};
982
983
5.19k
static const char _dns_text_to_value_list_index_offsets[] = {
984
5.19k
  0, 0, 3, 6, 9
985
5.19k
};
986
987
5.19k
static const char _dns_text_to_value_list_indicies[] = {
988
5.19k
  1, 2, 0, 3, 3, 1, 1, 2, 
989
5.19k
  0, 4, 2, 0, 0
990
5.19k
};
991
992
5.19k
static const char _dns_text_to_value_list_trans_targs[] = {
993
5.19k
  4, 0, 2, 4, 1
994
5.19k
};
995
996
5.19k
static const char _dns_text_to_value_list_trans_actions[] = {
997
5.19k
  1, 0, 5, 10, 7
998
5.19k
};
999
1000
5.19k
static const char _dns_text_to_value_list_eof_actions[] = {
1001
5.19k
  0, 0, 0, 0, 3
1002
5.19k
};
1003
1004
5.19k
static const int dns_text_to_value_list_start = 3;
1005
5.19k
static const int dns_text_to_value_list_first_final = 3;
1006
5.19k
static const int dns_text_to_value_list_error = 0;
1007
1008
5.19k
static const int dns_text_to_value_list_en_main = 3;
1009
1010
1011
5.19k
#line 1012 "libdnsdist-common.a.p/dnslabeltext.cc"
1012
5.19k
  {
1013
5.19k
  cs = dns_text_to_value_list_start;
1014
5.19k
  }
1015
1016
5.19k
#line 359 ".././dnslabeltext.rl"
1017
1018
1019
  // silence warnings
1020
5.19k
  (void) dns_text_to_value_list_first_final;
1021
5.19k
  (void) dns_text_to_value_list_error;
1022
5.19k
  (void) dns_text_to_value_list_en_main;
1023
  
1024
5.19k
#line 1025 "libdnsdist-common.a.p/dnslabeltext.cc"
1025
5.19k
  {
1026
5.19k
  int _klen;
1027
5.19k
  unsigned int _trans;
1028
5.19k
  const char *_acts;
1029
5.19k
  unsigned int _nacts;
1030
5.19k
  const unsigned char *_keys;
1031
1032
5.19k
  if ( p == pe )
1033
15
    goto _test_eof;
1034
5.18k
  if ( cs == 0 )
1035
0
    goto _out;
1036
2.20M
_resume:
1037
2.20M
  _keys = _dns_text_to_value_list_trans_keys + _dns_text_to_value_list_key_offsets[cs];
1038
2.20M
  _trans = _dns_text_to_value_list_index_offsets[cs];
1039
1040
2.20M
  _klen = _dns_text_to_value_list_single_lengths[cs];
1041
2.20M
  if ( _klen > 0 ) {
1042
2.20M
    const unsigned char *_lower = _keys;
1043
2.20M
    const unsigned char *_mid;
1044
2.20M
    const unsigned char *_upper = _keys + _klen - 1;
1045
5.96M
    while (1) {
1046
5.96M
      if ( _upper < _lower )
1047
1.90M
        break;
1048
1049
4.05M
      _mid = _lower + ((_upper-_lower) >> 1);
1050
4.05M
      if ( (*p) < *_mid )
1051
948k
        _upper = _mid - 1;
1052
3.10M
      else if ( (*p) > *_mid )
1053
2.81M
        _lower = _mid + 1;
1054
296k
      else {
1055
296k
        _trans += (unsigned int)(_mid - _keys);
1056
296k
        goto _match;
1057
296k
      }
1058
4.05M
    }
1059
1.90M
    _keys += _klen;
1060
1.90M
    _trans += _klen;
1061
1.90M
  }
1062
1063
1.90M
  _klen = _dns_text_to_value_list_range_lengths[cs];
1064
1.90M
  if ( _klen > 0 ) {
1065
0
    const unsigned char *_lower = _keys;
1066
0
    const unsigned char *_mid;
1067
0
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
1068
0
    while (1) {
1069
0
      if ( _upper < _lower )
1070
0
        break;
1071
1072
0
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
1073
0
      if ( (*p) < _mid[0] )
1074
0
        _upper = _mid - 2;
1075
0
      else if ( (*p) > _mid[1] )
1076
0
        _lower = _mid + 2;
1077
0
      else {
1078
0
        _trans += (unsigned int)((_mid - _keys)>>1);
1079
0
        goto _match;
1080
0
      }
1081
0
    }
1082
0
    _trans += _klen;
1083
0
  }
1084
1085
2.20M
_match:
1086
2.20M
  _trans = _dns_text_to_value_list_indicies[_trans];
1087
2.20M
  cs = _dns_text_to_value_list_trans_targs[_trans];
1088
1089
2.20M
  if ( _dns_text_to_value_list_trans_actions[_trans] == 0 )
1090
4
    goto _again;
1091
1092
2.20M
  _acts = _dns_text_to_value_list_actions + _dns_text_to_value_list_trans_actions[_trans];
1093
2.20M
  _nacts = (unsigned int) *_acts++;
1094
4.70M
  while ( _nacts-- > 0 )
1095
2.50M
  {
1096
2.50M
    switch ( *_acts++ )
1097
2.50M
    {
1098
1.90M
  case 0:
1099
1.90M
#line 330 ".././dnslabeltext.rl"
1100
1.90M
  {
1101
1.90M
    tmp += (*p);
1102
1.90M
    counter++;
1103
1.90M
  }
1104
1.90M
  break;
1105
401
  case 1:
1106
401
#line 335 ".././dnslabeltext.rl"
1107
401
  {
1108
401
    tmp += (*p);
1109
401
  }
1110
401
  break;
1111
295k
  case 2:
1112
295k
#line 339 ".././dnslabeltext.rl"
1113
295k
  {
1114
295k
    val.push_back(tmp);
1115
295k
    tmp.clear();
1116
295k
    counter++;
1117
295k
  }
1118
295k
  break;
1119
296k
  case 3:
1120
296k
#line 345 ".././dnslabeltext.rl"
1121
296k
  {
1122
296k
    counter++;
1123
296k
  }
1124
296k
  break;
1125
2.50M
#line 1126 "libdnsdist-common.a.p/dnslabeltext.cc"
1126
2.50M
    }
1127
2.50M
  }
1128
1129
2.20M
_again:
1130
2.20M
  if ( cs == 0 )
1131
4
    goto _out;
1132
2.20M
  if ( ++p != pe )
1133
2.20M
    goto _resume;
1134
5.19k
  _test_eof: {}
1135
5.19k
  if ( p == eof )
1136
5.19k
  {
1137
5.19k
  const char *__acts = _dns_text_to_value_list_actions + _dns_text_to_value_list_eof_actions[cs];
1138
5.19k
  unsigned int __nacts = (unsigned int) *__acts++;
1139
10.3k
  while ( __nacts-- > 0 ) {
1140
5.15k
    switch ( *__acts++ ) {
1141
5.15k
  case 2:
1142
5.15k
#line 339 ".././dnslabeltext.rl"
1143
5.15k
  {
1144
5.15k
    val.push_back(tmp);
1145
5.15k
    tmp.clear();
1146
5.15k
    counter++;
1147
5.15k
  }
1148
5.15k
  break;
1149
5.15k
#line 1150 "libdnsdist-common.a.p/dnslabeltext.cc"
1150
5.15k
    }
1151
5.15k
  }
1152
5.19k
  }
1153
1154
5.19k
  _out: {}
1155
5.19k
  }
1156
1157
0
#line 366 ".././dnslabeltext.rl"
1158
1159
5.19k
  if ( cs < dns_text_to_value_list_first_final ) {
1160
28
          throw runtime_error("Unable to parse DNS SVCB value list '"+in+"'");
1161
28
  }
1162
1163
5.17k
  return counter;
1164
5.19k
}
1165
1166
1167
#if 0
1168
int main()
1169
{
1170
  //char blah[]="\"blah\" \"bleh\" \"bloeh\\\"bleh\" \"\\97enzo\"";
1171
  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\"";
1172
  //char blah[]="\"abc \\097\\098 def\"";
1173
  printf("Input: '%s'\n", blah);
1174
  vector<string> res=dnstext(blah);
1175
  cerr<<res.size()<<" segments"<<endl;
1176
  cerr<<res[0]<<endl;
1177
}
1178
#endif