File: ext-variables-name.c

package info (click to toggle)
dovecot 1:2.2.13-12~deb8u4
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 38,792 kB
  • sloc: ansic: 341,472; sh: 16,920; makefile: 5,393; cpp: 1,474; perl: 265; xml: 44; python: 34; pascal: 27
file content (110 lines) | stat: -rw-r--r-- 2,235 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file
 */

#include "lib.h"
#include "str.h"
#include "array.h"

#include "sieve-common.h"

#include "ext-variables-common.h"
#include "ext-variables-limits.h"
#include "ext-variables-name.h"

#include <ctype.h>

bool sieve_variable_identifier_is_valid(const char *identifier)
{
	const char *p = identifier;
	size_t plen = strlen(identifier);
	const char *pend;

	if ( plen == 0 || plen >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN )
		return FALSE;

	pend = PTR_OFFSET(identifier, plen);

	if ( *p == '_' || i_isalpha(*p) ) {
		p++;

		while ( p < pend && (*p == '_' || i_isalnum(*p)) ) {
			p++;
		}
	}

	return ( p == pend );
}

int ext_variable_name_parse
(ARRAY_TYPE(sieve_variable_name) *vname, const char **str, const char *strend)
{
	const char *p = *str;

	array_clear(vname);

	while ( p < strend ) {
		struct sieve_variable_name *cur_element;
		string_t *cur_ident;

		/* Acquire current position in the array */

		if ( array_count(vname) >= EXT_VARIABLES_MAX_NAMESPACE_ELEMENTS )
			return -1;

		cur_element = array_append_space(vname);
		cur_ident = cur_element->identifier = t_str_new(32);

		/* Parse element */

		/* Identifier */
		if ( *p == '_' || i_isalpha(*p) ) {
			cur_element->num_variable = -1;
			str_truncate(cur_ident, 0);
			str_append_c(cur_ident, *p);
			p++;

			while ( p < strend && (*p == '_' || i_isalnum(*p)) ) {
				if ( str_len(cur_ident) >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN )
					return -1;
				str_append_c(cur_ident, *p);
				p++;
			}

		/* Num-variable */
		} else if ( i_isdigit(*p) ) {
			cur_element->num_variable = *p - '0';
			p++;

			while ( p < strend && i_isdigit(*p) ) {
				cur_element->num_variable = cur_element->num_variable*10 + (*p - '0');
				p++;
			}

			/* If a num-variable is first, no more elements can follow because no
			 * namespace is specified.
			 */
			if ( array_count(vname) == 1 ) {
				*str = p;
				return 1;
			}
		} else {
			*str = p;
			return -1;
		}

		/* Check whether next name element is present */
		if ( p < strend && *p == '.' ) {
			p++;

			/* It may not be empty */
			if ( p >= strend )
				return -1;
		} else
			break;
	}

	*str = p;
	return array_count(vname);
}