Coverage Report

Created: 2023-03-26 07:17

/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
0
{
263
264
0
#line 265 "dnslabeltext.cc"
265
0
static const char _dnsnameraw_actions[] = {
266
0
  0, 1, 0, 1, 1, 1, 2, 1, 
267
0
  3, 1, 4, 1, 5, 2, 1, 5, 
268
0
  2, 4, 0, 2, 4, 5
269
0
};
270
271
0
static const char _dnsnameraw_key_offsets[] = {
272
0
  0, 0, 2, 4, 6, 8, 10, 12
273
0
};
274
275
0
static const unsigned char _dnsnameraw_trans_keys[] = {
276
0
  46u, 92u, 48u, 57u, 48u, 57u, 48u, 57u, 
277
0
  46u, 92u, 46u, 92u, 46u, 92u, 0
278
0
};
279
280
0
static const char _dnsnameraw_single_lengths[] = {
281
0
  0, 2, 0, 0, 0, 2, 2, 2
282
0
};
283
284
0
static const char _dnsnameraw_range_lengths[] = {
285
0
  0, 0, 1, 1, 1, 0, 0, 0
286
0
};
287
288
0
static const char _dnsnameraw_index_offsets[] = {
289
0
  0, 0, 3, 5, 7, 9, 12, 15
290
0
};
291
292
0
static const char _dnsnameraw_trans_targs[] = {
293
0
  0, 2, 5, 3, 5, 4, 0, 7, 
294
0
  0, 6, 2, 5, 0, 2, 5, 6, 
295
0
  2, 5, 0
296
0
};
297
298
0
static const char _dnsnameraw_trans_actions[] = {
299
0
  0, 3, 13, 7, 5, 7, 0, 7, 
300
0
  0, 1, 0, 11, 0, 3, 13, 16, 
301
0
  9, 19, 0
302
0
};
303
304
0
static const char _dnsnameraw_eof_actions[] = {
305
0
  0, 0, 0, 0, 0, 1, 0, 16
306
0
};
307
308
0
static const int dnsnameraw_start = 1;
309
0
static const int dnsnameraw_first_final = 5;
310
0
static const int dnsnameraw_error = 0;
311
312
0
static const int dnsnameraw_en_main = 1;
313
314
315
0
#line 94 "dnslabeltext.rl"
316
317
0
  (void)dnsnameraw_error;  // silence warnings
318
0
  (void)dnsnameraw_en_main;
319
320
0
        DNSName::string_t ret;
321
322
0
        if(!*realinput || *realinput == '.') {
323
0
          ret.append(1, (char)0);
324
0
          return ret;
325
0
        }
326
327
0
        ret.reserve(inputlen+1);
328
329
0
        const char *p = realinput, *pe = realinput + inputlen;
330
0
        const char* eof = pe;
331
0
        int cs;
332
0
        char val = 0;
333
0
        unsigned char labellen=0;
334
0
        unsigned int lenpos=0;
335
        
336
0
#line 337 "dnslabeltext.cc"
337
0
  {
338
0
  cs = dnsnameraw_start;
339
0
  }
340
341
0
#line 342 "dnslabeltext.cc"
342
0
  {
343
0
  int _klen;
344
0
  unsigned int _trans;
345
0
  const char *_acts;
346
0
  unsigned int _nacts;
347
0
  const unsigned char *_keys;
348
349
0
  if ( p == pe )
350
0
    goto _test_eof;
351
0
  if ( cs == 0 )
352
0
    goto _out;
353
0
_resume:
354
0
  _keys = _dnsnameraw_trans_keys + _dnsnameraw_key_offsets[cs];
355
0
  _trans = _dnsnameraw_index_offsets[cs];
356
357
0
  _klen = _dnsnameraw_single_lengths[cs];
358
0
  if ( _klen > 0 ) {
359
0
    const unsigned char *_lower = _keys;
360
0
    const unsigned char *_mid;
361
0
    const unsigned char *_upper = _keys + _klen - 1;
362
0
    while (1) {
363
0
      if ( _upper < _lower )
364
0
        break;
365
366
0
      _mid = _lower + ((_upper-_lower) >> 1);
367
0
      if ( (*p) < *_mid )
368
0
        _upper = _mid - 1;
369
0
      else if ( (*p) > *_mid )
370
0
        _lower = _mid + 1;
371
0
      else {
372
0
        _trans += (unsigned int)(_mid - _keys);
373
0
        goto _match;
374
0
      }
375
0
    }
376
0
    _keys += _klen;
377
0
    _trans += _klen;
378
0
  }
379
380
0
  _klen = _dnsnameraw_range_lengths[cs];
381
0
  if ( _klen > 0 ) {
382
0
    const unsigned char *_lower = _keys;
383
0
    const unsigned char *_mid;
384
0
    const unsigned char *_upper = _keys + (_klen<<1) - 2;
385
0
    while (1) {
386
0
      if ( _upper < _lower )
387
0
        break;
388
389
0
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
390
0
      if ( (*p) < _mid[0] )
391
0
        _upper = _mid - 2;
392
0
      else if ( (*p) > _mid[1] )
393
0
        _lower = _mid + 2;
394
0
      else {
395
0
        _trans += (unsigned int)((_mid - _keys)>>1);
396
0
        goto _match;
397
0
      }
398
0
    }
399
0
    _trans += _klen;
400
0
  }
401
402
0
_match:
403
0
  cs = _dnsnameraw_trans_targs[_trans];
404
405
0
  if ( _dnsnameraw_trans_actions[_trans] == 0 )
406
0
    goto _again;
407
408
0
  _acts = _dnsnameraw_actions + _dnsnameraw_trans_actions[_trans];
409
0
  _nacts = (unsigned int) *_acts++;
410
0
  while ( _nacts-- > 0 )
411
0
  {
412
0
    switch ( *_acts++ )
413
0
    {
414
0
  case 0:
415
0
#line 114 "dnslabeltext.rl"
416
0
  { 
417
0
                        if (labellen > 63) {
418
0
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
419
0
                        }
420
0
                        ret[lenpos]=labellen;
421
0
                        labellen=0;
422
0
                }
423
0
  break;
424
0
  case 1:
425
0
#line 121 "dnslabeltext.rl"
426
0
  { 
427
0
                        lenpos=ret.size();
428
0
                        ret.append(1, (char)0);
429
0
                        labellen=0;
430
0
                }
431
0
  break;
432
0
  case 2:
433
0
#line 127 "dnslabeltext.rl"
434
0
  {
435
0
                  char c = *p;
436
0
                  ret.append(1, c);
437
0
                  labellen++;
438
0
                }
439
0
  break;
440
0
  case 3:
441
0
#line 132 "dnslabeltext.rl"
442
0
  {
443
0
                  char c = *p;
444
0
                  val *= 10;
445
0
                  val += c-'0';
446
0
                }
447
0
  break;
448
0
  case 4:
449
0
#line 137 "dnslabeltext.rl"
450
0
  {
451
0
                  ret.append(1, val);
452
0
                  labellen++;
453
0
                  val=0;
454
0
                }
455
0
  break;
456
0
  case 5:
457
0
#line 143 "dnslabeltext.rl"
458
0
  {
459
0
                  ret.append(1, *(p));
460
0
                  labellen++;
461
0
                }
462
0
  break;
463
0
#line 464 "dnslabeltext.cc"
464
0
    }
465
0
  }
466
467
0
_again:
468
0
  if ( cs == 0 )
469
0
    goto _out;
470
0
  if ( ++p != pe )
471
0
    goto _resume;
472
0
  _test_eof: {}
473
0
  if ( p == eof )
474
0
  {
475
0
  const char *__acts = _dnsnameraw_actions + _dnsnameraw_eof_actions[cs];
476
0
  unsigned int __nacts = (unsigned int) *__acts++;
477
0
  while ( __nacts-- > 0 ) {
478
0
    switch ( *__acts++ ) {
479
0
  case 0:
480
0
#line 114 "dnslabeltext.rl"
481
0
  { 
482
0
                        if (labellen > 63) {
483
0
                          throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': invalid label length "+std::to_string(labellen));
484
0
                        }
485
0
                        ret[lenpos]=labellen;
486
0
                        labellen=0;
487
0
                }
488
0
  break;
489
0
  case 4:
490
0
#line 137 "dnslabeltext.rl"
491
0
  {
492
0
                  ret.append(1, val);
493
0
                  labellen++;
494
0
                  val=0;
495
0
                }
496
0
  break;
497
0
#line 498 "dnslabeltext.cc"
498
0
    }
499
0
  }
500
0
  }
501
502
0
  _out: {}
503
0
  }
504
505
0
#line 164 "dnslabeltext.rl"
506
507
508
0
        if ( cs < dnsnameraw_first_final ) {
509
0
                throw runtime_error("Unable to parse DNS name '"+string(realinput)+"': cs="+std::to_string(cs));
510
0
        }
511
0
        ret.append(1, (char)0);
512
0
        return ret;
513
0
};
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
0
size_t parseRFC1035CharString(const std::string &in, std::string &val) {
518
519
0
  val.clear();
520
0
  val.reserve(in.size());
521
0
  const char *p = in.c_str();
522
0
  const char *pe = p + in.size();
523
0
  int cs = 0;
524
0
  uint8_t escaped_octet = 0;
525
  // Keeps track of how many chars we read from the source string
526
0
  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
0
#line 535 "dnslabeltext.cc"
535
0
static const char _dns_text_to_string_actions[] = {
536
0
  0, 1, 0, 1, 2, 1, 3, 2, 
537
0
  0, 1
538
0
};
539
540
0
static const char _dns_text_to_string_key_offsets[] = {
541
0
  0, 0, 8, 15, 17, 19, 22, 24, 
542
0
  33, 41, 43, 45, 48, 50, 58
543
0
};
544
545
0
static const char _dns_text_to_string_trans_keys[] = {
546
0
  34, 92, 33, 39, 42, 58, 60, 126, 
547
0
  50, 33, 47, 48, 49, 58, 126, 48, 
548
0
  57, 48, 57, 53, 48, 52, 48, 53, 
549
0
  9, 34, 92, 32, 39, 42, 58, 60, 
550
0
  126, 9, 50, 32, 47, 48, 49, 58, 
551
0
  126, 48, 57, 48, 57, 53, 48, 52, 
552
0
  48, 53, 33, 92, 35, 39, 42, 58, 
553
0
  60, 126, 0
554
0
};
555
556
0
static const char _dns_text_to_string_single_lengths[] = {
557
0
  0, 2, 1, 0, 0, 1, 0, 3, 
558
0
  2, 0, 0, 1, 0, 2, 0
559
0
};
560
561
0
static const char _dns_text_to_string_range_lengths[] = {
562
0
  0, 3, 3, 1, 1, 1, 1, 3, 
563
0
  3, 1, 1, 1, 1, 3, 0
564
0
};
565
566
0
static const char _dns_text_to_string_index_offsets[] = {
567
0
  0, 0, 6, 11, 13, 15, 18, 20, 
568
0
  27, 33, 35, 37, 40, 42, 48
569
0
};
570
571
0
static const char _dns_text_to_string_indicies[] = {
572
0
  2, 3, 0, 0, 0, 1, 5, 0, 
573
0
  4, 0, 1, 6, 1, 7, 1, 8, 
574
0
  6, 1, 7, 1, 9, 10, 11, 9, 
575
0
  9, 9, 1, 9, 13, 9, 12, 9, 
576
0
  1, 14, 1, 15, 1, 16, 14, 1, 
577
0
  15, 1, 0, 3, 0, 0, 0, 1, 
578
0
  1, 0
579
0
};
580
581
0
static const char _dns_text_to_string_trans_targs[] = {
582
0
  13, 0, 7, 2, 3, 5, 4, 13, 
583
0
  6, 7, 14, 8, 9, 11, 10, 7, 
584
0
  12
585
0
};
586
587
0
static const char _dns_text_to_string_trans_actions[] = {
588
0
  3, 0, 5, 5, 1, 1, 1, 7, 
589
0
  1, 3, 5, 5, 1, 1, 1, 7, 
590
0
  1
591
0
};
592
593
0
static const int dns_text_to_string_start = 1;
594
0
static const int dns_text_to_string_first_final = 13;
595
0
static const int dns_text_to_string_error = 0;
596
597
0
static const int dns_text_to_string_en_main = 1;
598
599
600
0
#line 601 "dnslabeltext.cc"
601
0
  {
602
0
  cs = dns_text_to_string_start;
603
0
  }
604
605
0
#line 232 "dnslabeltext.rl"
606
607
608
  // silence warnings
609
0
  (void) dns_text_to_string_first_final;
610
0
  (void) dns_text_to_string_error;
611
0
  (void) dns_text_to_string_en_main;
612
  
613
0
#line 614 "dnslabeltext.cc"
614
0
  {
615
0
  int _klen;
616
0
  unsigned int _trans;
617
0
  const char *_acts;
618
0
  unsigned int _nacts;
619
0
  const char *_keys;
620
621
0
  if ( p == pe )
622
0
    goto _test_eof;
623
0
  if ( cs == 0 )
624
0
    goto _out;
625
0
_resume:
626
0
  _keys = _dns_text_to_string_trans_keys + _dns_text_to_string_key_offsets[cs];
627
0
  _trans = _dns_text_to_string_index_offsets[cs];
628
629
0
  _klen = _dns_text_to_string_single_lengths[cs];
630
0
  if ( _klen > 0 ) {
631
0
    const char *_lower = _keys;
632
0
    const char *_mid;
633
0
    const char *_upper = _keys + _klen - 1;
634
0
    while (1) {
635
0
      if ( _upper < _lower )
636
0
        break;
637
638
0
      _mid = _lower + ((_upper-_lower) >> 1);
639
0
      if ( (*p) < *_mid )
640
0
        _upper = _mid - 1;
641
0
      else if ( (*p) > *_mid )
642
0
        _lower = _mid + 1;
643
0
      else {
644
0
        _trans += (unsigned int)(_mid - _keys);
645
0
        goto _match;
646
0
      }
647
0
    }
648
0
    _keys += _klen;
649
0
    _trans += _klen;
650
0
  }
651
652
0
  _klen = _dns_text_to_string_range_lengths[cs];
653
0
  if ( _klen > 0 ) {
654
0
    const char *_lower = _keys;
655
0
    const char *_mid;
656
0
    const char *_upper = _keys + (_klen<<1) - 2;
657
0
    while (1) {
658
0
      if ( _upper < _lower )
659
0
        break;
660
661
0
      _mid = _lower + (((_upper-_lower) >> 1) & ~1);
662
0
      if ( (*p) < _mid[0] )
663
0
        _upper = _mid - 2;
664
0
      else if ( (*p) > _mid[1] )
665
0
        _lower = _mid + 2;
666
0
      else {
667
0
        _trans += (unsigned int)((_mid - _keys)>>1);
668
0
        goto _match;
669
0
      }
670
0
    }
671
0
    _trans += _klen;
672
0
  }
673
674
0
_match:
675
0
  _trans = _dns_text_to_string_indicies[_trans];
676
0
  cs = _dns_text_to_string_trans_targs[_trans];
677
678
0
  if ( _dns_text_to_string_trans_actions[_trans] == 0 )
679
0
    goto _again;
680
681
0
  _acts = _dns_text_to_string_actions + _dns_text_to_string_trans_actions[_trans];
682
0
  _nacts = (unsigned int) *_acts++;
683
0
  while ( _nacts-- > 0 )
684
0
  {
685
0
    switch ( *_acts++ )
686
0
    {
687
0
  case 0:
688
0
#line 194 "dnslabeltext.rl"
689
0
  {
690
0
    escaped_octet *= 10;
691
0
    escaped_octet += (*p)-'0';
692
0
    counter++;
693
0
  }
694
0
  break;
695
0
  case 1:
696
0
#line 200 "dnslabeltext.rl"
697
0
  {
698
0
    val += escaped_octet;
699
0
    escaped_octet = 0;
700
0
  }
701
0
  break;
702
0
  case 2:
703
0
#line 205 "dnslabeltext.rl"
704
0
  {
705
0
    val += (*p);
706
0
    counter++;
707
0
  }
708
0
  break;
709
0
  case 3:
710
0
#line 210 "dnslabeltext.rl"
711
0
  {
712
0
    counter++;
713
0
  }
714
0
  break;
715
0
#line 716 "dnslabeltext.cc"
716
0
    }
717
0
  }
718
719
0
_again:
720
0
  if ( cs == 0 )
721
0
    goto _out;
722
0
  if ( ++p != pe )
723
0
    goto _resume;
724
0
  _test_eof: {}
725
0
  _out: {}
726
0
  }
727
728
0
#line 239 "dnslabeltext.rl"
729
730
0
  return counter;
731
0
}
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