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
|
/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
*/
/* Match-type ':contains'
*/
#include "lib.h"
#include "sieve-match-types.h"
#include "sieve-comparators.h"
#include "sieve-match.h"
#include <string.h>
#include <stdio.h>
/*
* Forward declarations
*/
static int mcht_contains_match_key
(struct sieve_match_context *mctx, const char *val, size_t val_size,
const char *key, size_t key_size);
/*
* Match-type object
*/
const struct sieve_match_type_def contains_match_type = {
SIEVE_OBJECT("contains",
&match_type_operand, SIEVE_MATCH_TYPE_CONTAINS),
.validate_context = sieve_match_substring_validate_context,
.match_key = mcht_contains_match_key
};
/*
* Match-type implementation
*/
/* FIXME: Naive substring match implementation. Should switch to more
* efficient algorithm if large values need to be searched (e.g. message body).
*/
static int mcht_contains_match_key
(struct sieve_match_context *mctx, const char *val, size_t val_size,
const char *key, size_t key_size)
{
const struct sieve_comparator *cmp = mctx->comparator;
const char *vend = (const char *) val + val_size;
const char *kend = (const char *) key + key_size;
const char *vp = val;
const char *kp = key;
if ( val_size == 0 )
return ( key_size == 0 ? 1 : 0 );
if ( cmp->def == NULL || cmp->def->char_match == NULL )
return 0;
while ( (vp < vend) && (kp < kend) ) {
if ( !cmp->def->char_match(cmp, &vp, vend, &kp, kend) )
vp++;
}
return ( kp == kend ? 1 : 0 );
}
|