Coverage Report

Created: 2026-09-03 06:30

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
13.2k
#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
7.13k
fromtext_caa(ARGS_FROMTEXT) {
280
7.13k
  isc_token_t token;
281
7.13k
  isc_textregion_t tr;
282
7.13k
  uint8_t flags;
283
7.13k
  unsigned int i;
284
285
7.13k
  REQUIRE(type == dns_rdatatype_caa);
286
287
7.13k
  UNUSED(type);
288
7.13k
  UNUSED(rdclass);
289
7.13k
  UNUSED(origin);
290
7.13k
  UNUSED(options);
291
7.13k
  UNUSED(callbacks);
292
293
  /* Flags. */
294
7.13k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
295
7.13k
              false));
296
7.13k
  if (token.value.as_ulong > 255U) {
297
43
    RETTOK(ISC_R_RANGE);
298
43
  }
299
7.09k
  flags = (uint8_t)(token.value.as_ulong & 255U);
300
7.09k
  RETERR(uint8_tobuffer(flags, target));
301
302
  /*
303
   * Tag
304
   */
305
7.09k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
306
7.09k
              false));
307
7.07k
  tr = token.value.as_textregion;
308
18.8k
  for (i = 0; i < tr.length; i++) {
309
11.8k
    if (!alphanumeric[(unsigned char)tr.base[i]]) {
310
12
      RETTOK(DNS_R_SYNTAX);
311
12
    }
312
11.8k
  }
313
7.06k
  RETERR(uint8_tobuffer(tr.length, target));
314
7.06k
  RETERR(mem_tobuffer(target, tr.base, tr.length));
315
316
  /*
317
   * Value
318
   */
319
7.06k
  RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
320
7.06k
              false));
321
7.05k
  if (token.type != isc_tokentype_qstring &&
322
6.62k
      token.type != isc_tokentype_string)
323
0
  {
324
0
    RETERR(DNS_R_SYNTAX);
325
0
  }
326
7.05k
  RETERR(multitxt_fromtext(&token.value.as_textregion, target));
327
7.01k
  return ISC_R_SUCCESS;
328
7.05k
}
329
330
static isc_result_t
331
1.28k
totext_caa(ARGS_TOTEXT) {
332
1.28k
  isc_region_t region;
333
1.28k
  uint8_t flags;
334
1.28k
  char buf[256];
335
336
1.28k
  UNUSED(tctx);
337
338
1.28k
  REQUIRE(rdata->type == dns_rdatatype_caa);
339
1.28k
  REQUIRE(rdata->length >= 3U);
340
1.28k
  REQUIRE(rdata->data != NULL);
341
342
1.28k
  dns_rdata_toregion(rdata, &region);
343
344
  /*
345
   * Flags
346
   */
347
1.28k
  flags = uint8_consume_fromregion(&region);
348
1.28k
  snprintf(buf, sizeof(buf), "%u ", flags);
349
1.28k
  RETERR(str_totext(buf, target));
350
351
  /*
352
   * Tag
353
   */
354
1.28k
  RETERR(txt_totext(&region, false, target));
355
1.28k
  RETERR(str_totext(" ", target));
356
357
  /*
358
   * Value
359
   */
360
1.28k
  RETERR(multitxt_totext(&region, target));
361
1.28k
  return ISC_R_SUCCESS;
362
1.28k
}
363
364
static isc_result_t
365
2.30k
fromwire_caa(ARGS_FROMWIRE) {
366
2.30k
  isc_region_t sr;
367
2.30k
  unsigned int len, i;
368
369
2.30k
  REQUIRE(type == dns_rdatatype_caa);
370
371
2.30k
  UNUSED(type);
372
2.30k
  UNUSED(rdclass);
373
2.30k
  UNUSED(dctx);
374
375
  /*
376
   * Flags
377
   */
378
2.30k
  isc_buffer_activeregion(source, &sr);
379
2.30k
  if (sr.length < 2) {
380
10
    return ISC_R_UNEXPECTEDEND;
381
10
  }
382
383
  /*
384
   * Flags, tag length
385
   */
386
2.29k
  RETERR(mem_tobuffer(target, sr.base, 2));
387
2.09k
  len = sr.base[1];
388
2.09k
  isc_region_consume(&sr, 2);
389
2.09k
  isc_buffer_forward(source, 2);
390
391
  /*
392
   * Zero length tag fields are illegal.
393
   */
394
2.09k
  if (sr.length < len || len == 0) {
395
48
    RETERR(DNS_R_FORMERR);
396
0
  }
397
398
  /* Check the Tag's value */
399
5.96k
  for (i = 0; i < len; i++) {
400
3.94k
    if (!alphanumeric[sr.base[i]]) {
401
26
      RETERR(DNS_R_FORMERR);
402
      /*
403
       * Tag + Value
404
       */
405
0
    }
406
3.94k
  }
407
  /*
408
   * Tag + Value
409
   */
410
2.01k
  isc_buffer_forward(source, sr.length);
411
2.01k
  return mem_tobuffer(target, sr.base, sr.length);
412
2.04k
}
413
414
static isc_result_t
415
762
towire_caa(ARGS_TOWIRE) {
416
762
  isc_region_t region;
417
418
762
  REQUIRE(rdata->type == dns_rdatatype_caa);
419
762
  REQUIRE(rdata->length >= 3U);
420
762
  REQUIRE(rdata->data != NULL);
421
422
762
  UNUSED(cctx);
423
424
762
  dns_rdata_toregion(rdata, &region);
425
762
  return mem_tobuffer(target, region.base, region.length);
426
762
}
427
428
static int
429
504k
compare_caa(ARGS_COMPARE) {
430
504k
  isc_region_t r1, r2;
431
432
504k
  REQUIRE(rdata1->type == rdata2->type);
433
504k
  REQUIRE(rdata1->rdclass == rdata2->rdclass);
434
504k
  REQUIRE(rdata1->type == dns_rdatatype_caa);
435
504k
  REQUIRE(rdata1->length >= 3U);
436
504k
  REQUIRE(rdata2->length >= 3U);
437
504k
  REQUIRE(rdata1->data != NULL);
438
504k
  REQUIRE(rdata2->data != NULL);
439
440
504k
  dns_rdata_toregion(rdata1, &r1);
441
504k
  dns_rdata_toregion(rdata2, &r2);
442
504k
  return isc_region_compare(&r1, &r2);
443
504k
}
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 */