Coverage Report

Created: 2026-09-01 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/lib-sieve/cmp-i-ascii-casemap.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
/* Comparator 'i;ascii-casemap':
4
 *
5
 */
6
7
#include "lib.h"
8
9
#include "sieve-common.h"
10
#include "sieve-comparators.h"
11
12
#include <string.h>
13
#include <stdio.h>
14
#include <ctype.h>
15
16
/*
17
 * Forward declarations
18
 */
19
20
static int
21
cmp_i_ascii_casemap_compare(const struct sieve_comparator *cmp,
22
          const char *val1, size_t val1_size,
23
          const char *val2, size_t val2_size);
24
static bool
25
cmp_i_ascii_casemap_char_match(const struct sieve_comparator *cmp,
26
             const char **val1, const char *val1_end,
27
             const char **val2, const char *val2_end);
28
29
/*
30
 * Comparator object
31
 */
32
33
const struct sieve_comparator_def i_ascii_casemap_comparator = {
34
  SIEVE_OBJECT("i;ascii-casemap", &comparator_operand,
35
         SIEVE_COMPARATOR_I_ASCII_CASEMAP),
36
  .flags =
37
    SIEVE_COMPARATOR_FLAG_ORDERING |
38
    SIEVE_COMPARATOR_FLAG_EQUALITY |
39
    SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH |
40
    SIEVE_COMPARATOR_FLAG_PREFIX_MATCH,
41
  .compare = cmp_i_ascii_casemap_compare,
42
  .char_match = cmp_i_ascii_casemap_char_match,
43
  .char_skip = sieve_comparator_octet_skip
44
};
45
46
/*
47
 * Comparator implementation
48
 */
49
50
static int
51
cmp_i_ascii_casemap_compare(const struct sieve_comparator *cmp ATTR_UNUSED,
52
          const char *val1, size_t val1_size,
53
          const char *val2, size_t val2_size)
54
0
{
55
0
  size_t size = I_MIN(val1_size, val2_size);
56
0
  int ret = strncasecmp(val1, val2, size);
57
58
0
  return (ret != 0 ? ret : (int)val1_size - (int)val2_size);
59
0
}
60
61
static bool
62
cmp_i_ascii_casemap_char_match(const struct sieve_comparator *cmp ATTR_UNUSED,
63
             const char **val, const char *val_end,
64
             const char **key, const char *key_end)
65
0
{
66
0
  const char *val_begin = *val;
67
0
  const char *key_begin = *key;
68
69
0
  while (*val < val_end && *key < key_end &&
70
0
         i_tolower(**val) == i_tolower(**key)) {
71
0
    (*val)++;
72
0
    (*key)++;
73
0
  }
74
75
0
  if (*key < key_end) {
76
    /* Reset */
77
0
    *val = val_begin;
78
0
    *key = key_begin;
79
80
0
    return FALSE;
81
0
  }
82
0
  return TRUE;
83
0
}