Coverage Report

Created: 2026-03-07 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/rdata/generic/caa_257.c
Line
Count
Source
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
#ifndef GENERIC_CAA_257_C
15
#define GENERIC_CAA_257_C 1
16
17
15.0k
#define RRTYPE_CAA_ATTRIBUTES (0)
18
19
static unsigned char const alphanumeric[256] = {
20
  /* 0x00-0x0f */ 0,
21
  0,
22
  0,
23
  0,
24
  0,
25
  0,
26
  0,
27
  0,
28
  0,
29
  0,
30
  0,
31
  0,
32
  0,
33
  0,
34
  0,
35
  0,
36
  /* 0x10-0x1f */ 0,
37
  0,
38
  0,
39
  0,
40
  0,
41
  0,
42
  0,
43
  0,
44
  0,
45
  0,
46
  0,
47
  0,
48
  0,
49
  0,
50
  0,
51
  0,
52
  /* 0x20-0x2f */ 0,
53
  0,
54
  0,
55
  0,
56
  0,
57
  0,
58
  0,
59
  0,
60
  0,
61
  0,
62
  0,
63
  0,
64
  0,
65
  0,
66
  0,
67
  0,
68
  /* 0x30-0x3f */ 1,
69
  1,
70
  1,
71
  1,
72
  1,
73
  1,
74
  1,
75
  1,
76
  1,
77
  1,
78
  0,
79
  0,
80
  0,
81
  0,
82
  0,
83
  0,
84
  /* 0x40-0x4f */ 0,
85
  1,
86
  1,
87
  1,
88
  1,
89
  1,
90
  1,
91
  1,
92
  1,
93
  1,
94
  1,
95
  1,
96
  1,
97
  1,
98
  1,
99
  1,
100
  /* 0x50-0x5f */ 1,
101
  1,
102
  1,
103
  1,
104
  1,
105
  1,
106
  1,
107
  1,
108
  1,
109
  1,
110
  1,
111
  0,
112
  0,
113
  0,
114
  0,
115
  0,
116
  /* 0x60-0x6f */ 0,
117
  1,
118
  1,
119
  1,
120
  1,
121
  1,
122
  1,
123
  1,
124
  1,
125
  1,
126
  1,
127
  1,
128
  1,
129
  1,
130
  1,
131
  1,
132
  /* 0x70-0x7f */ 1,
133
  1,
134
  1,
135
  1,
136
  1,
137
  1,
138
  1,
139
  1,
140
  1,
141
  1,
142
  1,
143
  0,
144
  0,
145
  0,
146
  0,
147
  0,
148
  /* 0x80-0x8f */ 0,
149
  0,
150
  0,
151
  0,
152
  0,
153
  0,
154
  0,
155
  0,
156
  0,
157
  0,
158
  0,
159
  0,
160
  0,
161
  0,
162
  0,
163
  0,
164
  /* 0x90-0x9f */ 0,
165
  0,
166
  0,
167
  0,
168
  0,
169
  0,
170
  0,
171
  0,
172
  0,
173
  0,
174
  0,
175
  0,
176
  0,
177
  0,
178
  0,
179
  0,
180
  /* 0xa0-0xaf */ 0,
181
  0,
182
  0,
183
  0,
184
  0,
185
  0,
186
  0,
187
  0,
188
  0,
189
  0,
190
  0,
191
  0,
192
  0,
193
  0,
194
  0,
195
  0,
196
  /* 0xb0-0xbf */ 0,
197
  0,
198
  0,
199
  0,
200
  0,
201
  0,
202
  0,
203
  0,
204
  0,
205
  0,
206
  0,
207
  0,
208
  0,
209
  0,
210
  0,
211
  0,
212
  /* 0xc0-0xcf */ 0,
213
  0,
214
  0,
215
  0,
216
  0,
217
  0,
218
  0,
219
  0,
220
  0,
221
  0,
222
  0,
223
  0,
224
  0,
225
  0,
226
  0,
227
  0,
228
  /* 0xd0-0xdf */ 0,
229
  0,
230
  0,
231
  0,
232
  0,
233
  0,
234
  0,
235
  0,
236
  0,
237
  0,
238
  0,
239
  0,
240
  0,
241
  0,
242
  0,
243
  0,
244
  /* 0xe0-0xef */ 0,
245
  0,
246
  0,
247
  0,
248
  0,
249
  0,
250
  0,
251
  0,
252
  0,
253
  0,
254
  0,
255
  0,
256
  0,
257
  0,
258
  0,
259
  0,
260
  /* 0xf0-0xff */ 0,
261
  0,
262
  0,
263
  0,
264
  0,
265
  0,
266
  0,
267
  0,
268
  0,
269
  0,
270
  0,
271
  0,
272
  0,
273
  0,
274
  0,
275
  0,
276
};
277
278
static isc_result_t
279
39.0k
fromtext_caa(ARGS_FROMTEXT) {
280
39.0k
  isc_token_t token;
281
39.0k
  isc_textregion_t tr;
282
39.0k
  uint8_t flags;
283
39.0k
  unsigned int i;
284
285
39.0k
  REQUIRE(type == dns_rdatatype_caa);
286
287
39.0k
  UNUSED(type);
288
39.0k
  UNUSED(rdclass);
289
39.0k
  UNUSED(origin);
290
39.0k
  UNUSED(options);
291
39.0k
  UNUSED(callbacks);
292
293
  /* Flags. */
294
39.0k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
295
39.0k
              false));
