/src/pigeonhole/src/lib-sieve/plugins/variables/ext-variables-name.c
Line | Count | Source |
1 | | /* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file |
2 | | */ |
3 | | |
4 | | #include "lib.h" |
5 | | #include "str.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 | 0 | } |
34 | |
|
35 | 0 | return ( p == pend ); |
36 | 0 | } |
37 | | |
38 | | int ext_variable_name_parse |
39 | | (ARRAY_TYPE(sieve_variable_name) *vname, const char **str, const char *strend) |
40 | 0 | { |
41 | 0 | const char *p = *str; |
42 | |
|
43 | 0 | array_clear(vname); |
44 | |
|
45 | 0 | while ( p < strend ) { |
46 | 0 | struct sieve_variable_name *cur_element; |
47 | 0 | string_t *cur_ident; |
48 | | |
49 | | /* Acquire current position in the array */ |
50 | |
|
51 | 0 | if ( array_count(vname) >= EXT_VARIABLES_MAX_NAMESPACE_ELEMENTS ) |
52 | 0 | return -1; |
53 | | |
54 | 0 | cur_element = array_append_space(vname); |
55 | 0 | cur_ident = cur_element->identifier = t_str_new(32); |
56 | | |
57 | | /* Parse element */ |
58 | | |
59 | | /* Identifier */ |
60 | 0 | if ( *p == '_' || i_isalpha(*p) ) { |
61 | 0 | cur_element->num_variable = -1; |
62 | 0 | str_truncate(cur_ident, 0); |
63 | 0 | str_append_c(cur_ident, *p); |
64 | 0 | p++; |
65 | |
|
66 | 0 | while ( p < strend && (*p == '_' || i_isalnum(*p)) ) { |
67 | 0 | if ( str_len(cur_ident) >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN ) |
68 | 0 | return -1; |
69 | 0 | str_append_c(cur_ident, *p); |
70 | 0 | p++; |
71 | 0 | } |
72 | | |
73 | | /* Num-variable */ |
74 | 0 | } else if ( i_isdigit(*p) ) { |
75 | 0 | cur_element->num_variable = *p - '0'; |
76 | 0 | p++; |
77 | |
|
78 | 0 | while ( p < strend && i_isdigit(*p) ) { |
79 | 0 | cur_element->num_variable = cur_element->num_variable*10 + (*p - '0'); |
80 | 0 | p++; |
81 | 0 | } |
82 | | |
83 | | /* If a num-variable is first, no more elements can follow because no |
84 | | * namespace is specified. |
85 | | */ |
86 | 0 | if ( array_count(vname) == 1 ) { |
87 | 0 | *str = p; |
88 | 0 | return 1; |
89 | 0 | } |
90 | 0 | } else { |
91 | 0 | *str = p; |
92 | 0 | return -1; |
93 | 0 | } |
94 | | |
95 | | /* Check whether next name element is present */ |
96 | 0 | if ( p < strend && *p == '.' ) { |
97 | 0 | p++; |
98 | | |
99 | | /* It may not be empty */ |
100 | 0 | if ( p >= strend ) |
101 | 0 | return -1; |
102 | 0 | } else |
103 | 0 | break; |
104 | 0 | } |
105 | | |
106 | 0 | *str = p; |
107 | 0 | return array_count(vname); |
108 | 0 | } |
109 | | |
110 | | |