Coverage Report

Created: 2025-08-28 07:00

/src/pdns/pdns/dnslabeltext.cc
Line
Count
Source (jump to first uncovered line)
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 "dnsname.hh"
9
#include "namespaces.hh"
10
#include "dnswriter.hh"
11
#include "misc.hh"
12
13
namespace {
14
void appendSplit(vector<string>& ret, string& segment, char c)
15
0
{
16
0
  if(segment.size()>254) {
17
0
    ret.push_back(segment);
18
0
    segment.clear();
19
0
  }
20
0
  segment.append(1, c);
21
0
}
22
23
}
24
25
vector<string> segmentDNSText(const string& input )
26
0
{
27
  // cerr<<"segmentDNSText("<<input<<")"<<endl; 
28
29
0
#line 30 "dnslabeltext.cc"
30
0
static const char _dnstext_actions[] = {
31
0
  0, 1, 0, 1, 1, 1, 2, 1, 
32
0
  3, 1, 4, 1, 5, 2, 0, 1, 
33
0
  2, 4, 5
34
0
};
35
36
0
static const char _dnstext_key_offsets[] = {
37
0
  0, 0, 1, 3, 5, 7, 9, 11, 
38
0
  15
39
0
};
40
41
0
static const unsigned char _dnstext_trans_keys[] = {
42
0
  34u, 34u, 92u, 48u, 57u, 48u, 57u, 48u, 
43
0
  57u, 34u, 92u, 32u, 34u, 9u, 13u, 34u, 
44
0
  0
45
0
};
46
47
0
static const char _dnstext_single_lengths[] = {
48
0
  0, 1, 2, 0, 0, 0, 2, 2, 
49
0
  1
50
0
};
51
52
0
static const char _dnstext_range_lengths[] = {
53
0
  0, 0, 0, 1, 1, 1, 0, 1, 
54
0
  0
55
0
};
56
57
0
static const char _dnstext_index_offsets[] = {
58
0
  0, 0, 2, 5, 7, 9, 11, 14, 
59
0
  18
60
0
};
61
62
0
static const char _dnstext_trans_targs[] = {
63
0
  2, 0, 7, 3, 2, 4, 2, 5, 
64
0
  0, 6, 0, 7, 3, 2, 8, 2, 
65
0
  8, 0, 2, 0, 0
66
0
};
67
68
0
static const char _dnstext_trans_actions[] = {
69
0
  3, 0, 0, 0, 11, 7, 5, 7, 
70
0
  0, 7, 0, 9, 9, 16, 0, 13, 
71
0
  0, 0, 13, 0, 0
72
0
};
73
74
0
static const char _dnstext_eof_actions[] = {
75
0
  0, 0, 0, 0, 0, 0, 0, 1, 
76
0
  1
77
0
};
78
79
0
static const int dnstext_start = 1;
80
0
static const int dnstext_first_final = 7;
81
0
static const int dnstext_error = 0;
82
83
0
static const int dnstext_en_main = 1;
84
85
86
0
#line 30 "dnslabeltext.rl"
87
88
0
  (void)dnstext_error;  // silence warnings
89
0
  (void)dnstext_en_main;
90
0
        const char *p = input.c_str(), *pe = input.c_str() + input.length();
91
0
        const char* eof = pe;
92
0
        int cs;
93
0
        char val = 0;
94
95
0
        string segment;
96
0
        vector<string> ret;
97
98
        
99
0
#line 100 "dnslabeltext.cc"
100
0
  {
101
0
  cs = dnstext_start;
102
0
  }
103
104
0
#line 105 "dnslabeltext.cc"
105
0
  {
106
0
  int _klen;
107
0
  unsigned int _trans;
108
0
  const char *_acts;
109
0
  unsigned int _nacts;
110
0
  const unsigned char *_keys;
111
112
0
  if ( p == pe )
113
0
    goto _test_eof;
114
0
  if ( cs == 0 )
115
0
    goto _out;
116
0
_resume:
117
0
  _keys = _dnstext_trans_keys + _dnstext_key_offsets[cs];
118
0
  _trans = _dnstext_index_offsets[cs];
119
120
0
  _klen = _dnstext_single_lengths[cs];
121
0
  if ( _klen > 0 ) {
122
0
    const unsigned char *_lower = _keys;
123
0
    const unsigned char *_mid;
124
0
    const unsigned char *_upper = _keys + _klen - 1;
125
0
    while (1) {
126
0
      if ( _upper < _lower )
127
0
        break;
128
129
0
      _mid = _lower + ((_upper-_lower) >> 1);
130
0
      if ( (*p) < *_mid )
131
0
        _upper = _mid - 1;
132
0
      else if ( (*p) > *_mid )
133
0
        _lower = _mid + 1;
134
0
      else {
135
0
        _trans += (unsigned int)(_mid - _keys);
136
0
        goto _match;
137
0
      }
138
0
    }
139
0
    _keys += _klen;
140
0
    _trans += _klen;
141
0
  }
142
143
0
  _klen = _dnstext_range_lengths[cs];
144
0
  if ( _klen > 0 ) {
145
0
    const unsigned char *_lower = _keys;
146
0
    const unsigned char *_mid;
147
0
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
148
0
    while (1) {
149
0
      if ( _upper < _lower )
150
0
        break;
151
152
0
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
153
0
      if ( (*p) < _mid[0] )
154
0
        _upper = _mid - 2;
155
0
      else if ( (*p) > _mid[1] )
156
0
        _lower = _mid + 2;
157
0
      else {
158
0
        _trans += (unsigned int)((_mid - _keys)>>1);
159
0
        goto _match;
160
0
      }
161
0
    }
162
0
    _trans += _klen;
163
0
  }
164
165
0
_match:
166
0
  cs = _dnstext_trans_targs[_trans];
167
168
0
  if ( _dnstext_trans_actions[_trans] == 0 )
169
0
    goto _again;
170
171
0
  _acts = _dnstext_actions + _dnstext_trans_actions[_trans];
172
0
  _nacts = (unsigned int) *_acts++;
173
0
  while ( _nacts-- > 0 )
174
0
  {
175
0
    switch ( *_acts++ )
176
0
    {
177
0
  case 0:
178
0
#line 42 "dnslabeltext.rl"
179
0
  { 
180
0
                        ret.push_back(segment);
181
0
                        segment.clear();
182
0
                }
183
0
  break;
184
0
  case 1:
185
0
#line 46 "dnslabeltext.rl"
186
0
  { 
187
0
                        segment.clear();
188
0
                }
189
0
  break;
190
0
  case 2:
191
0
#line 50 "dnslabeltext.rl"
192
0
  {
193
0
                  char c = *p;
194
0
                  appendSplit(ret, segment, c);
195
0
                }
196
0
  break;
197
0
  case 3:
198
0
#line 54 "dnslabeltext.rl"
199
0
  {
200
0
                  char c = *p;
201
0
                  val *= 10;
202
0
                  val += c-'0';
203
                  
204
0
                }
205
0
  break;
206
0
  case 4:
207
0
#line 60 "dnslabeltext.rl"
208
0
  {
209
0
                  appendSplit(ret, segment, val);
210
0
                  val=0;
211
0
                }
212
0
  break;
213
0
  case 5:
214
0
#line 65 "dnslabeltext.rl"
215
0
  {
216
0
                  appendSplit(ret, segment, *(p));
217
0
                }
218
0
  break;
219
0
#line 220 "dnslabeltext.cc"
220
0
    }
221
0
  }
222
223
0
_again:
224
0
  if ( cs == 0 )
225
0
    goto _out;
226
0
  if ( ++p != pe )
227
0
    goto _resume;
228
0
  _test_eof: {}
229
0
  if ( p == eof )
230
0
  {
231
0
  const char *__acts = _dnstext_actions + _dnstext_eof_actions[cs];
232
0
  unsigned int __nacts = (unsigned int) *__acts++;
233
0
  while ( __nacts-- > 0 ) {
234
0
    switch ( *__acts++ ) {
235
0
  case 0:
236
0
#line 42 "dnslabeltext.rl"
237
0
  { 
238
0
                        ret.push_back(segment);
239
0
                        segment.clear();
240
0
                }
241
0
  break;
242
0
#line 243 "dnslabeltext.cc"
243
0
    }
244
0
  }
245
0
  }
246
247
0
  _out: {}
248
0
  }
249
250
0
#line 78 "dnslabeltext.rl"
251
252
253
0
        if ( cs < dnstext_first_final ) {
254
0
                throw runtime_error("Unable to parse DNS TXT '"+input+"'");
255
0
        }
256
257
0
        return ret;
258
0
};
259
260
261
DNSName::string_t segmentDNSNameRaw(const char* realinput, size_t inputlen)
262
42.0k
{
263
264
42.0k
#line 265 "dnslabeltext.cc"
265
42.0k
static const char _dnsnameraw_actions[] = {
266
42.0k
  0, 1, 0, 1, 1, 1, 2, 1, 
267
42.0k
  3, 1, 4, 1, 5, 2, 1, 5, 
268
42.0k
  2, 4, 0, 2, 4, 5
269
42.0k
};
270
271
42.0k
static const char _dnsnameraw_key_offsets[] = {
272
42.0k
  0, 0, 2, 4, 6, 8, 10, 12
273
42.0k
};
274
275
42.0k
static const unsigned char _dnsnameraw_trans_keys[] = {
276
42.0k
  46u, 92u, 48u, 57u, 48u, 57u, 48u, 57u, 
277
42.0k
  46u, 92u, 46u, 92u, 46u, 92u, 0
278
42.0k
};
279
280
42.0k
static const char _dnsnameraw_single_lengths[] = {
281
42.0k
  0, 2, 0, 0, 0, 2, 2, 2
282
42.0k
};
283
284
42.0k
static const char _dnsnameraw_range_lengths[] = {
285
42.0k
  0, 0, 1, 1, 1, 0, 0, 0
286
42.0k
};
287
288
42.0k
static const char _dnsnameraw_index_offsets[] = {
289
42.0k
  0, 0, 3, 5, 7, 9, 12, 15
290
42.0k
};
291
292
42.0k
static const char _dnsnameraw_trans_targs[] = {
293
42.0k
  0, 2, 5, 3, 5, 4, 0, 7, 
294
42.0k
  0, 6, 2, 5, 0, 2, 5, 6, 
295
42.0k
  2, 5, 0
296
42.0k
};
297
298
42.0k
static const char _dnsnameraw_trans_actions[] = {
299
42.0k
  0, 3, 13, 7, 5, 7, 0, 7, 
300
42.0k
  0, 1, 0, 11, 0, 3, 13, 16, 
301
42.0k
  9, 19, 0
302
42.0k
};
303
304
42.0k
static const char _dnsnameraw_eof_actions[] = {
305
42.0k
  0, 0, 0, 0, 0, 1, 0, 16
306
42.0k
};
307
308
42.0k
static const int dnsnameraw_start = 1;
309
42.0k
static const int dnsnameraw_first_final = 5;
310
42.0k
static const int dnsnameraw_error = 0;
311
312
42.0k
static const int dnsnameraw_en_main = 1;
313
314
315
42.0k
#line 94 "dnslabeltext.rl"
316
317
42.0k
  (void)dnsnameraw_error;  // silence warnings
318
42.0k
  (void)dnsnameraw_en_main;
319
320
42.0k
        DNSName::string_t ret;
321
322
42.0k
        if(!*realinput || *realinput == '.') {
323
1.04k
          ret.append(1, (char)0);
324
1.04k
          return ret;
325
1.04k
        }
326
327
41.0k
        ret.reserve(inputlen+1);
328
329
41.0k
        const char *p = realinput, *pe = realinput + inputlen;
330
41.0k
        const char* eof = pe;
331
41.0k
        int cs;
332
41.0k
        char val = 0;
333
41.0k
        unsigned char labellen=0;
334
41.0k
        unsigned int lenpos=0;
335
        
336
41.0k
#line 337 "dnslabeltext.cc"
337
41.0k
  {
338
41.0k
  cs = dnsnameraw_start;
339
41.0k
  }
340
341
41.0k
#line 342 "dnslabeltext.cc"
342
41.0k
  {
343
41.0k
  int _klen;
344
41.0k
  unsigned int _trans;
345
41.0k
  const char *_acts;
346
41.0k
  unsigned int _nacts;
347
41.0k
  const unsigned char *_keys;
348
349
41.0k
  if ( p == pe )
350
0
    goto _test_eof;
351
41.0k
  if ( cs == 0 )
352
0
    goto _out;
353
297M
_resume:
354
297M
  _keys = _dnsnameraw_trans_keys + _dnsnameraw_key_offsets[cs];
355
297M
  _trans = _dnsnameraw_index_offsets[cs];
356
357
297M
  _klen = _dnsnameraw_single_lengths[cs];
358
297M
  if ( _klen > 0 ) {
359
297M
    const unsigned char *_lower = _keys;
360
297M
    const unsigned char *_mid;
361
297M
    const unsigned char *_upper = _keys + _klen - 1;
362
891M
    while (1) {
363
891M
      if ( _upper < _lower )
364
297M
        break;
365
366
594M
      _mid = _lower + ((_upper-_lower) >> 1);
367
594M
      if ( (*p) < *_mid )
368
297M
        _upper = _mid - 1;
369
297M
      else if ( (*p) > *_mid )
370
297M
        _lower = _mid + 1;
371
73.0k
      else {
372
73.0k
        _trans += (unsigned int)(_mid - _keys);
373
73.0k
        goto _match;
374
73.0k
      }
375
594M
    }
376
297M
    _keys += _klen;
377
297M
    _trans += _klen;
378
297M
  }
379
380
297M
  _klen = _dnsnameraw_range_lengths[cs];
381
297M
  if ( _klen > 0 ) {
382
102k
    const unsigned char *_lower = _keys;
383
102k
    const unsigned char *_mid;
384
102k
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
385
118k
    while (1) {
386
118k
      if ( _upper < _lower )
387
15.3k
        break;
388
389
102k
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
390
102k
      if ( (*p) < _mid[0] )
391
7.14k
        _upper = _mid - 2;
392
95.6k
      else if ( (*p) > _mid[1] )
393
8.24k
        _lower = _mid + 2;
394
87.4k
      else {
395
87.4k
        _trans += (unsigned int)((_mid - _keys)>>1);
396
87.4k
        goto _match;
397
87.4k
      }
398
102k
    }
399
15.3k
    _trans += _klen;
400
15.3k
  }
401
402
297M
_match:
403
297M
  cs = _dnsnameraw_trans_targs[_trans];
404
405
297M
  if ( _dnsnameraw_trans_actions[_trans] == 0 )
406
39.9k
    goto _again;
407
408
297M
  _acts = _dnsnameraw_actions + _dnsnameraw_trans_actions[_trans];
409
297M
  _nacts = (unsigned int) *_acts++;
410
594M
  while ( _nacts-- > 0 )
411
297M
  {
412
297M
    switch ( *_acts++ )
413
297M
    {
414
28.4k
  case 0:
415
28.4k
#line 114 "dnslabeltext.rl"
416
28.4k
  { 
417
28.4k
                        if (labellen > 63) {
418
52
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
419
52
                        }
420
28.4k
                        ret[lenpos]=labellen;
421
28.4k
                        labellen=0;
422
28.4k
                }
423
0
  break;
424
50.4k
  case 1:
425
50.4k
#line 121 "dnslabeltext.rl"
426
50.4k
  { 
427
50.4k
                        lenpos=ret.size();
428
50.4k
                        ret.append(1, (char)0);
429
50.4k
                        labellen=0;
430
50.4k
                }
431
50.4k
  break;
432
15.3k
  case 2:
433
15.3k
#line 127 "dnslabeltext.rl"
434
15.3k
  {
435
15.3k
                  char c = *p;
436
15.3k
                  ret.append(1, c);
437
15.3k
                  labellen++;
438
15.3k
                }
439
15.3k
  break;
440
87.4k
  case 3:
441
87.4k
#line 132 "dnslabeltext.rl"
442
87.4k
  {
443
87.4k
                  char c = *p;
444
87.4k
                  val *= 10;
445
87.4k
                  val += c-'0';
446
87.4k
                }
447
87.4k
  break;
448
27.9k
  case 4:
449
27.9k
#line 137 "dnslabeltext.rl"
450
27.9k
  {
451
27.9k
                  ret.append(1, val);
452
27.9k
                  labellen++;
453
27.9k
                  val=0;
454
27.9k
                }
455
27.9k
  break;
456
297M
  case 5:
457
297M
#line 143 "dnslabeltext.rl"
458
297M
  {
459
297M
                  ret.append(1, *(p));
460
297M
                  labellen++;
461
297M
                }
462
297M
  break;
463
297M
#line 464 "dnslabeltext.cc"
464
297M
    }
465
297M
  }
466
467
297M
_again:
468
297M
  if ( cs == 0 )
469
11
    goto _out;
470
297M
  if ( ++p != pe )
471
297M
    goto _resume;
472
40.9k
  _test_eof: {}
473
40.9k
  if ( p == eof )
474
40.9k
  {
475
40.9k
  const char *__acts = _dnsnameraw_actions + _dnsnameraw_eof_actions[cs];
476
40.9k
  unsigned int __nacts = (unsigned int) *__acts++;
477
63.9k
  while ( __nacts-- > 0 ) {
478
23.0k
    switch ( *__acts++ ) {
479
21.8k
  case 0:
480
21.8k
#line 114 "dnslabeltext.rl"
481
21.8k
  { 
482
21.8k
                        if (labellen > 63) {
483
81
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
484
81
                        }
485
21.7k
                        ret[lenpos]=labellen;
486
21.7k
                        labellen=0;
487
21.7k
                }
488
0
  break;
489
1.19k
  case 4:
490
1.19k
#line 137 "dnslabeltext.rl"
491
1.19k
  {
492
1.19k
                  ret.append(1, val);
493
1.19k
                  labellen++;
494
1.19k
                  val=0;
495
1.19k
                }
496
1.19k
  break;
497
23.0k
#line 498 "dnslabeltext.cc"
498
23.0k
    }
499
23.0k
  }
500
40.9k
  }
501
502
40.8k
  _out: {}
503
40.8k
  }
504
505
0
#line 164 "dnslabeltext.rl"
506
507
508
40.8k
        if ( cs < dnsnameraw_first_final ) {
509
91
                throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': cs="+std::to_string(cs));
510
91
        }
511
40.7k
        ret.append(1, (char)0);
512
40.7k
        return ret;
513
40.8k
};
514
515
// Reads an RFC 1035 character string from 'in', puts the resulting bytes in 'out'.
516
// Returns the amount of bytes read from 'in'
517
140
size_t parseRFC1035CharString(const std::string &in, std::string &val) {
518
519
140
  val.clear();
520
140
  val.reserve(in.size());
521
140
  const char *p = in.c_str();
522
140
  const char *pe = p + in.size();
523
140
  int cs = 0;
524
140
  uint8_t escaped_octet = 0;
525
  // Keeps track of how many chars we read from the source string
526
140
  size_t counter=0;
527
528
/* This parses an RFC 1035 char-string.
529
 * It was created from the ABNF in draft-ietf-dnsop-svcb-https-02 with
530
 * https://github.com/zinid/abnfc and modified to put all the characters in the
531
 * right place.
532
 */
533
534
140
#line 535 "dnslabeltext.cc"
535
140
static const char _dns_text_to_string_actions[] = {
536
140
  0, 1, 0, 1, 2, 1, 3, 2, 
537
140
  0, 1
538
140
};
539
540
140
static const char _dns_text_to_string_key_offsets[] = {
541
140
  0, 0, 8, 15, 17, 19, 22, 24, 
542
140
  33, 41, 43, 45, 48, 50, 58
543
140
};
544
545
140
static const char _dns_text_to_string_trans_keys[] = {
546
140
  34, 92, 33, 39, 42, 58, 60, 126, 
547
140
  50, 33, 47, 48, 49, 58, 126, 48, 
548
140
  57, 48, 57, 53, 48, 52, 48, 53, 
549
140
  9, 34, 92, 32, 39, 42, 58, 60, 
550
140
  126, 9, 50, 32, 47, 48, 49, 58, 
551
140
  126, 48, 57, 48, 57, 53, 48, 52, 
552
140
  48, 53, 33, 92, 35, 39, 42, 58, 
553
140
  60, 126, 0
554
140
};
555
556
140
static const char _dns_text_to_string_single_lengths[] = {
557
140
  0, 2, 1, 0, 0, 1, 0, 3, 
558
140
  2, 0, 0, 1, 0, 2, 0
559
140
};
560
561
140
static const char _dns_text_to_string_range_lengths[] = {
562
140
  0, 3, 3, 1, 1, 1, 1, 3, 
563
140
  3, 1, 1, 1, 1, 3, 0
564
140
};
565
566
140
static const char _dns_text_to_string_index_offsets[] = {
567
140
  0, 0, 6, 11, 13, 15, 18, 20, 
568
140
  27, 33, 35, 37, 40, 42, 48
569
140
};
570
571
140
static const char _dns_text_to_string_indicies[] = {
572
140
  2, 3, 0, 0, 0, 1, 5, 0, 
573
140
  4, 0, 1, 6, 1, 7, 1, 8, 
574
140
  6, 1, 7, 1, 9, 10, 11, 9, 
575
140
  9, 9, 1, 9, 13, 9, 12, 9, 
576
140
  1, 14, 1, 15, 1, 16, 14, 1, 
577
140
  15, 1, 0, 3, 0, 0, 0, 1, 
578
140
  1, 0
579
140
};
580
581
140
static const char _dns_text_to_string_trans_targs[] = {
582
140
  13, 0, 7, 2, 3, 5, 4, 13, 
583
140
  6, 7, 14, 8, 9, 11, 10, 7, 
584
140
  12
585
140
};
586
587
140
static const char _dns_text_to_string_trans_actions[] = {
588
140
  3, 0, 5, 5, 1, 1, 1, 7, 
589
140
  1, 3, 5, 5, 1, 1, 1, 7, 
590
140
  1
591
140
};
592
593
140
static const int dns_text_to_string_start = 1;
594
140
static const int dns_text_to_string_first_final = 13;
595
140
static const int dns_text_to_string_error = 0;
596
597
140
static const int dns_text_to_string_en_main = 1;
598
599
600
140
#line 601 "dnslabeltext.cc"
601
140
  {
602
140
  cs = dns_text_to_string_start;
603
140
  }
604
605
140
#line 232 "dnslabeltext.rl"
606
607
608
  // silence warnings
609
140
  (void) dns_text_to_string_first_final;
610
140
  (void) dns_text_to_string_error;
611
140
  (void) dns_text_to_string_en_main;
612
  
613
140
#line 614 "dnslabeltext.cc"
614
140
  {
615
140
  int _klen;
616
140
  unsigned int _trans;
617
140
  const char *_acts;
618
140
  unsigned int _nacts;
619
140
  const char *_keys;
620
621
140
  if ( p == pe )
622
0
    goto _test_eof;
623
140
  if ( cs == 0 )
624
0
    goto _out;
625
5.61k
_resume:
626
5.61k
  _keys = _dns_text_to_string_trans_keys + _dns_text_to_string_key_offsets[cs];
627
5.61k
  _trans = _dns_text_to_string_index_offsets[cs];
628
629
5.61k
  _klen = _dns_text_to_string_single_lengths[cs];
630
5.61k
  if ( _klen > 0 ) {
631
4.54k
    const char *_lower = _keys;
632
4.54k
    const char *_mid;
633
4.54k
    const char *_upper = _keys + _klen - 1;
634
11.1k
    while (1) {
635
11.1k
      if ( _upper < _lower )
636
3.12k
        break;
637
638
7.99k
      _mid = _lower + ((_upper-_lower) >> 1);
639
7.99k
      if ( (*p) < *_mid )
640
2.62k
        _upper = _mid - 1;
641
5.36k
      else if ( (*p) > *_mid )
642
3.94k
        _lower = _mid + 1;
643
1.41k
      else {
644
1.41k
        _trans += (unsigned int)(_mid - _keys);
645
1.41k
        goto _match;
646
1.41k
      }
647
7.99k
    }
648
3.12k
    _keys += _klen;
649
3.12k
    _trans += _klen;
650
3.12k
  }
651
652
4.19k
  _klen = _dns_text_to_string_range_lengths[cs];
653
4.19k
  if ( _klen > 0 ) {
654
4.19k
    const char *_lower = _keys;
655
4.19k
    const char *_mid;
656
4.19k
    const char *_upper = _keys + (_klen<<1) - 2;
657
5.79k
    while (1) {
658
5.79k
      if ( _upper < _lower )
659
75
        break;
660
661
5.71k
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
662
5.71k
      if ( (*p) < _mid[0] )
663
695
        _upper = _mid - 2;
664
5.02k
      else if ( (*p) > _mid[1] )
665
909
        _lower = _mid + 2;
666
4.11k
      else {
667
4.11k
        _trans += (unsigned int)((_mid - _keys)>>1);
668
4.11k
        goto _match;
669
4.11k
      }
670
5.71k
    }
671
75
    _trans += _klen;
672
75
  }
673
674
5.61k
_match:
675
5.61k
  _trans = _dns_text_to_string_indicies[_trans];
676
5.61k
  cs = _dns_text_to_string_trans_targs[_trans];
677
678
5.61k
  if ( _dns_text_to_string_trans_actions[_trans] == 0 )
679
76
    goto _again;
680
681
5.53k
  _acts = _dns_text_to_string_actions + _dns_text_to_string_trans_actions[_trans];
682
5.53k
  _nacts = (unsigned int) *_acts++;
683
11.6k
  while ( _nacts-- > 0 )
684
6.08k
  {
685
6.08k
    switch ( *_acts++ )
686
6.08k
    {
687
1.66k
  case 0:
688
1.66k
#line 194 "dnslabeltext.rl"
689
1.66k
  {
690
1.66k
    escaped_octet *= 10;
691
1.66k
    escaped_octet += (*p)-'0';
692
1.66k
    counter++;
693
1.66k
  }
694
1.66k
  break;
695
550
  case 1:
696
550
#line 200 "dnslabeltext.rl"
697
550
  {
698
550
    val += escaped_octet;
699
550
    escaped_octet = 0;
700
550
  }
701
550
  break;
702
2.85k
  case 2:
703
2.85k
#line 205 "dnslabeltext.rl"
704
2.85k
  {
705
2.85k
    val += (*p);
706
2.85k
    counter++;
707
2.85k
  }
708
2.85k
  break;
709
1.00k
  case 3:
710
1.00k
#line 210 "dnslabeltext.rl"
711
1.00k
  {
712
1.00k
    counter++;
713
1.00k
  }
714
1.00k
  break;
715
6.08k
#line 716 "dnslabeltext.cc"
716
6.08k
    }
717
6.08k
  }
718
719
5.61k
_again:
720
5.61k
  if ( cs == 0 )
721
76
    goto _out;
722
5.53k
  if ( ++p != pe )
723
5.47k
    goto _resume;
724
64
  _test_eof: {}
725
140
  _out: {}
726
140
  }
727
728
0
#line 239 "dnslabeltext.rl"
729
730
0
  return counter;
731
64
}
732
733
0
size_t parseSVCBValueListFromParsedRFC1035CharString(const std::string &in, std::vector<std::string> &val) {
734
0
  val.clear();
735
0
  const char *p = in.c_str();
736
0
  const char *pe = p + in.size();
737
0
  int cs = 0;
738
0
  const char* eof = pe;
739
  // Keeps track of how many chars we read from the source string
740
0
  size_t counter=0;
741
742
  // Here we store the parsed value until we hit a comma or are done
743
0
  std::string tmp;
744
745
746
0
#line 747 "dnslabeltext.cc"
747
0
static const char _dns_text_to_value_list_actions[] = {
748
0
  0, 1, 0, 1, 2, 1, 3, 2, 
749
0
  2, 3, 2, 3, 1
750
0
};
751
752
0
static const char _dns_text_to_value_list_key_offsets[] = {
753
0
  0, 0, 2, 4, 6
754
0
};
755
756
0
static const unsigned char _dns_text_to_value_list_trans_keys[] = {
757
0
  44u, 92u, 44u, 92u, 44u, 92u, 44u, 92u, 
758
0
  0
759
0
};
760
761
0
static const char _dns_text_to_value_list_single_lengths[] = {
762
0
  0, 2, 2, 2, 2
763
0
};
764
765
0
static const char _dns_text_to_value_list_range_lengths[] = {
766
0
  0, 0, 0, 0, 0
767
0
};
768
769
0
static const char _dns_text_to_value_list_index_offsets[] = {
770
0
  0, 0, 3, 6, 9
771
0
};
772
773
0
static const char _dns_text_to_value_list_indicies[] = {
774
0
  1, 2, 0, 3, 3, 1, 1, 2, 
775
0
  0, 4, 2, 0, 0
776
0
};
777
778
0
static const char _dns_text_to_value_list_trans_targs[] = {
779
0
  4, 0, 2, 4, 1
780
0
};
781
782
0
static const char _dns_text_to_value_list_trans_actions[] = {
783
0
  1, 0, 5, 10, 7
784
0
};
785
786
0
static const char _dns_text_to_value_list_eof_actions[] = {
787
0
  0, 0, 0, 0, 3
788
0
};
789
790
0
static const int dns_text_to_value_list_start = 3;
791
0
static const int dns_text_to_value_list_first_final = 3;
792
0
static const int dns_text_to_value_list_error = 0;
793
794
0
static const int dns_text_to_value_list_en_main = 3;
795
796
797
0
#line 798 "dnslabeltext.cc"
798
0
  {
799
0
  cs = dns_text_to_value_list_start;
800
0
  }
801
802
0
#line 288 "dnslabeltext.rl"
803
804
805
  // silence warnings
806
0
  (void) dns_text_to_value_list_first_final;
807
0
  (void) dns_text_to_value_list_error;
808
0
  (void) dns_text_to_value_list_en_main;
809
  
810
0
#line 811 "dnslabeltext.cc"
811
0
  {
812
0
  int _klen;
813
0
  unsigned int _trans;
814
0
  const char *_acts;
815
0
  unsigned int _nacts;
816
0
  const unsigned char *_keys;
817
818
0
  if ( p == pe )
819
0
    goto _test_eof;
820
0
  if ( cs == 0 )
821
0
    goto _out;
822
0
_resume:
823
0
  _keys = _dns_text_to_value_list_trans_keys + _dns_text_to_value_list_key_offsets[cs];
824
0
  _trans = _dns_text_to_value_list_index_offsets[cs];
825
826
0
  _klen = _dns_text_to_value_list_single_lengths[cs];
827
0
  if ( _klen > 0 ) {
828
0
    const unsigned char *_lower = _keys;
829
0
    const unsigned char *_mid;
830
0
    const unsigned char *_upper = _keys + _klen - 1;
831
0
    while (1) {
832
0
      if ( _upper < _lower )
833
0
        break;
834
835
0
      _mid = _lower + ((_upper-_lower) >> 1);
836
0
      if ( (*p) < *_mid )
837
0
        _upper = _mid - 1;
838
0
      else if ( (*p) > *_mid )
839
0
        _lower = _mid + 1;
840
0
      else {
841
0
        _trans += (unsigned int)(_mid - _keys);
842
0
        goto _match;
843
0
      }
844
0
    }
845
0
    _keys += _klen;
846
0
    _trans += _klen;
847
0
  }
848
849
0
  _klen = _dns_text_to_value_list_range_lengths[cs];
850
0
  if ( _klen > 0 ) {
851
0
    const unsigned char *_lower = _keys;
852
0
    const unsigned char *_mid;
853
0
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
854
0
    while (1) {
855
0
      if ( _upper < _lower )
856
0
        break;
857
858
0
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
859
0
      if ( (*p) < _mid[0] )
860
0
        _upper = _mid - 2;
861
0
      else if ( (*p) > _mid[1] )
862
0
        _lower = _mid + 2;
863
0
      else {
864
0
        _trans += (unsigned int)((_mid - _keys)>>1);
865
0
        goto _match;
866
0
      }
867
0
    }
868
0
    _trans += _klen;
869
0
  }
870
871
0
_match:
872
0
  _trans = _dns_text_to_value_list_indicies[_trans];
873
0
  cs = _dns_text_to_value_list_trans_targs[_trans];
874
875
0
  if ( _dns_text_to_value_list_trans_actions[_trans] == 0 )
876
0
    goto _again;
877
878
0
  _acts = _dns_text_to_value_list_actions + _dns_text_to_value_list_trans_actions[_trans];
879
0
  _nacts = (unsigned int) *_acts++;
880
0
  while ( _nacts-- > 0 )
881
0
  {
882
0
    switch ( *_acts++ )
883
0
    {
884
0
  case 0:
885
0
#line 259 "dnslabeltext.rl"
886
0
  {
887
0
    tmp += (*p);
888
0
    counter++;
889
0
  }
890
0
  break;
891
0
  case 1:
892
0
#line 264 "dnslabeltext.rl"
893
0
  {
894
0
    tmp += (*p);
895
0
  }
896
0
  break;
897
0
  case 2:
898
0
#line 268 "dnslabeltext.rl"
899
0
  {
900
0
    val.push_back(tmp);
901
0
    tmp.clear();
902
0
    counter++;
903
0
  }
904
0
  break;
905
0
  case 3:
906
0
#line 274 "dnslabeltext.rl"
907
0
  {
908
0
    counter++;
909
0
  }
910
0
  break;
911
0
#line 912 "dnslabeltext.cc"
912
0
    }
913
0
  }
914
915
0
_again:
916
0
  if ( cs == 0 )
917
0
    goto _out;
918
0
  if ( ++p != pe )
919
0
    goto _resume;
920
0
  _test_eof: {}
921
0
  if ( p == eof )
922
0
  {
923
0
  const char *__acts = _dns_text_to_value_list_actions + _dns_text_to_value_list_eof_actions[cs];
924
0
  unsigned int __nacts = (unsigned int) *__acts++;
925
0
  while ( __nacts-- > 0 ) {
926
0
    switch ( *__acts++ ) {
927
0
  case 2:
928
0
#line 268 "dnslabeltext.rl"
929
0
  {
930
0
    val.push_back(tmp);
931
0
    tmp.clear();
932
0
    counter++;
933
0
  }
934
0
  break;
935
0
#line 936 "dnslabeltext.cc"
936
0
    }
937
0
  }
938
0
  }
939
940
0
  _out: {}
941
0
  }
942
943
0
#line 295 "dnslabeltext.rl"
944
945
0
  if ( cs < dns_text_to_value_list_first_final ) {
946
0
          throw runtime_error("Unable to parse DNS SVCB value list '"+in+"'");
947
0
  }
948
949
0
  return counter;
950
0
}
951
952
953
#if 0
954
int main()
955
{
956
  //char blah[]="\"blah\" \"bleh\" \"bloeh\\\"bleh\" \"\\97enzo\"";
957
  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\"";
958
  //char blah[]="\"abc \\097\\098 def\"";
959
  printf("Input: '%s'\n", blah);
960
  vector<string> res=dnstext(blah);
961
  cerr<<res.size()<<" segments"<<endl;
962
  cerr<<res[0]<<endl;
963
}
964
#endif