296
39.0k
  if (token.value.as_ulong > 255U) {
297
40
    RETTOK(ISC_R_RANGE);
298
40
  }
299
39.0k
  flags = (uint8_t)(token.value.as_ulong & 255U);
300
39.0k
  RETERR(uint8_tobuffer(flags, target));
301
302
  /*
303
   * Tag
304
   */
305
39.0k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
306
39.0k
              false));
307
39.0k
  tr = token.value.as_textregion;
308
94.6k
  for (i = 0; i < tr.length; i++) {
309
55.6k
    if (!alphanumeric[(unsigned char)tr.base[i]]) {
310
10
      RETTOK(DNS_R_SYNTAX);
311
10
    }
312
55.6k
  }
313
39.0k
  RETERR(uint8_tobuffer(tr.length, target));
314
39.0k
  RETERR(mem_tobuffer(target, tr.base, tr.length));
315
316
  /*
317
   * Value
318
   */
319
39.0k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
320
39.0k
              false));
321
39.0k
  if (token.type != isc_tokentype_qstring &&
322
38.6k
      token.type != isc_tokentype_string)
323
0
  {
324
0
    RETERR(DNS_R_SYNTAX);
325
0
  }
326
39.0k
  RETERR(multitxt_fromtext(&token.value.as_textregion, target));
327
38.9k
  return ISC_R_SUCCESS;
