Coverage Report

Created: 2026-10-16 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pdns/pdns/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
1.88M
{
17
1.88M
  if(segment.size()>254) {
18
6.53k
    ret.push_back(segment);
19
6.53k
    segment.clear();
20
6.53k
  }
21
1.88M
  segment.append(1, c);
22
1.88M
}
23
24
}
25
26
vector<string> segmentDNSText(const string& input )
27
751
{
28
  // cerr<<"segmentDNSText("<<input<<")"<<endl; 
29
30
751
#line 31 "dnslabeltext.cc"
31
751
static const char _dnstext_actions[] = {
32
751
  0, 1, 0, 1, 1, 1, 2, 1, 
33
751
  3, 1, 4, 1, 5, 2, 0, 1, 
34
751
  2, 4, 5
35
751
};
36
37
751
static const char _dnstext_key_offsets[] = {
38
751
  0, 0, 1, 3, 5, 7, 9, 11, 
39
751
  15
40
751
};
41
42
751
static const unsigned char _dnstext_trans_keys[] = {
43
751
  34u, 34u, 92u, 48u, 57u, 48u, 57u, 48u, 
44
751
  57u, 34u, 92u, 32u, 34u, 9u, 13u, 34u, 
45
751
  0
46
751
};
47
48
751
static const char _dnstext_single_lengths[] = {
49
751
  0, 1, 2, 0, 0, 0, 2, 2, 
50
751
  1
51
751
};
52
53
751
static const char _dnstext_range_lengths[] = {
54
751
  0, 0, 0, 1, 1, 1, 0, 1, 
55
751
  0
56
751
};
57
58
751
static const char _dnstext_index_offsets[] = {
59
751
  0, 0, 2, 5, 7, 9, 11, 14, 
60
751
  18
61
751
};
62
63
751
static const char _dnstext_trans_targs[] = {
64
751
  2, 0, 7, 3, 2, 4, 2, 5, 
65
751
  0, 6, 0, 7, 3, 2, 8, 2, 
66
751
  8, 0, 2, 0, 0
67
751
};
68
69
751
static const char _dnstext_trans_actions[] = {
70
751
  3, 0, 0, 0, 11, 7, 5, 7, 
71
751
  0, 7, 0, 9, 9, 16, 0, 13, 
72
751
  0, 0, 13, 0, 0
73
751
};
74
75
751
static const char _dnstext_eof_actions[] = {
76
751
  0, 0, 0, 0, 0, 0, 0, 1, 
77
751
  1
78
751
};
79
80
751
static const int dnstext_start = 1;
81
751
static const int dnstext_first_final = 7;
82
751
static const int dnstext_error = 0;
83
84
751
static const int dnstext_en_main = 1;
85
86
87
751
#line 31 "dnslabeltext.rl"
88
89
751
  (void)dnstext_error;  // silence warnings
90
751
  (void)dnstext_en_main;
91
751
        const char *p = input.c_str(), *pe = input.c_str() + input.length();
92
751
        const char* eof = pe;
93
751
        int cs;
94
751
        char val = 0;
95
96
751
        string segment;
97
751
        vector<string> ret;
98
99
        
100
751
#line 101 "dnslabeltext.cc"
101
751
  {
102
751
  cs = dnstext_start;
103
751
  }
104
105
751
#line 106 "dnslabeltext.cc"
106
751
  {
107
751
  int _klen;
108
751
  unsigned int _trans;
109
751
  const char *_acts;
110
751
  unsigned int _nacts;
111
751
  const unsigned char *_keys;
112
113
751
  if ( p == pe )
114
0
    goto _test_eof;
115
751
  if ( cs == 0 )
116
0
    goto _out;
117
2.36M
_resume:
118
2.36M
  _keys = _dnstext_trans_keys + _dnstext_key_offsets[cs];
119
2.36M
  _trans = _dnstext_index_offsets[cs];
120
121
2.36M
  _klen = _dnstext_single_lengths[cs];
122
2.36M
  if ( _klen > 0 ) {
123
2.34M
    const unsigned char *_lower = _keys;
124
2.34M
    const unsigned char *_mid;
125
2.34M
    const unsigned char *_upper = _keys + _klen - 1;
126
5.50M
    while (1) {
127
5.50M
      if ( _upper < _lower )
128
1.86M
        break;
129
130
3.64M
      _mid = _lower + ((_upper-_lower) >> 1);
131
3.64M
      if ( (*p) < *_mid )
132
1.11M
        _upper = _mid - 1;
133
2.53M
      else if ( (*p) > *_mid )
134
2.05M
        _lower = _mid + 1;
135
475k
      else {
136
475k
        _trans += (unsigned int)(_mid - _keys);
137
475k
        goto _match;
138
475k
      }
139
3.64M
    }
140
1.86M
    _keys += _klen;
141
1.86M
    _trans += _klen;
142
1.86M
  }
143
144
1.89M
  _klen = _dnstext_range_lengths[cs];
145
1.89M
  if ( _klen > 0 ) {
146
25.5k
    const unsigned char *_lower = _keys;
147
25.5k
    const unsigned char *_mid;
148
25.5k
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
149
44.9k
    while (1) {
150
44.9k
      if ( _upper < _lower )
151
19.4k
        break;
152
153
25.5k
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
154
25.5k
      if ( (*p) < _mid[0] )
155
1.50k
        _upper = _mid - 2;
156
24.0k
      else if ( (*p) > _mid[1] )
157
17.9k
        _lower = _mid + 2;
158
6.14k
      else {
159
6.14k
        _trans += (unsigned int)((_mid - _keys)>>1);
160
6.14k
        goto _match;
161
6.14k
      }
162
25.5k
    }
163
19.4k
    _trans += _klen;
164
19.4k
  }
165
166
2.36M
_match:
167
2.36M
  cs = _dnstext_trans_targs[_trans];
168
169
2.36M
  if ( _dnstext_trans_actions[_trans] == 0 )
170
322k
    goto _again;
171
172
2.04M
  _acts = _dnstext_actions + _dnstext_trans_actions[_trans];
173
2.04M
  _nacts = (unsigned int) *_acts++;
174
4.24M
  while ( _nacts-- > 0 )
175
2.19M
  {
176
2.19M
    switch ( *_acts++ )
177
2.19M
    {
178
150k
  case 0:
179
150k
#line 43 "dnslabeltext.rl"
180
150k
  { 
181
150k
                        ret.push_back(segment);
182
150k
                        segment.clear();
183
150k
                }
184
150k
  break;
185
151k
  case 1:
186
151k
#line 47 "dnslabeltext.rl"
187
151k
  { 
188
151k
                        segment.clear();
189
151k
                }
190
151k
  break;
191
19.4k
  case 2:
192
19.4k
#line 51 "dnslabeltext.rl"
193
19.4k
  {
194
19.4k
                  char c = *p;
195
19.4k
                  appendSplit(ret, segment, c);
196
19.4k
                }
197
19.4k
  break;
198
6.13k
  case 3:
199
6.13k
#line 55 "dnslabeltext.rl"
200
6.13k
  {
201
6.13k
                  char c = *p;
202
6.13k
                  val *= 10;
203
6.13k
                  val += c-'0';
204
                  
205
6.13k
                }
206
6.13k
  break;
207
2.04k
  case 4:
208
2.04k
#line 61 "dnslabeltext.rl"
209
2.04k
  {
210
2.04k
                  appendSplit(ret, segment, val);
211
2.04k
                  val=0;
212
2.04k
                }
213
2.04k
  break;
214
1.86M
  case 5:
215
1.86M
#line 66 "dnslabeltext.rl"
216
1.86M
  {
217
1.86M
                  appendSplit(ret, segment, *(p));
218
1.86M
                }
219
1.86M
  break;
220
2.19M
#line 221 "dnslabeltext.cc"
221
2.19M
    }
222
2.19M
  }
223
224
2.36M
_again:
225
2.36M
  if ( cs == 0 )
226
4
    goto _out;
227
2.36M
  if ( ++p != pe )
228
2.36M
    goto _resume;
229
747
  _test_eof: {}
230
747
  if ( p == eof )
231
747
  {
232
747
  const char *__acts = _dnstext_actions + _dnstext_eof_actions[cs];
233
747
  unsigned int __nacts = (unsigned int) *__acts++;
234
1.45k
  while ( __nacts-- > 0 ) {
235
704
    switch ( *__acts++ ) {
236
704
  case 0:
237
704
#line 43 "dnslabeltext.rl"
238
704
  { 
239
704
                        ret.push_back(segment);
240
704
                        segment.clear();
241
704
                }
242
704
  break;
243
704
#line 244 "dnslabeltext.cc"
244
704
    }
245
704
  }
246
747
  }
247
248
751
  _out: {}
249
751
  }
250
251
0
#line 79 "dnslabeltext.rl"
252
253
254
751
        if ( cs < dnstext_first_final ) {
255
47
                throw runtime_error("Unable to parse DNS TXT '"+input+"'");
256
47
        }
257
258
704
        return ret;
259
751
};
260
261
262
DNSName::string_t segmentDNSNameRaw(const char* realinput, size_t inputlen)
263
25.0k
{
264
265
25.0k
#line 266 "dnslabeltext.cc"
266
25.0k
static const char _dnsnameraw_actions[] = {
267
25.0k
  0, 1, 0, 1, 1, 1, 2, 1, 
268
25.0k
  3, 1, 4, 1, 5, 2, 1, 5, 
269
25.0k
  2, 4, 0, 2, 4, 5
270
25.0k
};
271
272
25.0k
static const char _dnsnameraw_key_offsets[] = {
273
25.0k
  0, 0, 2, 4, 6, 8, 10, 12
274
25.0k
};
275
276
25.0k
static const unsigned char _dnsnameraw_trans_keys[] = {
277
25.0k
  46u, 92u, 48u, 57u, 48u, 57u, 48u, 57u, 
278
25.0k
  46u, 92u, 46u, 92u, 46u, 92u, 0
279
25.0k
};
280
281
25.0k
static const char _dnsnameraw_single_lengths[] = {
282
25.0k
  0, 2, 0, 0, 0, 2, 2, 2
283
25.0k
};
284
285
25.0k
static const char _dnsnameraw_range_lengths[] = {
286
25.0k
  0, 0, 1, 1, 1, 0, 0, 0
287
25.0k
};
288
289
25.0k
static const char _dnsnameraw_index_offsets[] = {
290
25.0k
  0, 0, 3, 5, 7, 9, 12, 15
291
25.0k
};
292
293
25.0k
static const char _dnsnameraw_trans_targs[] = {
294
25.0k
  0, 2, 5, 3, 5, 4, 0, 7, 
295
25.0k
  0, 6, 2, 5, 0, 2, 5, 6, 
296
25.0k
  2, 5, 0
297
25.0k
};
298
299
25.0k
static const char _dnsnameraw_trans_actions[] = {
300
25.0k
  0, 3, 13, 7, 5, 7, 0, 7, 
301
25.0k
  0, 1, 0, 11, 0, 3, 13, 16, 
302
25.0k
  9, 19, 0
303
25.0k
};
304
305
25.0k
static const char _dnsnameraw_eof_actions[] = {
306
25.0k
  0, 0, 0, 0, 0, 1, 0, 16
307
25.0k
};
308
309
25.0k
static const int dnsnameraw_start = 1;
310
25.0k
static const int dnsnameraw_first_final = 5;
311
25.0k
static const int dnsnameraw_error = 0;
312
313
25.0k
static const int dnsnameraw_en_main = 1;
314
315
316
25.0k
#line 95 "dnslabeltext.rl"
317
318
25.0k
  (void)dnsnameraw_error;  // silence warnings
319
25.0k
  (void)dnsnameraw_en_main;
320
321
25.0k
        DNSName::string_t ret;
322
323
25.0k
        if(!*realinput || *realinput == '.') {
324
1.28k
          ret.append(1, (char)0);
325
1.28k
          return ret;
326
1.28k
        }
327
328
23.8k
        ret.reserve(inputlen+1);
329
330
23.8k
        const char *p = realinput, *pe = realinput + inputlen;
331
23.8k
        const char* eof = pe;
332
23.8k
        int cs;
333
23.8k
        char val = 0;
334
23.8k
        unsigned char labellen=0;
335
23.8k
        unsigned int lenpos=0;
336
        
337
23.8k
#line 338 "dnslabeltext.cc"
338
23.8k
  {
339
23.8k
  cs = dnsnameraw_start;
340
23.8k
  }
341
342
23.8k
#line 343 "dnslabeltext.cc"
343
23.8k
  {
344
23.8k
  int _klen;
345
23.8k
  unsigned int _trans;
346
23.8k
  const char *_acts;
347
23.8k
  unsigned int _nacts;
348
23.8k
  const unsigned char *_keys;
349
350
23.8k
  if ( p == pe )
351
0
    goto _test_eof;
352
23.8k
  if ( cs == 0 )
353
0
    goto _out;
354
288M
_resume:
355
288M
  _keys = _dnsnameraw_trans_keys + _dnsnameraw_key_offsets[cs];
356
288M
  _trans = _dnsnameraw_index_offsets[cs];
357
358
288M
  _klen = _dnsnameraw_single_lengths[cs];
359
288M
  if ( _klen > 0 ) {
360
288M
    const unsigned char *_lower = _keys;
361
288M
    const unsigned char *_mid;
362
288M
    const unsigned char *_upper = _keys + _klen - 1;
363
865M
    while (1) {
364
865M
      if ( _upper < _lower )
365
288M
        break;
366
367
576M
      _mid = _lower + ((_upper-_lower) >> 1);
368
576M
      if ( (*p) < *_mid )
369
288M
        _upper = _mid - 1;
370
288M
      else if ( (*p) > *_mid )
371
288M
        _lower = _mid + 1;
372
76.4k
      else {
373
76.4k
        _trans += (unsigned int)(_mid - _keys);
374
76.4k
        goto _match;
375
76.4k
      }
376
576M
    }
377
288M
    _keys += _klen;
378
288M
    _trans += _klen;
379
288M
  }
380
381
288M
  _klen = _dnsnameraw_range_lengths[cs];
382
288M
  if ( _klen > 0 ) {
383
55.4k
    const unsigned char *_lower = _keys;
384
55.4k
    const unsigned char *_mid;
385
55.4k
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
386
78.1k
    while (1) {
387
78.1k
      if ( _upper < _lower )
388
22.7k
        break;
389
390
55.4k
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
391
55.4k
      if ( (*p) < _mid[0] )
392
9.82k
        _upper = _mid - 2;
393
45.6k
      else if ( (*p) > _mid[1] )
394
12.8k
        _lower = _mid + 2;
395
32.7k
      else {
396
32.7k
        _trans += (unsigned int)((_mid - _keys)>>1);
397
32.7k
        goto _match;
398
32.7k
      }
399
55.4k
    }
400
22.7k
    _trans += _klen;
401
22.7k
  }
402
403
288M
_match:
404
288M
  cs = _dnsnameraw_trans_targs[_trans];
405
406
288M
  if ( _dnsnameraw_trans_actions[_trans] == 0 )
407
28.3k
    goto _again;
408
409
288M
  _acts = _dnsnameraw_actions + _dnsnameraw_trans_actions[_trans];
410
288M
  _nacts = (unsigned int) *_acts++;
411
577M
  while ( _nacts-- > 0 )
412
288M
  {
413
288M
    switch ( *_acts++ )
414
288M
    {
415
42.6k
  case 0:
416
42.6k
#line 115 "dnslabeltext.rl"
417
42.6k
  { 
418
42.6k
                        if (labellen > 63) {
419
77
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
420
77
                        }
421
42.5k
                        ret[lenpos]=labellen;
422
42.5k
                        labellen=0;
423
42.5k
                }
424
0
  break;
425
61.0k
  case 1:
426
61.0k
#line 122 "dnslabeltext.rl"
427
61.0k
  { 
428
61.0k
                        lenpos=ret.size();
429
61.0k
                        ret.append(1, (char)0);
430
61.0k
                        labellen=0;
431
61.0k
                }
432
61.0k
  break;
433
22.7k
  case 2:
434
22.7k
#line 128 "dnslabeltext.rl"
435
22.7k
  {
436
22.7k
                  char c = *p;
437
22.7k
                  ret.append(1, c);
438
22.7k
                  labellen++;
439
22.7k
                }
440
22.7k
  break;
441
32.7k
  case 3:
442
32.7k
#line 133 "dnslabeltext.rl"
443
32.7k
  {
444
32.7k
                  char c = *p;
445
32.7k
                  val *= 10;
446
32.7k
                  val += c-'0';
447
32.7k
                }
448
32.7k
  break;
449
9.49k
  case 4:
450
9.49k
#line 138 "dnslabeltext.rl"
451
9.49k
  {
452
9.49k
                  ret.append(1, val);
453
9.49k
                  labellen++;
454
9.49k
                  val=0;
455
9.49k
                }
456
9.49k
  break;
457
288M
  case 5:
458
288M
#line 144 "dnslabeltext.rl"
459
288M
  {
460
288M
                  ret.append(1, *(p));
461
288M
                  labellen++;
462
288M
                }
463
288M
  break;
464
288M
#line 465 "dnslabeltext.cc"
465
288M
    }
466
288M
  }
467
468
288M
_again:
469
288M
  if ( cs == 0 )
470
29
    goto _out;
471
288M
  if ( ++p != pe )
472
288M
    goto _resume;
473
23.6k
  _test_eof: {}
474
23.6k
  if ( p == eof )
475
23.6k
  {
476
23.6k
  const char *__acts = _dnsnameraw_actions + _dnsnameraw_eof_actions[cs];
477
23.6k
  unsigned int __nacts = (unsigned int) *__acts++;
478
43.2k
  while ( __nacts-- > 0 ) {
479
19.6k
    switch ( *__acts++ ) {
480
18.2k
  case 0:
481
18.2k
#line 115 "dnslabeltext.rl"
482
18.2k
  { 
483
18.2k
                        if (labellen > 63) {
484
83
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
485
83
                        }
486
18.2k
                        ret[lenpos]=labellen;
487
18.2k
                        labellen=0;
488
18.2k
                }
489
0
  break;
490
1.39k
  case 4:
491
1.39k
#line 138 "dnslabeltext.rl"
492
1.39k
  {
493
1.39k
                  ret.append(1, val);
494
1.39k
                  labellen++;
495
1.39k
                  val=0;
496
1.39k
                }
497
1.39k
  break;
498
19.6k
#line 499 "dnslabeltext.cc"
499
19.6k
    }
500
19.6k
  }
501
23.6k
  }
502
503
23.6k
  _out: {}
504
23.6k
  }
505
506
0
#line 165 "dnslabeltext.rl"
507
508
509
23.6k
        if ( cs < dnsnameraw_first_final ) {
510
185
                throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': cs="+std::to_string(cs));
511
185
        }
512
23.4k
        ret.append(1, (char)0);
513
23.4k
        return ret;
514
23.6k
};
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
4.97k
size_t parseRFC1035CharString(std::string_view in, std::string &val) {
519
520
4.97k
  val.clear();
521
4.97k
  val.reserve(in.size());
522
4.97k
  const char *p = in.data();
523
4.97k
  const char *pe = p + in.size();
524
4.97k
  int cs = 0;
525
4.97k
  uint8_t escaped_octet = 0;
526
  // Keeps track of how many chars we read from the source string
527
4.97k
  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
4.97k
#line 536 "dnslabeltext.cc"
536
4.97k
static const char _dns_text_to_string_actions[] = {
537
4.97k
  0, 1, 0, 1, 2, 1, 3, 2, 
538
4.97k
  0, 1
539
4.97k
};
540
541
4.97k
static const char _dns_text_to_string_key_offsets[] = {
542
4.97k
  0, 0, 8, 15, 17, 19, 22, 24, 
543
4.97k
  33, 41, 43, 45, 48, 50, 58
544
4.97k
};
545
546
4.97k
static const char _dns_text_to_string_trans_keys[] = {
547
4.97k
  34, 92, 33, 39, 42, 58, 60, 126, 
548
4.97k
  50, 33, 47, 48, 49, 58, 126, 48, 
549
4.97k
  57, 48, 57, 53, 48, 52, 48, 53, 
550
4.97k
  9, 34, 92, 32, 39, 42, 58, 60, 
551
4.97k
  126, 9, 50, 32, 47, 48, 49, 58, 
552
4.97k
  126, 48, 57, 48, 57, 53, 48, 52, 
553
4.97k
  48, 53, 33, 92, 35, 39, 42, 58, 
554
4.97k
  60, 126, 0
555
4.97k
};
556
557
4.97k
static const char _dns_text_to_string_single_lengths[] = {
558
4.97k
  0, 2, 1, 0, 0, 1, 0, 3, 
559
4.97k
  2, 0, 0, 1, 0, 2, 0
560
4.97k
};
561
562
4.97k
static const char _dns_text_to_string_range_lengths[] = {
563
4.97k
  0, 3, 3, 1, 1, 1, 1, 3, 
564
4.97k
  3, 1, 1, 1, 1, 3, 0
565
4.97k
};
566
567
4.97k
static const char _dns_text_to_string_index_offsets[] = {
568
4.97k
  0, 0, 6, 11, 13, 15, 18, 20, 
569
4.97k
  27, 33, 35, 37, 40, 42, 48
570
4.97k
};
571
572
4.97k
static const char _dns_text_to_string_indicies[] = {
573
4.97k
  2, 3, 0, 0, 0, 1, 5, 0, 
574
4.97k
  4, 0, 1, 6, 1, 7, 1, 8, 
575
4.97k
  6, 1, 7, 1, 9, 10, 11, 9, 
576
4.97k
  9, 9, 1, 9, 13, 9, 12, 9, 
577
4.97k
  1, 14, 1, 15, 1, 16, 14, 1, 
578
4.97k
  15, 1, 0, 3, 0, 0, 0, 1, 
579
4.97k
  1, 0
580
4.97k
};
581
582
4.97k
static const char _dns_text_to_string_trans_targs[] = {
583
4.97k
  13, 0, 7, 2, 3, 5, 4, 13, 
584
4.97k
  6, 7, 14, 8, 9, 11, 10, 7, 
585
4.97k
  12
586
4.97k
};
587
588
4.97k
static const char _dns_text_to_string_trans_actions[] = {
589
4.97k
  3, 0, 5, 5, 1, 1, 1, 7, 
590
4.97k
  1, 3, 5, 5, 1, 1, 1, 7, 
591
4.97k
  1
592
4.97k
};
593
594
4.97k
static const int dns_text_to_string_start = 1;
595
4.97k
static const int dns_text_to_string_first_final = 13;
596
4.97k
static const int dns_text_to_string_error = 0;
597
598
4.97k
static const int dns_text_to_string_en_main = 1;
599
600
601
4.97k
#line 602 "dnslabeltext.cc"
602
4.97k
  {
603
4.97k
  cs = dns_text_to_string_start;
604
4.97k
  }
605
606
4.97k
#line 233 "dnslabeltext.rl"
607
608
609
  // silence warnings
610
4.97k
  (void) dns_text_to_string_first_final;
611
4.97k
  (void) dns_text_to_string_error;
612
4.97k
  (void) dns_text_to_string_en_main;
613
  
614
4.97k
#line 615 "dnslabeltext.cc"
615
4.97k
  {
616
4.97k
  int _klen;
617
4.97k
  unsigned int _trans;
618
4.97k
  const char *_acts;
619
4.97k
  unsigned int _nacts;
620
4.97k
  const char *_keys;
621
622
4.97k
  if ( p == pe )
623
183
    goto _test_eof;
624
4.78k
  if ( cs == 0 )
625
0
    goto _out;
626
6.83M
_resume:
627
6.83M
  _keys = _dns_text_to_string_trans_keys + _dns_text_to_string_key_offsets[cs];
628
6.83M
  _trans = _dns_text_to_string_index_offsets[cs];
629
630
6.83M
  _klen = _dns_text_to_string_single_lengths[cs];
631
6.83M
  if ( _klen > 0 ) {
632
6.83M
    const char *_lower = _keys;
633
6.83M
    const char *_mid;
634
6.83M
    const char *_upper = _keys + _klen - 1;
635
19.0M
    while (1) {
636
19.0M
      if ( _upper < _lower )
637
5.43M
        break;
638
639
13.6M
      _mid = _lower + ((_upper-_lower) >> 1);
640
13.6M
      if ( (*p) < *_mid )
641
4.61M
        _upper = _mid - 1;
642
9.04M
      else if ( (*p) > *_mid )
643
7.63M
        _lower = _mid + 1;
644
1.40M
      else {
645
1.40M
        _trans += (unsigned int)(_mid - _keys);
646
1.40M
        goto _match;
647
1.40M
      }
648
13.6M
    }
649
5.43M
    _keys += _klen;
650
5.43M
    _trans += _klen;
651
5.43M
  }
652
653
5.43M
  _klen = _dns_text_to_string_range_lengths[cs];
654
5.43M
  if ( _klen > 0 ) {
655
5.43M
    const char *_lower = _keys;
656
5.43M
    const char *_mid;
657
5.43M
    const char *_upper = _keys + (_klen<<1) - 2;
658
8.23M
    while (1) {
659
8.23M
      if ( _upper < _lower )
660
3.01k
        break;
661
662
8.23M
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
663
8.23M
      if ( (*p) < _mid[0] )
664
99.1k
        _upper = _mid - 2;
665
8.13M
      else if ( (*p) > _mid[1] )
666
2.69M
        _lower = _mid + 2;
667
5.43M
      else {
668
5.43M
        _trans += (unsigned int)((_mid - _keys)>>1);
669
5.43M
        goto _match;
670
5.43M
      }
671
8.23M
    }
672
3.01k
    _trans += _klen;
673
3.01k
  }
674
675
6.83M
_match:
676
6.83M
  _trans = _dns_text_to_string_indicies[_trans];
677
6.83M
  cs = _dns_text_to_string_trans_targs[_trans];
678
679
6.83M
  if ( _dns_text_to_string_trans_actions[_trans] == 0 )
680
3.03k
    goto _again;
681
682
6.83M
  _acts = _dns_text_to_string_actions + _dns_text_to_string_trans_actions[_trans];
683
6.83M
  _nacts = (unsigned int) *_acts++;
684
13.6M
  while ( _nacts-- > 0 )
685
6.83M
  {
686
6.83M
    switch ( *_acts++ )
687
6.83M
    {
688
4.58k
  case 0:
689
4.58k
#line 195 "dnslabeltext.rl"
690
4.58k
  {
691
4.58k
    escaped_octet *= 10;
692
4.58k
    escaped_octet += (*p)-'0';
693
4.58k
    counter++;
694
4.58k
  }
695
4.58k
  break;
696
1.50k
  case 1:
697
1.50k
#line 201 "dnslabeltext.rl"
698
1.50k
  {
699
1.50k
    val += escaped_octet;
700
1.50k
    escaped_octet = 0;
701
1.50k
  }
702
1.50k
  break;
703
6.82M
  case 2:
704
6.82M
#line 206 "dnslabeltext.rl"
705
6.82M
  {
706
6.82M
    val += (*p);
707
6.82M
    counter++;
708
6.82M
  }
709
6.82M
  break;
710
3.29k
  case 3:
711
3.29k
#line 211 "dnslabeltext.rl"
712
3.29k
  {
713
3.29k
    counter++;
714
3.29k
  }
715
3.29k
  break;
716
6.83M
#line 717 "dnslabeltext.cc"
717
6.83M
    }
718
6.83M
  }
719
720
6.83M
_again:
721
6.83M
  if ( cs == 0 )
722
3.03k
    goto _out;
723
6.83M
  if ( ++p != pe )
724
6.83M
    goto _resume;
725
1.94k
  _test_eof: {}
726
4.97k
  _out: {}
727
4.97k
  }
728
729
0
#line 240 "dnslabeltext.rl"
730
731
0
  return counter;
732
1.94k
}
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 "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 "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 "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 "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
1.24k
size_t parseSVCBValueListFromParsedRFC1035CharString(const std::string &in, std::vector<std::string> &val) {
948
1.24k
  val.clear();
949
1.24k
  const char *p = in.c_str();
950
1.24k
  const char *pe = p + in.size();
951
1.24k
  int cs = 0;
952
1.24k
  const char* eof = pe;
953
  // Keeps track of how many chars we read from the source string
954
1.24k
  size_t counter=0;
955
956
  // Here we store the parsed value until we hit a comma or are done
957
1.24k
  std::string tmp;
958
959
960
1.24k
#line 961 "dnslabeltext.cc"
961
1.24k
static const char _dns_text_to_value_list_actions[] = {
962
1.24k
  0, 1, 0, 1, 2, 1, 3, 2, 
963
1.24k
  2, 3, 2, 3, 1
964
1.24k
};
965
966
1.24k
static const char _dns_text_to_value_list_key_offsets[] = {
967
1.24k
  0, 0, 2, 4, 6
968
1.24k
};
969
970
1.24k
static const unsigned char _dns_text_to_value_list_trans_keys[] = {
971
1.24k
  44u, 92u, 44u, 92u, 44u, 92u, 44u, 92u, 
972
1.24k
  0
973
1.24k
};
974
975
1.24k
static const char _dns_text_to_value_list_single_lengths[] = {
976
1.24k
  0, 2, 2, 2, 2
977
1.24k
};
978
979
1.24k
static const char _dns_text_to_value_list_range_lengths[] = {
980
1.24k
  0, 0, 0, 0, 0
981
1.24k
};
982
983
1.24k
static const char _dns_text_to_value_list_index_offsets[] = {
984
1.24k
  0, 0, 3, 6, 9
985
1.24k
};
986
987
1.24k
static const char _dns_text_to_value_list_indicies[] = {
988
1.24k
  1, 2, 0, 3, 3, 1, 1, 2, 
989
1.24k
  0, 4, 2, 0, 0
990
1.24k
};
991
992
1.24k
static const char _dns_text_to_value_list_trans_targs[] = {
993
1.24k
  4, 0, 2, 4, 1
994
1.24k
};
995
996
1.24k
static const char _dns_text_to_value_list_trans_actions[] = {
997
1.24k
  1, 0, 5, 10, 7
998
1.24k
};
999
1000
1.24k
static const char _dns_text_to_value_list_eof_actions[] = {
1001
1.24k
  0, 0, 0, 0, 3
1002
1.24k
};
1003
1004
1.24k
static const int dns_text_to_value_list_start = 3;
1005
1.24k
static const int dns_text_to_value_list_first_final = 3;
1006
1.24k
static const int dns_text_to_value_list_error = 0;
1007
1008
1.24k
static const int dns_text_to_value_list_en_main = 3;
1009
1010
1011
1.24k
#line 1012 "dnslabeltext.cc"
1012
1.24k
  {
1013
1.24k
  cs = dns_text_to_value_list_start;
1014
1.24k
  }
1015
1016
1.24k
#line 359 "dnslabeltext.rl"
1017
1018
1019
  // silence warnings
1020
1.24k
  (void) dns_text_to_value_list_first_final;
1021
1.24k
  (void) dns_text_to_value_list_error;
1022
1.24k
  (void) dns_text_to_value_list_en_main;
1023
  
1024
1.24k
#line 1025 "dnslabeltext.cc"
1025
1.24k
  {
1026
1.24k
  int _klen;
1027
1.24k
  unsigned int _trans;
1028
1.24k
  const char *_acts;
1029
1.24k
  unsigned int _nacts;
1030
1.24k
  const unsigned char *_keys;
1031
1032
1.24k
  if ( p == pe )
1033
23
    goto _test_eof;
1034
1.22k
  if ( cs == 0 )
1035
0
    goto _out;
1036
1.88M
_resume:
1037
1.88M
  _keys = _dns_text_to_value_list_trans_keys + _dns_text_to_value_list_key_offsets[cs];
1038
1.88M
  _trans = _dns_text_to_value_list_index_offsets[cs];
1039
1040
1.88M
  _klen = _dns_text_to_value_list_single_lengths[cs];
1041
1.88M
  if ( _klen > 0 ) {
1042
1.88M
    const unsigned char *_lower = _keys;
1043
1.88M
    const unsigned char *_mid;
1044
1.88M
    const unsigned char *_upper = _keys + _klen - 1;
1045
4.69M
    while (1) {
1046
4.69M
      if ( _upper < _lower )
1047
1.40M
        break;
1048
1049
3.28M
      _mid = _lower + ((_upper-_lower) >> 1);
1050
3.28M
      if ( (*p) < *_mid )
1051
909k
        _upper = _mid - 1;
1052
2.37M
      else if ( (*p) > *_mid )
1053
1.89M
        _lower = _mid + 1;
1054
480k
      else {
1055
480k
        _trans += (unsigned int)(_mid - _keys);
1056
480k
        goto _match;
1057
480k
      }
1058
3.28M
    }
1059
1.40M
    _keys += _klen;
1060
1.40M
    _trans += _klen;
1061
1.40M
  }
1062
1063
1.40M
  _klen = _dns_text_to_value_list_range_lengths[cs];
1064
1.40M
  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
1.88M
_match:
1086
1.88M
  _trans = _dns_text_to_value_list_indicies[_trans];
1087
1.88M
  cs = _dns_text_to_value_list_trans_targs[_trans];
1088
1089
1.88M
  if ( _dns_text_to_value_list_trans_actions[_trans] == 0 )
1090
6
    goto _again;
1091
1092
1.88M
  _acts = _dns_text_to_value_list_actions + _dns_text_to_value_list_trans_actions[_trans];
1093
1.88M
  _nacts = (unsigned int) *_acts++;
1094
4.25M
  while ( _nacts-- > 0 )
1095
2.36M
  {
1096
2.36M
    switch ( *_acts++ )
1097
2.36M
    {
1098
1.40M
  case 0:
1099
1.40M
#line 330 "dnslabeltext.rl"
1100
1.40M
  {
1101
1.40M
    tmp += (*p);
1102
1.40M
    counter++;
1103
1.40M
  }
1104
1.40M
  break;
1105
552
  case 1:
1106
552
#line 335 "dnslabeltext.rl"
1107
552
  {
1108
552
    tmp += (*p);
1109
552
  }
1110
552
  break;
1111
479k
  case 2:
1112
479k
#line 339 "dnslabeltext.rl"
1113
479k
  {
1114
479k
    val.push_back(tmp);
1115
479k
    tmp.clear();
1116
479k
    counter++;
1117
479k
  }
1118
479k
  break;
1119
480k
  case 3:
1120
480k
#line 345 "dnslabeltext.rl"
1121
480k
  {
1122
480k
    counter++;
1123
480k
  }
1124
480k
  break;
1125
2.36M
#line 1126 "dnslabeltext.cc"
1126
2.36M
    }
1127
2.36M
  }
1128
1129
1.88M
_again:
1130
1.88M
  if ( cs == 0 )
1131
6
    goto _out;
1132
1.88M
  if ( ++p != pe )
1133
1.88M
    goto _resume;
1134
1.23k
  _test_eof: {}
1135
1.23k
  if ( p == eof )
1136
1.23k
  {
1137
1.23k
  const char *__acts = _dns_text_to_value_list_actions + _dns_text_to_value_list_eof_actions[cs];
1138
1.23k
  unsigned int __nacts = (unsigned int) *__acts++;
1139
2.42k
  while ( __nacts-- > 0 ) {
1140
1.18k
    switch ( *__acts++ ) {
1141
1.18k
  case 2:
1142
1.18k
#line 339 "dnslabeltext.rl"
1143
1.18k
  {
1144
1.18k
    val.push_back(tmp);
1145
1.18k
    tmp.clear();
1146
1.18k
    counter++;
1147
1.18k
  }
1148
1.18k
  break;
1149
1.18k
#line 1150 "dnslabeltext.cc"
1150
1.18k
    }
1151
1.18k
  }
1152
1.23k
  }
1153
1154
1.24k
  _out: {}
1155
1.24k
  }
1156
1157
0
#line 366 "dnslabeltext.rl"
1158
1159
1.24k
  if ( cs < dns_text_to_value_list_first_final ) {
1160
33
          throw runtime_error("Unable to parse DNS SVCB value list '"+in+"'");
1161
33
  }
1162
1163
1.21k
  return counter;
1164
1.24k
}
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