1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
9
#include "sieve-extensions.h"
10
#include "sieve-commands.h"
11
#include "sieve-code.h"
12
#include "sieve-binary.h"
13
#include "sieve-validator.h"
14
#include "sieve-generator.h"
15
#include "sieve-interpreter.h"
16
#include "sieve-dump.h"
17
#include "sieve-comparators.h"
18
#include "sieve-match-types.h"
20
#include "sieve-match.h"
23
* Matching implementation
26
struct sieve_match_context *sieve_match_begin
27
(struct sieve_interpreter *interp, const struct sieve_match_type *mtch,
28
const struct sieve_comparator *cmp,
29
const struct sieve_match_key_extractor *kextract,
30
struct sieve_coded_stringlist *key_list)
32
struct sieve_match_context *mctx;
35
pool = pool_alloconly_create("sieve_match_context", 1024);
36
mctx = p_new(pool, struct sieve_match_context, 1);
39
mctx->interp = interp;
40
mctx->match_type = mtch;
41
mctx->comparator = cmp;
42
mctx->kextract = kextract;
43
mctx->key_list = key_list;
45
if ( mtch->match_init != NULL ) {
46
mtch->match_init(mctx);
53
(struct sieve_match_context *mctx, const char *value, size_t val_size)
55
const struct sieve_match_type *mtch = mctx->match_type;
56
sieve_coded_stringlist_reset(mctx->key_list);
59
/* Reject unimplemented match-type */
60
if ( mtch->match == NULL )
63
/* Match to all key values */
64
if ( mtch->is_iterative ) {
65
unsigned int key_index = 0;
66
string_t *key_item = NULL;
69
while ( (ok=sieve_coded_stringlist_next_item(mctx->key_list, &key_item))
73
if ( mctx->kextract != NULL && mtch->allow_key_extract ) {
74
const struct sieve_match_key_extractor *kext = mctx->kextract;
77
if ( (ret=kext->init(&kctx, key_item)) > 0 ) {
81
while ( (ret=kext->extract_key(kctx, &key, &key_size)) > 0 ) {
83
(mctx, value, val_size, key, key_size, key_index);
85
if ( ret != 0 ) break;
89
ret = mtch->match(mctx, value, val_size, str_c(key_item),
90
str_len(key_item), key_index);
112
result = mtch->match(mctx, value, val_size, NULL, 0, -1);
121
int sieve_match_end(struct sieve_match_context **mctx)
123
const struct sieve_match_type *mtch = (*mctx)->match_type;
126
if ( mtch->match_deinit != NULL ) {
127
ret = mtch->match_deinit(*mctx);
130
pool_unref(&(*mctx)->pool);
137
* Reading match operands
140
bool sieve_match_dump_optional_operands
141
(const struct sieve_dumptime_env *denv, sieve_size_t *address, int *opt_code)
143
if ( *opt_code != SIEVE_MATCH_OPT_END ||
144
sieve_operand_optional_present(denv->sbin, address) ) {
146
if ( !sieve_operand_optional_read(denv->sbin, address, opt_code) )
149
switch ( *opt_code ) {
150
case SIEVE_MATCH_OPT_END:
152
case SIEVE_MATCH_OPT_COMPARATOR:
153
if ( !sieve_opr_comparator_dump(denv, address) )
156
case SIEVE_MATCH_OPT_MATCH_TYPE:
157
if ( !sieve_opr_match_type_dump(denv, address) )
163
} while ( *opt_code != SIEVE_MATCH_OPT_END );
169
int sieve_match_read_optional_operands
170
(const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code,
171
const struct sieve_comparator **cmp_r, const struct sieve_match_type **mtch_r)
173
/* Handle any optional arguments */
174
if ( *opt_code != SIEVE_MATCH_OPT_END ||
175
sieve_operand_optional_present(renv->sbin, address) ) {
177
if ( !sieve_operand_optional_read(renv->sbin, address, opt_code) ) {
178
sieve_runtime_trace_error(renv, "invalid optional operand");
179
return SIEVE_EXEC_BIN_CORRUPT;
182
switch ( *opt_code ) {
183
case SIEVE_MATCH_OPT_END:
185
case SIEVE_MATCH_OPT_COMPARATOR:
186
if ( (*cmp_r = sieve_opr_comparator_read(renv, address)) == NULL ) {
187
sieve_runtime_trace_error(renv, "invalid comparator operand");
188
return SIEVE_EXEC_BIN_CORRUPT;
191
case SIEVE_MATCH_OPT_MATCH_TYPE:
192
if ( (*mtch_r = sieve_opr_match_type_read(renv, address)) == NULL ) {
193
sieve_runtime_trace_error(renv, "invalid match type operand");
194
return SIEVE_EXEC_BIN_CORRUPT;
198
return SIEVE_EXEC_OK;
200
} while ( *opt_code != SIEVE_MATCH_OPT_END );
203
return SIEVE_EXEC_OK;