328
39.0k
}
329
330
static isc_result_t
331
904
totext_caa(ARGS_TOTEXT) {
332
904
  isc_region_t region;
333
904
  uint8_t flags;
334
904
  char buf[256];
335
336
904
  UNUSED(tctx);
337
338
904
  REQUIRE(rdata->type == dns_rdatatype_caa);
339
904
  REQUIRE(rdata->length >= 3U);
340
904
  REQUIRE(rdata->data != NULL);
341
342
904
  dns_rdata_toregion(rdata, &region);
343
344
  /*
345
   * Flags
346
   */
347
904
  flags = uint8_consume_fromregion(&region);
348
904
  snprintf(buf, sizeof(buf), "%u ", flags);
349
904
  RETERR(str_totext(buf, target));
350
351
  /*
352
   * Tag
353
   */
354
904
  RETERR(txt_totext(&region, false, target));
355
904
  RETERR(str_totext(" ", target));
356
357
  /*
358
   * Value
359
   */
360
904
  RETERR(multitxt_totext(&region, target));
361
904
  return ISC_R_SUCCESS;
362
904
}
363
364
static isc_result_t
365
1.73k
fromwire_caa(ARGS_FROMWIRE) {
366
1.73k
  isc_region_t sr;
367
1.73k
  unsigned int len, i;
368
369
1.73k
  REQUIRE(type == dns_rdatatype_caa);
370
371
1.73k
  UNUSED(type);
372
1.73k
  UNUSED(rdclass);
373
1.73k
  UNUSED(dctx);
374
375
  /*
376
   * Flags
377
   */
378
1.73k
  isc_buffer_activeregion(source, &sr);
379
1.73k
  if (sr.length < 2) {
380
11
    return ISC_R_UNEXPECTEDEND;
381
11
  }
382
383
  /*
384
   * Flags, tag length
385
   */
386
1.72k
  RETERR(mem_tobuffer(target, sr.base, 2));
387
1.65k
  len = sr.base[1];
388
1.65k
  isc_region_consume(&sr, 2);
389
1.65k
  isc_buffer_forward(source, 2);
390
391
  /*
392
   * Zero length tag fields are illegal.
393
   */
394
1.65k
  if (sr.length < len || len == 0) {
395
43
    RETERR(DNS_R_FORMERR);
396
0
  }
397
398
  /* Check the Tag's value */
399
5.12k
  for (i = 0; i < len; i++) {
400
3.53k
    if (!alphanumeric[sr.base[i]]) {
401
18
      RETERR(DNS_R_FORMERR);
402
      /*
403
       * Tag + Value
404
       */
405
0
    }
406
3.53k
  }
407
  /*
408
   * Tag + Value
409
   */
410
1.59k
  isc_buffer_forward(source, sr.length);
411
1.59k
  return mem_tobuffer(target, sr.base, sr.length);
412
1.60k
}
413
414
static isc_result_t
415
462
towire_caa(ARGS_TOWIRE) {
416
462
  isc_region_t region;
417
418
462
  REQUIRE(rdata->type == dns_rdatatype_caa);
419
462
  REQUIRE(rdata->length >= 3U);
420
462
  REQUIRE(rdata->data != NULL);
421
422
462
  UNUSED(cctx);
423
424
462
  dns_rdata_toregion(rdata, &region);
425
462
  return mem_tobuffer(target, region.base, region.length);
426
462
}
427
428
static int
429
1.36M
compare_caa(ARGS_COMPARE) {
430
1.36M
  isc_region_t r1, r2;
431
432
1.36M
  REQUIRE(rdata1->type == rdata2->type);
433
1.36M
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
434
1.36M
  REQUIRE(rdata1->type == dns_rdatatype_caa);
435
1.36M
  REQUIRE(rdata1->length >= 3U);
436
1.36M
  REQUIRE(rdata2->length >= 3U);
437
1.36M
  REQUIRE(rdata1->data != NULL);
438
1.36M
  REQUIRE(rdata2->data != NULL);
439
440
1.36M
  dns_rdata_toregion(rdata1, &r1);
441
1.36M
  dns_rdata_toregion(rdata2, &r2);
442
1.36M
  return isc_region_compare(&r1, &r2);
443
1.36M
}
444
445
static isc_result_t
446
0
fromstruct_caa(ARGS_FROMSTRUCT) {
447
0
  dns_rdata_caa_t *caa = source;
448
0
  isc_region_t region;
449
0
  unsigned int i;
450
451
0
  REQUIRE(type == dns_rdatatype_caa);
452
0
  REQUIRE(caa != NULL);
453
0
  REQUIRE(caa->common.rdtype == type);
454
0
  REQUIRE(caa->common.rdclass == rdclass);
455
0
  REQUIRE(caa->tag != NULL && caa->tag_len != 0);
456
0
  REQUIRE(caa->value != NULL);
457
458
0
  UNUSED(type);
459
0
  UNUSED(rdclass);
460
461
  /*
462
   * Flags
463
   */
464
0
  RETERR(uint8_tobuffer(caa->flags, target));
465
466
  /*
467
   * Tag length
468
   */
469
0
  RETERR(uint8_tobuffer(caa->tag_len, target));
470
471
  /*
472
   * Tag
473
   */
474
0
  region.base = caa->tag;
475
0
  region.length = caa->tag_len;
476
0
  for (i = 0; i < region.length; i++) {
477
0
    if (!alphanumeric[region.base[i]]) {
478
0
      RETERR(DNS_R_SYNTAX);
479
0
    }
480
0
  }
481
0
  RETERR(isc_buffer_copyregion(target, &region));
482
483
  /*
484
   * Value
485
   */
486
0
  region.base = caa->value;
487
0
  region.length = caa->value_len;
488
0
  return isc_buffer_copyregion(target, &region);
489
0
}
490
491
static isc_result_t
492
0
tostruct_caa(ARGS_TOSTRUCT) {
493
0
  dns_rdata_caa_t *caa = target;
494
0
  isc_region_t sr;
495
496
0
  REQUIRE(rdata->type == dns_rdatatype_caa);
497
0
  REQUIRE(caa != NULL);
498
0
  REQUIRE(rdata->length >= 3U);
499
0
  REQUIRE(rdata->data != NULL);
500
501
0
  DNS_RDATACOMMON_INIT(caa, rdata->type, rdata->rdclass);
502
503
0
  dns_rdata_toregion(rdata, &sr);
504
505
  /*
506
   * Flags
507
   */
508
0
  caa->flags = uint8_fromregion(&sr);
509
0
  isc_region_consume(&sr, 1);
510
511
  /*
512
   * Tag length
513
   */
514
0
  caa->tag_len = uint8_fromregion(&sr);
515
0
  isc_region_consume(&sr, 1);
516
517
  /*
518
   * Tag
519
   */
520
0
  INSIST(sr.length >= caa->tag_len);
521
0
  caa->tag = mem_maybedup(mctx, sr.base, caa->tag_len);
522
0
  isc_region_consume(&sr, caa->tag_len);
523
524
  /*
525
   * Value
526
   */
527
0
  caa->value_len = sr.length;
528
0
  caa->value = mem_maybedup(mctx, sr.base, sr.length);
529
530
0
  caa->mctx = mctx;
531
0
  return ISC_R_SUCCESS;
532
0
}
533
534
static void
535
0
freestruct_caa(ARGS_FREESTRUCT) {
536
0
  dns_rdata_caa_t *caa = (dns_rdata_caa_t *)source;
537
538
0
  REQUIRE(caa != NULL);
539
0
  REQUIRE(caa->common.rdtype == dns_rdatatype_caa);
540
541
0
  if (caa->mctx == NULL) {
542
0
    return;
543
0
  }
544
545
0
  if (caa->tag != NULL) {
546
0
    isc_mem_free(caa->mctx, caa->tag);
547
0
  }
548
0
  if (caa->value != NULL) {
549
0
    isc_mem_free(caa->mctx, caa->value);
550
0
  }
551
0
  caa->mctx = NULL;
552
0
}
553
554
static isc_result_t
555
0
additionaldata_caa(ARGS_ADDLDATA) {
556
0
  REQUIRE(rdata->type == dns_rdatatype_caa);
557
0
  REQUIRE(rdata->data != NULL);
558
0
  REQUIRE(rdata->length >= 3U);
559
560
0
  UNUSED(rdata);
561
0
  UNUSED(owner);
562
0
  UNUSED(add);
563
0
  UNUSED(arg);
564
565
0
  return ISC_R_SUCCESS;
566
0
}
567
568
static isc_result_t
569
0
digest_caa(ARGS_DIGEST) {
570
0
  isc_region_t r;
571
572
0
  REQUIRE(rdata->type == dns_rdatatype_caa);
573
0
  REQUIRE(rdata->data != NULL);
574
0
  REQUIRE(rdata->length >= 3U);
575
576
0
  dns_rdata_toregion(rdata, &r);
577
578
0
  return (digest)(arg, &r);
579
0
}
580
581
static bool
582
0
checkowner_caa(ARGS_CHECKOWNER) {
583
0
  REQUIRE(type == dns_rdatatype_caa);
584
585
0
  UNUSED(name);
586
0
  UNUSED(type);
587
0
  UNUSED(rdclass);
588
0
  UNUSED(wildcard);
589
590
0
  return true;
591
0
}
592
593
static bool
594
0
checknames_caa(ARGS_CHECKNAMES) {
595
0
  REQUIRE(rdata->type == dns_rdatatype_caa);
596
0
  REQUIRE(rdata->data != NULL);
597
0
  REQUIRE(rdata->length >= 3U);
598
599
0
  UNUSED(rdata);
600
0
  UNUSED(owner);
601
0
  UNUSED(bad);
602
603
0
  return true;
604
0
}
605
606
static int
607
0
casecompare_caa(ARGS_COMPARE) {
608
0
  return compare_caa(rdata1, rdata2);
609
0
}
610
611
#endif /* GENERIC_CAA_257_C */