/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 | } |