Coverage Report

Created: 2026-08-13 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/lib-sieve/plugins/variables/ext-variables-name.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "str.h"
5
#include "strnum.h"
6
#include "array.h"
7
8
#include "sieve-common.h"
9
10
#include "ext-variables-common.h"
11
#include "ext-variables-limits.h"
12
#include "ext-variables-name.h"
13
14
#include <ctype.h>
15
16
bool sieve_variable_identifier_is_valid(const char *identifier)
17
0
{
18
0
  const char *p = identifier;
19
0
  size_t plen = strlen(identifier);
20
0
  const char *pend;
21
22
0
  if (plen == 0 || plen >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN)
23
0
    return FALSE;
24
25
0
  pend = PTR_OFFSET(identifier, plen);
26
27
0
  if (*p == '_' || i_isalpha(*p)) {
28
0
    p++;
29
30
0
    while (p < pend && (*p == '_' || i_isalnum(*p)))
31
0
      p++;
32
0
  }
33
34
0
  return (p == pend);
35
0
}
36
37
int ext_variable_name_parse(ARRAY_TYPE(sieve_variable_name) *vname,
38
          const char **str, const char *strend)
39
0
{
40
0
  const char *p = *str;
41
0
  const unsigned char *endp;
42
43
0
  array_clear(vname);
44
45
0
  while (p < strend) {
46
0
    struct sieve_variable_name *cur_element;
47
0
    uintmax_t num;
48
0
    string_t *cur_ident;
49
50
    /* Acquire current position in the array */
51
52
0
    if (array_count(vname) >= EXT_VARIABLES_MAX_NAMESPACE_ELEMENTS)
53
0
      return -1;
54
55
0
    cur_element = array_append_space(vname);
56
0
    cur_ident = cur_element->identifier = t_str_new(32);
57
58
    /* Parse element */
59
60
    /* Identifier */
61
0
    if (*p == '_' || i_isalpha(*p)) {
62
0
      cur_element->num_variable = -1;
63
0
      str_truncate(cur_ident, 0);
64
0
      str_append_c(cur_ident, *p);
65
0
      p++;
66
67
0
      while (p < strend && (*p == '_' || i_isalnum(*p))) {
68
0
        if (str_len(cur_ident) >=
69
0
            EXT_VARIABLES_MAX_VARIABLE_NAME_LEN)
70
0
          return -1;
71
0
        str_append_c(cur_ident, *p);
72
0
        p++;
73
0
      }
74
75
    /* Num-variable */
76
0
    } else if (str_parse_data_uintmax(
77
0
      (const unsigned char *)p, strend - p, &num,
78
0
      &endp) == 0) {
79
0
      p = (const char *)endp;
80
0
      if (num > INT_MAX)
81
0
        return -1;
82
0
      cur_element->num_variable = (int)num;
83
84
      /* If a num-variable is first, no more elements can
85
         follow because no namespace is specified.
86
       */
87
0
      if (array_count(vname) == 1) {
88
0
        *str = p;
89
0
        return 1;
90
0
      }
91
0
    } else {
92
0
      *str = p;
93
0
      return -1;
94
0
    }
95
96
    /* Check whether next name element is present */
97
0
    if (p < strend && *p == '.') {
98
0
      p++;
99
100
      /* It may not be empty */
101
0
      if (p >= strend)
102
0
        return -1;
103
0
    } else
104
0
      break;
105
0
  }
106
107
0
  *str = p;
108
0
  return array_count(vname);
109
0
}