summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/numaddr.c2
-rw-r--r--include/mailutils/sieve.h78
-rw-r--r--libmu_sieve/Makefile.am1
-rw-r--r--libmu_sieve/actions.c17
-rw-r--r--libmu_sieve/comparator.c297
-rw-r--r--libmu_sieve/extensions/editheader.c62
-rw-r--r--libmu_sieve/extensions/list.c2
-rw-r--r--libmu_sieve/extensions/vacation.c22
-rw-r--r--libmu_sieve/mem.c41
-rw-r--r--libmu_sieve/prog.c366
-rw-r--r--libmu_sieve/relational.c5
-rw-r--r--libmu_sieve/require.c24
-rw-r--r--libmu_sieve/runtime.c46
-rw-r--r--libmu_sieve/sieve-priv.h51
-rw-r--r--libmu_sieve/sieve.y257
-rw-r--r--libmu_sieve/string.c61
-rw-r--r--libmu_sieve/tests.c84
-rw-r--r--libmu_sieve/util.c379
-rw-r--r--sieve/tests/delheader.at2
-rw-r--r--sieve/tests/enc-char.at35
20 files changed, 908 insertions, 924 deletions
diff --git a/examples/numaddr.c b/examples/numaddr.c
index 7981e0bc2..584d2b9f7 100644
--- a/examples/numaddr.c
+++ b/examples/numaddr.c
@@ -95,7 +95,7 @@ numaddr_test (mu_sieve_machine_t mach)
vc.count = 0;
/* Count the addresses */
- rc = mu_sieve_vlist_do (h, _count_items, &vc);
+ rc = mu_sieve_vlist_do (mach, h, _count_items, &vc);
/* Here rc >= 1 iff the counted number of addresses is greater or equal
to vc.limit. If `:under' tag was given we reverse the return value */
diff --git a/include/mailutils/sieve.h b/include/mailutils/sieve.h
index 20ad24eec..7227abad8 100644
--- a/include/mailutils/sieve.h
+++ b/include/mailutils/sieve.h
@@ -33,6 +33,13 @@ extern "C" {
typedef struct mu_sieve_machine *mu_sieve_machine_t;
+typedef struct mu_sieve_string
+{
+ char *orig;
+ char *exp;
+ void *rx;
+} mu_sieve_string_t;
+
typedef int (*mu_sieve_handler_t) (mu_sieve_machine_t mach);
typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t mach,
const char *action,
@@ -40,13 +47,12 @@ typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t mach,
typedef int (*mu_sieve_relcmp_t) (int, int);
typedef int (*mu_sieve_relcmpn_t) (size_t, size_t);
-typedef int (*mu_sieve_comparator_t) (const char *, const char *);
+typedef int (*mu_sieve_comparator_t) (mu_sieve_machine_t mach,
+ mu_sieve_string_t *, const char *);
typedef int (*mu_sieve_retrieve_t) (void *item, void *data, int idx,
char **pval);
typedef void (*mu_sieve_destructor_t) (void *data);
-typedef int (*mu_sieve_tag_checker_t) (mu_sieve_machine_t mach,
- const char *name,
- mu_list_t tags, mu_list_t args);
+typedef int (*mu_sieve_tag_checker_t) (mu_sieve_machine_t mach);
typedef enum
{
@@ -55,24 +61,29 @@ typedef enum
SVT_STRING,
SVT_STRING_LIST,
SVT_TAG,
- SVT_IDENT,
- SVT_POINTER
+ SVT_IDENT
}
mu_sieve_data_type;
-typedef struct mu_sieve_runtime_tag mu_sieve_runtime_tag_t;
+struct mu_sieve_slice
+{
+ size_t first;
+ size_t count;
+};
+
+typedef struct mu_sieve_slice *mu_sieve_slice_t;
union mu_sieve_value_storage
{
char *string;
size_t number;
- mu_list_t list;
- void *ptr;
+ struct mu_sieve_slice list;
};
typedef struct
{
mu_sieve_data_type type;
+ char *tag;
union mu_sieve_value_storage v;
} mu_sieve_value_t;
@@ -88,12 +99,6 @@ typedef struct
mu_sieve_tag_checker_t checker;
} mu_sieve_tag_group_t;
-struct mu_sieve_runtime_tag
-{
- char *tag;
- mu_sieve_value_t *arg;
-};
-
typedef struct
{
const char *name;
@@ -135,11 +140,9 @@ void *mu_sieve_realloc (mu_sieve_machine_t mach, void *ptr, size_t size);
void mu_sieve_reclaim_default (void *p);
void mu_sieve_reclaim_list (void *p);
void mu_sieve_reclaim_value (void *p);
-void mu_sieve_reclaim_tag (void *p);
-mu_sieve_value_t *mu_sieve_value_create (mu_sieve_machine_t mach,
- mu_sieve_data_type type, void *data);
-void mu_sieve_slist_destroy (mu_list_t *plist);
+size_t mu_sieve_value_create (mu_sieve_machine_t mach,
+ mu_sieve_data_type type, void *data);
/* Symbol space functions */
mu_sieve_register_t *mu_sieve_test_lookup (mu_sieve_machine_t mach,
@@ -185,30 +188,41 @@ int mu_sieve_str_to_relcmp (const char *str, mu_sieve_relcmp_t *test,
mu_sieve_relcmpn_t *stest);
mu_sieve_relcmp_t mu_sieve_get_relcmp (mu_sieve_machine_t mach);
-void mu_sieve_require (mu_sieve_machine_t mach, mu_list_t slist);
+void mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list);
+void mu_sieve_value_get (mu_sieve_machine_t mach, mu_sieve_value_t *val,
+ mu_sieve_data_type type, void *ret);
+
int mu_sieve_get_tag (mu_sieve_machine_t mach, char *name,
mu_sieve_data_type type, void *ret);
-int mu_sieve_get_tag_untyped (mu_sieve_machine_t mach,
- char *name, mu_sieve_value_t **ret);
+mu_sieve_value_t *mu_sieve_get_tag_untyped (mu_sieve_machine_t mach,
+ char const *name);
+mu_sieve_value_t *mu_sieve_get_tag_n (mu_sieve_machine_t mach, size_t n);
int mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name);
-int mu_sieve_match_part_checker (mu_sieve_machine_t mach,
- const char *name, mu_list_t tags,
- mu_list_t args);
-int mu_sieve_match_part_checker (mu_sieve_machine_t mach,
- const char *name, mu_list_t tags,
- mu_list_t args);
+int mu_sieve_match_part_checker (mu_sieve_machine_t mach);
+
/* Operations on value lists */
mu_sieve_value_t *mu_sieve_get_arg_optional (mu_sieve_machine_t mach,
size_t index);
mu_sieve_value_t *mu_sieve_get_arg_untyped (mu_sieve_machine_t mach,
size_t index);
-int mu_sieve_get_arg (mu_sieve_machine_t mach, size_t index,
- mu_sieve_data_type type, void *ret);
-int mu_sieve_vlist_do (mu_sieve_value_t *val, mu_list_action_t ac,
+void mu_sieve_get_arg (mu_sieve_machine_t mach, size_t index,
+ mu_sieve_data_type type, void *ret);
+
+char *mu_sieve_string (mu_sieve_machine_t mach,
+ mu_sieve_slice_t slice,
+ size_t i);
+struct mu_sieve_string *mu_sieve_string_raw (mu_sieve_machine_t mach,
+ mu_sieve_slice_t slice,
+ size_t i);
+
+
+int mu_sieve_vlist_do (mu_sieve_machine_t mach,
+ mu_sieve_value_t *val, mu_list_action_t ac,
void *data);
-int mu_sieve_vlist_compare (mu_sieve_value_t *a, mu_sieve_value_t *b,
+int mu_sieve_vlist_compare (mu_sieve_machine_t mach,
+ mu_sieve_value_t *a, mu_sieve_value_t *b,
mu_sieve_comparator_t comp,
mu_sieve_relcmp_t test, mu_sieve_retrieve_t ac,
void *data, size_t *count);
diff --git a/libmu_sieve/Makefile.am b/libmu_sieve/Makefile.am
index 0b06ffe3e..b9f3a0ada 100644
--- a/libmu_sieve/Makefile.am
+++ b/libmu_sieve/Makefile.am
@@ -42,6 +42,7 @@ libmu_sieve_la_SOURCES = \
sieve-gram.h\
sieve-lex.c\
strexp.c\
+ string.c\
tests.c\
util.c
libmu_sieve_la_LIBADD = ${MU_LIB_MAILUTILS} @LTDL_LIB@
diff --git a/libmu_sieve/actions.c b/libmu_sieve/actions.c
index 077b8cd06..f3ef7f472 100644
--- a/libmu_sieve/actions.c
+++ b/libmu_sieve/actions.c
@@ -511,24 +511,22 @@ mu_sieve_data_type fileinto_args[] = {
};
static int
-perms_tag_checker (mu_sieve_machine_t mach,
- const char *name, mu_list_t tags, mu_list_t args)
+perms_tag_checker (mu_sieve_machine_t mach)
{
- mu_iterator_t itr;
+ size_t i;
int err = 0;
- if (!tags || mu_list_get_iterator (tags, &itr))
+ if (mach->tagcount == 0)
return 0;
- for (mu_iterator_first (itr); !err && !mu_iterator_is_done (itr);
- mu_iterator_next (itr))
+ for (i = 0; i < mach->tagcount; i++)
{
int flag;
const char *p;
- mu_sieve_runtime_tag_t *t;
- mu_iterator_current (itr, (void **)&t);
+ mu_sieve_value_t *t = mu_sieve_get_tag_n (mach, i);
+
if (strcmp (t->tag, "permissions") == 0)
{
- if (mu_parse_stream_perm_string (&flag, t->arg->v.string, &p))
+ if (mu_parse_stream_perm_string (&flag, t->v.string, &p))
{
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
_("invalid permissions (near %s)"), p);
@@ -537,7 +535,6 @@ perms_tag_checker (mu_sieve_machine_t mach,
}
}
}
- mu_iterator_destroy (&itr);
return err;
}
diff --git a/libmu_sieve/comparator.c b/libmu_sieve/comparator.c
index a2ac34b0f..a0d5836d3 100644
--- a/libmu_sieve/comparator.c
+++ b/libmu_sieve/comparator.c
@@ -38,13 +38,13 @@ typedef struct {
int
mu_sieve_register_comparator (mu_sieve_machine_t mach,
- const char *name,
- int required,
- mu_sieve_comparator_t is,
- mu_sieve_comparator_t contains,
- mu_sieve_comparator_t matches,
- mu_sieve_comparator_t regex,
- mu_sieve_comparator_t eq)
+ const char *name,
+ int required,
+ mu_sieve_comparator_t is,
+ mu_sieve_comparator_t contains,
+ mu_sieve_comparator_t matches,
+ mu_sieve_comparator_t regex,
+ mu_sieve_comparator_t eq)
{
sieve_comparator_record_t *rp;
@@ -113,56 +113,28 @@ mu_sieve_comparator_lookup (mu_sieve_machine_t mach, const char *name,
return NULL;
}
-static int
-_find_comparator (void *item, void *data)
-{
- mu_sieve_runtime_tag_t *tag = item;
-
- if (strcmp (tag->tag, TAG_COMPFUN) == 0)
- {
- *(mu_sieve_comparator_t*)data = tag->arg->v.ptr;
- return 1;
- }
- return 0;
-}
+static int i_ascii_casemap_is (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text);
mu_sieve_comparator_t
mu_sieve_get_comparator (mu_sieve_machine_t mach)
{
- mu_sieve_comparator_t comp = NULL;
-
- mu_list_foreach (mach->tag_list, _find_comparator, &comp);
- return comp ? comp : mu_sieve_comparator_lookup (mach,
- "i;ascii-casemap",
- MU_SIEVE_MATCH_IS);
+ if (!mach->comparator)
+ return i_ascii_casemap_is;
+ return mach->comparator;
}
/* Compile time support */
-
-struct regex_data
-{
- mu_sieve_machine_t mach;
- int flags;
- mu_list_t list;
-};
-
-#ifndef FNM_CASEFOLD
-static int
-_pattern_upcase (void *item, void *data)
-{
- mu_strupper (item);
- return 0;
-}
-#endif
-
-static int
-_regex_compile (void *item, void *data)
+static void
+compile_pattern (mu_sieve_machine_t mach, mu_sieve_string_t *pattern, int flags)
{
- struct regex_data *rd = data;
int rc;
- regex_t *preg = mu_sieve_malloc (rd->mach, sizeof (*preg));
-
- rc = regcomp (preg, (char*)item, rd->flags);
+ regex_t *preg;
+
+ if (pattern->rx)
+ return;
+ preg = mu_sieve_malloc (mach, sizeof (*preg));
+ rc = regcomp (preg, pattern->orig, REG_EXTENDED | flags);
if (rc)
{
size_t size = regerror (rc, preg, NULL, 0);
@@ -170,64 +142,39 @@ _regex_compile (void *item, void *data)
if (errbuf)
{
regerror (rc, preg, errbuf, size);
- mu_diag_at_locus (MU_LOG_ERROR, &rd->mach->locus,
- _("regex error: %s"), errbuf);
+ mu_sieve_error (mach, _("regex error: %s"), errbuf);
free (errbuf);
}
else
- mu_diag_at_locus (MU_LOG_ERROR, &rd->mach->locus, _("regex error"));
- mu_i_sv_error (rd->mach);
- return rc;
+ mu_sieve_error (mach, _("regex error"));
+ mu_sieve_abort (mach);
}
-
- mu_list_append (rd->list, preg);
-
- return 0;
-}
-
-static int
-_free_regex (void *item, void *unused)
-{
- regfree ((regex_t*)item);
- return 0;
-}
-
-static void
-_free_reglist (void *data)
-{
- mu_list_t list = data;
- mu_list_foreach (list, _free_regex, NULL);
- mu_list_destroy (&list);
+ pattern->rx = preg;
}
static int
-comp_false (const char *pattern, const char *text)
+comp_false (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
+ const char *text)
{
return 0;
}
int
-mu_sieve_match_part_checker (mu_sieve_machine_t mach,
- const char *name, mu_list_t tags, mu_list_t args)
+mu_sieve_match_part_checker (mu_sieve_machine_t mach)
{
- mu_iterator_t itr;
- mu_sieve_runtime_tag_t *match = NULL;
- mu_sieve_runtime_tag_t *comp = NULL;
- mu_sieve_runtime_tag_t *tmp;
+ size_t i;
+ mu_sieve_value_t *match = NULL;
mu_sieve_comparator_t compfun = NULL;
- char *compname = "false";
+ char *compname = NULL;
int matchtype;
- int err = 0;
-
- if (!tags || mu_list_get_iterator (tags, &itr))
+
+ if (mach->tagcount == 0)
return 0;
- for (mu_iterator_first (itr); !err && !mu_iterator_is_done (itr);
- mu_iterator_next (itr))
+ for (i = 0; i < mach->tagcount; i++)
{
- mu_sieve_runtime_tag_t *t;
- mu_iterator_current (itr, (void **)&t);
+ mu_sieve_value_t *t = mu_sieve_get_tag_n (mach, i);
if (strcmp (t->tag, "is") == 0
|| strcmp (t->tag, "contains") == 0
@@ -240,22 +187,21 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach,
{
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
_("match type specified twice in call to `%s'"),
- name);
+ mach->identifier);
mu_i_sv_error (mach);
- err = 1;
+ return 1;
}
else
match = t;
}
- else if (strcmp (t->tag, "comparator") == 0)
- comp = t;
+ else if (strcmp (t->tag, "comparator") == 0)
+ {
+ if (t->type != SVT_STRING)
+ abort ();
+ compname = mu_sieve_string (mach, &t->v.list, 0);
+ }
}
- mu_iterator_destroy (&itr);
-
- if (err)
- return 1;
-
if (!match || strcmp (match->tag, "is") == 0)
matchtype = MU_SIEVE_MATCH_IS;
else if (strcmp (match->tag, "contains") == 0)
@@ -264,42 +210,43 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach,
matchtype = MU_SIEVE_MATCH_MATCHES;
else if (strcmp (match->tag, "regex") == 0)
matchtype = MU_SIEVE_MATCH_REGEX;
- else
+ else if (match->type == SVT_STRING)
{
- char *str = match->arg->v.string;
+ char *str = mu_sieve_string (mach, &match->v.list, 0);
if (strcmp (match->tag, "count") == 0)
{
mu_sieve_value_t *val;
char *str;
size_t count;
- if (comp && strcmp (comp->arg->v.string, "i;ascii-numeric"))
+ if (compname && strcmp (compname, "i;ascii-numeric"))
{
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
/* TRANSLATORS: Do not translate ':count'.
It is the name of a Sieve tag */
_("comparator %s is incompatible with "
":count in call to `%s'"),
- comp->arg->v.string,
- name);
+ compname,
+ mach->identifier);
mu_i_sv_error (mach);
return 1;
}
matchtype = MU_SIEVE_MATCH_LAST; /* to not leave it undefined */
+ compname = "false";
compfun = comp_false;
- if (mu_list_get (args, 1, (void**) &val))
- return 1; /* shouldn't happen */
- /* NOTE: Type of v is always SVT_STRING_LIST */
- mu_list_count (val->v.list, &count);
- if (count > 1)
+ val = mu_sieve_get_arg_untyped (mach, 1);
+ /* NOTE: Type of val is always SVT_STRING_LIST */
+ if (val->type != SVT_STRING_LIST)
+ abort ();
+ if (val->v.list.count > 1)
{
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
_("second argument must be a list of one element"));
mu_i_sv_error (mach);
return 1;
}
- mu_list_get (val->v.list, 0, (void **) &str);
+ str = mu_sieve_string_raw (mach, &val->v.list, 0)->orig;
count = strtoul (str, &str, 10);
if (*str)
{
@@ -316,72 +263,32 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach,
{
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
_("invalid relational match `%s' in call to `%s'"),
- str, name);
+ str, mach->identifier);
mu_i_sv_error (mach);
return 1;
}
}
-
+ else
+ abort ();//FIXME
+
if (!compfun)
{
- compname = comp ? comp->arg->v.string : "i;ascii-casemap";
+ if (!compname)
+ compname = "i;ascii-casemap";
compfun = mu_sieve_comparator_lookup (mach, compname, matchtype);
if (!compfun)
{
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
_("comparator `%s' is incompatible with match type `%s' in call to `%s'"),
- compname, match ? match->tag : "is", name);
+ compname, match ? match->tag : "is",
+ mach->identifier);
mu_i_sv_error (mach);
return 1;
}
}
- tmp = mu_sieve_malloc (mach, sizeof (*tmp));
- tmp->tag = TAG_COMPFUN;
- tmp->arg = mu_sieve_value_create (mach, SVT_POINTER, compfun);
- mu_list_append (tags, tmp);
+ mach->comparator = compfun;
- if (matchtype == MU_SIEVE_MATCH_REGEX)
- {
- /* To speed up things, compile all patterns at once.
- Notice that it is supposed that patterns are in arg 2 */
- mu_sieve_value_t *val, *newval;
- struct regex_data rd;
- int rc;
-
- if (mu_list_get (args, 1, (void**)&val))
- return 0;
-
- rd.mach = mach;
- rd.flags = REG_EXTENDED;
- if (strcmp (compname, "i;ascii-casemap") == 0)
- rd.flags |= REG_ICASE;
-
- mu_list_create (&rd.list);
-
- rc = mu_sieve_vlist_do (val, _regex_compile, &rd);
-
- mu_sieve_machine_add_destructor (rd.mach, _free_reglist, rd.list);
-
- if (rc)
- return rc;
- newval = mu_sieve_value_create (rd.mach, SVT_STRING_LIST, rd.list);
- mu_list_replace (args, val, newval);
- }
-#ifndef FNM_CASEFOLD
- else if (matchtype == MU_SIEVE_MATCH_MATCHES
- && strcmp (compname, "i;ascii-casemap") == 0)
- {
- int rc;
- mu_sieve_value_t *val;
-
- if (mu_list_get (args, 1, (void**)&val))
- return 0;
- rc = mu_sieve_vlist_do (val, _pattern_upcase, NULL);
- if (rc)
- return rc;
- }
-#endif
return 0;
}
@@ -390,85 +297,88 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach,
/* :comparator i;octet */
static int
-i_octet_is (const char *pattern, const char *text)
+i_octet_is (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
+ const char *text)
{
- return strcmp (pattern, text) == 0;
+ return strcmp (pattern->orig, text) == 0;
}
static int
-i_octet_contains (const char *pattern, const char *text)
+i_octet_contains (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
+ const char *text)
{
- return strstr (text, pattern) != NULL;
+ return strstr (text, pattern->orig) != NULL;
}
static int
-i_octet_matches (const char *pattern, const char *text)
+i_octet_matches (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
+ const char *text)
{
- return fnmatch (pattern, text, 0) == 0;
+ return fnmatch (pattern->orig, text, 0) == 0;
}
static int
-i_octet_regex (const char *pattern, const char *text)
+i_octet_regex (mu_sieve_machine_t mach, mu_sieve_string_t *pattern,
+ const char *text)
{
- return regexec ((regex_t *) pattern, text, 0, NULL, 0) == 0;
+ compile_pattern (mach, pattern, 0);
+ return regexec ((regex_t *)pattern->rx, text, 0, NULL, 0) == 0;
}
static int
-i_octet_eq (const char *pattern, const char *text)
+i_octet_eq (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
- return strcmp (text, pattern);
+ return strcmp (text, pattern->orig);
}
/* :comparator i;ascii-casemap */
static int
-i_ascii_casemap_is (const char *pattern, const char *text)
+i_ascii_casemap_is (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
- return mu_c_strcasecmp (pattern, text) == 0;
+ return mu_c_strcasecmp (pattern->orig, text) == 0;
}
static int
-i_ascii_casemap_contains (const char *pattern, const char *text)
+i_ascii_casemap_contains (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
- return mu_c_strcasestr (text, pattern) != NULL;
+ return mu_c_strcasestr (text, pattern->orig) != NULL;
}
static int
-i_ascii_casemap_matches (const char *pattern, const char *text)
+i_ascii_casemap_matches (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
-#ifdef FNM_CASEFOLD
- return fnmatch (pattern, text, FNM_CASEFOLD) == 0;
-#else
- int rc;
- char *p = strdup (text);
- if (!p)
- return 0;
- _pattern_upcase (p, NULL);
- rc = fnmatch (pattern, p, 0) == 0;
- free (p);
- return rc;
-#endif
+ return fnmatch (pattern->orig, text, FNM_CASEFOLD) == 0;
}
static int
-i_ascii_casemap_regex (const char *pattern, const char *text)
+i_ascii_casemap_regex (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
- return regexec ((regex_t *) pattern, text, 0, NULL, 0) == 0;
+ compile_pattern (mach, pattern, REG_ICASE);
+ return regexec ((regex_t *) pattern->rx, text, 0, NULL, 0) == 0;
}
static int
-i_ascii_casemap_eq (const char *pattern, const char *text)
+i_ascii_casemap_eq (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
- return mu_c_strcasecmp (text, pattern);
+ return mu_c_strcasecmp (text, pattern->orig);
}
/* :comparator i;ascii-numeric */
static int
-i_ascii_numeric_is (const char *pattern, const char *text)
+i_ascii_numeric_is (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
- if (mu_isdigit (*pattern))
+ if (mu_isdigit (*pattern->orig))
{
if (mu_isdigit (*text))
- return strtol (pattern, NULL, 10) == strtol (text, NULL, 10);
+ //FIXME: Error checking
+ return strtol (pattern->orig, NULL, 10) == strtol (text, NULL, 10);
else
return 0;
}
@@ -479,13 +389,14 @@ i_ascii_numeric_is (const char *pattern, const char *text)
}
static int
-i_ascii_numeric_eq (const char *pattern, const char *text)
+i_ascii_numeric_eq (mu_sieve_machine_t mach,
+ mu_sieve_string_t *pattern, const char *text)
{
- if (mu_isdigit (*pattern))
+ if (mu_isdigit (*pattern->orig))
{
if (mu_isdigit (*text))
{
- size_t a = strtoul (pattern, NULL, 10);
+ size_t a = strtoul (pattern->orig, NULL, 10);
size_t b = strtoul (text, NULL, 10);
if (b > a)
return 1;
diff --git a/libmu_sieve/extensions/editheader.c b/libmu_sieve/extensions/editheader.c
index 52c745eb4..3ef017f0d 100644
--- a/libmu_sieve/extensions/editheader.c
+++ b/libmu_sieve/extensions/editheader.c
@@ -81,7 +81,6 @@ sieve_deleteheader (mu_sieve_machine_t mach)
{
mu_sieve_value_t *val;
const char *field_name;
- const char *field_pattern;
mu_message_t msg;
mu_header_t hdr;
int rc;
@@ -91,41 +90,9 @@ sieve_deleteheader (mu_sieve_machine_t mach)
mu_sieve_get_arg (mach, 0, SVT_STRING, &field_name);
val = mu_sieve_get_arg_optional (mach, 1);
- if (!val)
- {
- field_pattern = NULL;
- mu_sieve_log_action (mach, "DELETEHEADER", "%s", field_name);
- }
- else
- {
- switch (val->type)
- {
- case SVT_STRING_LIST:
- if (mu_list_get (val->v.list, 0, (void**)&field_pattern))
- {
- mu_sieve_error (mach, "%lu: %s",
- (unsigned long) mu_sieve_get_message_num (mach),
- _("cannot get list item"));
- mu_sieve_abort (mach);
- }
- mu_sieve_log_action (mach, "DELETEHEADER", "%s: (regexp)",
- field_name);
- break;
-
- case SVT_STRING:
- field_pattern = val->v.string;
- mu_sieve_log_action (mach, "DELETEHEADER", "%s: %s", field_name,
- field_pattern);
- break;
-
- default:
- mu_sieve_error (mach, "%lu: %s: %d",
- (unsigned long) mu_sieve_get_message_num (mach),
- _("unexpected value type"), val->type);
- mu_sieve_abort (mach);
-
- }
- }
+
+ mu_sieve_log_action (mach, "DELETEHEADER", "%s%s", field_name,
+ val ? " (values)" : "" );
if (mu_sieve_is_dry_run (mach))
return 0;
@@ -141,7 +108,14 @@ sieve_deleteheader (mu_sieve_machine_t mach)
mu_sieve_abort (mach);
}
- mu_header_get_iterator (hdr, &itr);
+ rc = mu_header_get_iterator (hdr, &itr);
+ if (rc)
+ {
+ mu_sieve_error (mach, "mu_header_get_iterator: %s",
+ mu_strerror (rc));
+ mu_sieve_abort (mach);
+ }
+
if (mu_sieve_get_tag (mach, "last", SVT_VOID, NULL))
{
int backwards = 1;
@@ -162,10 +136,18 @@ sieve_deleteheader (mu_sieve_machine_t mach)
if (idx && ++i < idx)
continue;
- if (field_pattern)
+ if (val)
{
- if (comp (field_pattern, fv))
- mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
+ for (i = 0; i < val->v.list.count; i++)
+ {
+ mu_sieve_string_t *s = mu_sieve_string_raw (mach,
+ &val->v.list, i);
+ if (comp (mach, s, fv))
+ {
+ mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
+ break;
+ }
+ }
}
else
mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
diff --git a/libmu_sieve/extensions/list.c b/libmu_sieve/extensions/list.c
index 71696c6ec..3a64e0a69 100644
--- a/libmu_sieve/extensions/list.c
+++ b/libmu_sieve/extensions/list.c
@@ -159,7 +159,7 @@ list_test (mu_sieve_machine_t mach)
h = mu_sieve_get_arg_untyped (mach, 0);
v = mu_sieve_get_arg_untyped (mach, 1);
mu_message_get_header (mu_sieve_get_message (mach), &clos.header);
- result = mu_sieve_vlist_compare (h, v, comp,
+ result = mu_sieve_vlist_compare (mach, h, v, comp,
mu_sieve_get_relcmp (mach),
list_retrieve_header,
&clos, NULL) > 0;
diff --git a/libmu_sieve/extensions/vacation.c b/libmu_sieve/extensions/vacation.c
index 989a87a8e..fa19c8785 100644
--- a/libmu_sieve/extensions/vacation.c
+++ b/libmu_sieve/extensions/vacation.c
@@ -161,8 +161,8 @@ _compare (void *item, void *data)
of the originating mail. Return non-zero if so and store a pointer
to the matching address in *MY_ADDRESS. */
static int
-match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses,
- char const **my_address)
+match_addresses (mu_sieve_machine_t mach, mu_header_t hdr, char *email,
+ mu_sieve_value_t *addresses, char const **my_address)
{
int match = 0;
const char *str;
@@ -176,7 +176,7 @@ match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses,
if (_compare (email, &ad))
match = 1;
else if (addresses)
- match += mu_sieve_vlist_do (addresses, _compare, &ad);
+ match += mu_sieve_vlist_do (mach, addresses, _compare, &ad);
mu_address_destroy (&ad.addr);
}
}
@@ -188,7 +188,7 @@ match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses,
if (_compare (email, &ad))
match = 1;
else if (addresses)
- match += mu_sieve_vlist_do (addresses, _compare, &ad);
+ match += mu_sieve_vlist_do (mach, addresses, _compare, &ad);
mu_address_destroy (&ad.addr);
}
}
@@ -249,8 +249,8 @@ noreply_address_p (mu_sieve_machine_t mach, char *email)
for (i = 0; rc == 0 && noreply_sender[i]; i++)
rc = regex_comparator (noreply_sender[i], &rd);
- if (!rc && mu_sieve_get_tag_untyped (mach, "noreply", &arg))
- rc = mu_sieve_vlist_do (arg, regex_comparator, &rd);
+ if (!rc && (arg = mu_sieve_get_tag_untyped (mach, "noreply")) != NULL)
+ rc = mu_sieve_vlist_do (mach, arg, regex_comparator, &rd);
return rc;
}
@@ -716,12 +716,13 @@ vacation_reply (mu_sieve_machine_t mach, mu_message_t msg,
{
mu_header_set_value (newhdr, MU_HEADER_TO, to, 0);
- if (mu_sieve_get_tag_untyped (mach, "header", &val))
+ val = mu_sieve_get_tag_untyped (mach, "header");
+ if (val)
{
struct header_closure hc;
hc.mach = mach;
hc.hdr = newhdr;
- mu_sieve_vlist_do (val, add_header, &hc);
+ mu_sieve_vlist_do (mach, val, add_header, &hc);
}
vacation_subject (mach, msg, newhdr);
@@ -807,9 +808,8 @@ sieve_action_vacation (mu_sieve_machine_t mach)
return_address = my_address;
else
{
- mu_sieve_value_t *val = NULL;
- mu_sieve_get_tag_untyped (mach, "aliases", &val);
- if (match_addresses (hdr, my_address, val, &return_address) == 0)
+ mu_sieve_value_t *val = mu_sieve_get_tag_untyped (mach, "aliases");
+ if (match_addresses (mach, hdr, my_address, val, &return_address) == 0)
{
free (my_address);
return 0;
diff --git a/libmu_sieve/mem.c b/libmu_sieve/mem.c
index f03b06dd5..25dc26c5b 100644
--- a/libmu_sieve/mem.c
+++ b/libmu_sieve/mem.c
@@ -196,11 +196,42 @@ mu_sieve_reclaim_value (void *p)
/* For now, the same as _default. Will change in the future */
free (p);
}
-
+
+/* Based on gnulib's x2nrealloc */
void
-mu_sieve_reclaim_tag (void *p)
+mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb,
+ size_t size)
{
- mu_sieve_runtime_tag_t *tag = p;
- mu_sieve_reclaim_value (tag->arg);
-}
+ void *ptr = *pptr;
+ size_t nmemb = *pnmemb;
+
+ if (!ptr)
+ {
+ if (!nmemb)
+ {
+ /* Initial allocation size */
+ nmemb = 16;
+ }
+ }
+ else
+ {
+ /* Set NMEMB = floor (1.5 * NMEMB) + 1 so that progress is made even
+ if NMEMB == 0.
+ Check for overflow, so that NMEMB * SIZE stays in size_t range.
+ The check may be slightly conservative, but an exact check isn't
+ worth the trouble. */
+ if ((size_t) -1 / 3 * 2 / size <= nmemb)
+ {
+ mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
+ _("requested too much memory %zu * %zu"),
+ nmemb, size);
+ mu_sieve_abort (mach);
+ }
+ nmemb += nmemb / 2 + 1;
+ }
+ ptr = mu_sieve_realloc (mach, ptr, nmemb * size);
+
+ *pptr = ptr;
+ *pnmemb = nmemb;
+}
diff --git a/libmu_sieve/prog.c b/libmu_sieve/prog.c
index 8c6bc6d8e..17b65870f 100644
--- a/libmu_sieve/prog.c
+++ b/libmu_sieve/prog.c
@@ -24,25 +24,15 @@
#include <assert.h>
#include <sieve-priv.h>
-int
+void
mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op)
{
if (mach->pc >= mach->progsize)
{
- size_t newsize = mach->progsize + SIEVE_CODE_INCR;
- sieve_op_t *newprog =
- mu_sieve_realloc (mach, mach->prog, newsize * sizeof mach->prog[0]);
- if (!newprog)