Coverage Report

Created: 2025-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dovecot/src/lib-dns/dns-util.c
Line
Count
Source
1
/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
2
#include "lib.h"
3
#include "dns-util.h"
4
5
/**
6
  return first position from b->a of c or a if not found
7
 */
8
static inline
9
const char *strchr_ba(const char *a, const char *b, char c)
10
0
{
11
0
  for(;b>a && *b != c; b--);
12
0
  return b;
13
0
}
14
15
int dns_ncompare(const char *a, const char *b, size_t n)
16
0
{
17
0
  if (a == NULL && b == NULL) return 0;
18
0
  if (a == NULL && b != NULL) return 1;
19
0
  if (a != NULL && b == NULL) return -1;
20
21
0
  for(size_t i = 0; i < n &&
22
0
        *a != '\0' &&
23
0
        *b != '\0' &&
24
0
        dns_tolower(*a) == dns_tolower(*b);
25
0
      i++, a++, b++);
26
27
0
  return dns_tolower(*a) - dns_tolower(*b);
28
0
}
29
30
int dns_compare(const char *a, const char *b)
31
0
{
32
0
  return dns_ncompare(a, b, SIZE_MAX);
33
0
}
34
35
int dns_compare_labels(const char *a, const char *b)
36
0
{
37
0
  if (a == NULL && b == NULL) return 0;
38
0
  if (a == NULL && b != NULL) return 1;
39
0
  if (a != NULL && b == NULL) return -1;
40
41
0
  const char *ptr_a = a + strlen(a);
42
0
  const char *ptr_b = b + strlen(b);
43
0
  const char *label_a = ptr_a, *label_b = ptr_b;
44
0
  int comp = 0;
45
46
0
  while(comp == 0 && ptr_a > a && ptr_b > b) {
47
    /* look for start of label, including dot */
48
0
    label_a = strchr_ba(a, ptr_a, '.');
49
0
    label_b = strchr_ba(b, ptr_b, '.');
50
0
    if (ptr_a - label_a != ptr_b - label_b)
51
      /* compare labels up to minimum length
52
         but include \0 to make sure that we
53
         don't consider alpha and alphabet
54
         equal */
55
0
      return dns_ncompare(label_a, label_b,
56
0
             I_MIN(ptr_a - label_a,
57
0
             ptr_b - label_b)+1);
58
0
    comp = dns_ncompare(label_a, label_b, ptr_a -label_a);
59
0
    ptr_a = label_a - 1;
60
0
    ptr_b = label_b - 1;
61
0
  }
62
63
0
  return dns_tolower(*label_a) - dns_tolower(*label_b);
64
0
}
65
66
int dns_match_wildcard(const char *name, const char *mask)
67
0
{
68
0
  i_assert(name != NULL && mask != NULL);
69
70
0
  for(;*name != '\0' && *mask != '\0'; name++, mask++) {
71
0
    switch(*mask) {
72
0
    case '*':
73
0
      name = strchr(name, '.');
74
0
      if (name == NULL || mask[1] != '.') return -1;
75
0
      mask++;
76
0
      break;
77
0
    case '?':
78
0
      break;
79
0
    default:
80
0
      if (dns_tolower(*name) != dns_tolower(*mask)) return -1;
81
0
    }
82
0
  }
83
0
  if (*mask == '*') mask++;
84
0
  return dns_tolower(*name) == dns_tolower(*mask) ? 0 : -1;
85
0
}