sieve: change string allocation and argument passing convention
Strings are allocated in a per-machine string space. String and argument lists form contiguous arrays of structures. Regular ex- pressions are compiled when they are needed. Compiled expressions are cached for eventual reuse.
Showing
20 changed files
with
313 additions
and
220 deletions
... | @@ -95,7 +95,7 @@ numaddr_test (mu_sieve_machine_t mach) | ... | @@ -95,7 +95,7 @@ numaddr_test (mu_sieve_machine_t mach) |
95 | vc.count = 0; | 95 | vc.count = 0; |
96 | 96 | ||
97 | /* Count the addresses */ | 97 | /* Count the addresses */ |
98 | rc = mu_sieve_vlist_do (h, _count_items, &vc); | 98 | rc = mu_sieve_vlist_do (mach, h, _count_items, &vc); |
99 | 99 | ||
100 | /* Here rc >= 1 iff the counted number of addresses is greater or equal | 100 | /* Here rc >= 1 iff the counted number of addresses is greater or equal |
101 | to vc.limit. If `:under' tag was given we reverse the return value */ | 101 | to vc.limit. If `:under' tag was given we reverse the return value */ | ... | ... |
... | @@ -33,6 +33,13 @@ extern "C" { | ... | @@ -33,6 +33,13 @@ extern "C" { |
33 | 33 | ||
34 | typedef struct mu_sieve_machine *mu_sieve_machine_t; | 34 | typedef struct mu_sieve_machine *mu_sieve_machine_t; |
35 | 35 | ||
36 | typedef struct mu_sieve_string | ||
37 | { | ||
38 | char *orig; | ||
39 | char *exp; | ||
40 | void *rx; | ||
41 | } mu_sieve_string_t; | ||
42 | |||
36 | typedef int (*mu_sieve_handler_t) (mu_sieve_machine_t mach); | 43 | typedef int (*mu_sieve_handler_t) (mu_sieve_machine_t mach); |
37 | typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t mach, | 44 | typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t mach, |
38 | const char *action, | 45 | const char *action, |
... | @@ -40,13 +47,12 @@ typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t mach, | ... | @@ -40,13 +47,12 @@ typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t mach, |
40 | 47 | ||
41 | typedef int (*mu_sieve_relcmp_t) (int, int); | 48 | typedef int (*mu_sieve_relcmp_t) (int, int); |
42 | typedef int (*mu_sieve_relcmpn_t) (size_t, size_t); | 49 | typedef int (*mu_sieve_relcmpn_t) (size_t, size_t); |
43 | typedef int (*mu_sieve_comparator_t) (const char *, const char *); | 50 | typedef int (*mu_sieve_comparator_t) (mu_sieve_machine_t mach, |
51 | mu_sieve_string_t *, const char *); | ||
44 | typedef int (*mu_sieve_retrieve_t) (void *item, void *data, int idx, | 52 | typedef int (*mu_sieve_retrieve_t) (void *item, void *data, int idx, |
45 | char **pval); | 53 | char **pval); |
46 | typedef void (*mu_sieve_destructor_t) (void *data); | 54 | typedef void (*mu_sieve_destructor_t) (void *data); |
47 | typedef int (*mu_sieve_tag_checker_t) (mu_sieve_machine_t mach, | 55 | typedef int (*mu_sieve_tag_checker_t) (mu_sieve_machine_t mach); |
48 | const char *name, | ||
49 | mu_list_t tags, mu_list_t args); | ||
50 | 56 | ||
51 | typedef enum | 57 | typedef enum |
52 | { | 58 | { |
... | @@ -55,24 +61,29 @@ typedef enum | ... | @@ -55,24 +61,29 @@ typedef enum |
55 | SVT_STRING, | 61 | SVT_STRING, |
56 | SVT_STRING_LIST, | 62 | SVT_STRING_LIST, |
57 | SVT_TAG, | 63 | SVT_TAG, |
58 | SVT_IDENT, | 64 | SVT_IDENT |
59 | SVT_POINTER | ||
60 | } | 65 | } |
61 | mu_sieve_data_type; | 66 | mu_sieve_data_type; |
62 | 67 | ||
63 | typedef struct mu_sieve_runtime_tag mu_sieve_runtime_tag_t; | 68 | struct mu_sieve_slice |
69 | { | ||
70 | size_t first; | ||
71 | size_t count; | ||
72 | }; | ||
73 | |||
74 | typedef struct mu_sieve_slice *mu_sieve_slice_t; | ||
64 | 75 | ||
65 | union mu_sieve_value_storage | 76 | union mu_sieve_value_storage |
66 | { | 77 | { |
67 | char *string; | 78 | char *string; |
68 | size_t number; | 79 | size_t number; |
69 | mu_list_t list; | 80 | struct mu_sieve_slice list; |
70 | void *ptr; | ||
71 | }; | 81 | }; |
72 | 82 | ||
73 | typedef struct | 83 | typedef struct |
74 | { | 84 | { |
75 | mu_sieve_data_type type; | 85 | mu_sieve_data_type type; |
86 | char *tag; | ||
76 | union mu_sieve_value_storage v; | 87 | union mu_sieve_value_storage v; |
77 | } mu_sieve_value_t; | 88 | } mu_sieve_value_t; |
78 | 89 | ||
... | @@ -88,12 +99,6 @@ typedef struct | ... | @@ -88,12 +99,6 @@ typedef struct |
88 | mu_sieve_tag_checker_t checker; | 99 | mu_sieve_tag_checker_t checker; |
89 | } mu_sieve_tag_group_t; | 100 | } mu_sieve_tag_group_t; |
90 | 101 | ||
91 | struct mu_sieve_runtime_tag | ||
92 | { | ||
93 | char *tag; | ||
94 | mu_sieve_value_t *arg; | ||
95 | }; | ||
96 | |||
97 | typedef struct | 102 | typedef struct |
98 | { | 103 | { |
99 | const char *name; | 104 | const char *name; |
... | @@ -135,11 +140,9 @@ void *mu_sieve_realloc (mu_sieve_machine_t mach, void *ptr, size_t size); | ... | @@ -135,11 +140,9 @@ void *mu_sieve_realloc (mu_sieve_machine_t mach, void *ptr, size_t size); |
135 | void mu_sieve_reclaim_default (void *p); | 140 | void mu_sieve_reclaim_default (void *p); |
136 | void mu_sieve_reclaim_list (void *p); | 141 | void mu_sieve_reclaim_list (void *p); |
137 | void mu_sieve_reclaim_value (void *p); | 142 | void mu_sieve_reclaim_value (void *p); |
138 | void mu_sieve_reclaim_tag (void *p); | ||
139 | 143 | ||
140 | mu_sieve_value_t *mu_sieve_value_create (mu_sieve_machine_t mach, | 144 | size_t mu_sieve_value_create (mu_sieve_machine_t mach, |
141 | mu_sieve_data_type type, void *data); | 145 | mu_sieve_data_type type, void *data); |
142 | void mu_sieve_slist_destroy (mu_list_t *plist); | ||
143 | 146 | ||
144 | /* Symbol space functions */ | 147 | /* Symbol space functions */ |
145 | mu_sieve_register_t *mu_sieve_test_lookup (mu_sieve_machine_t mach, | 148 | 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, | ... | @@ -185,30 +188,41 @@ int mu_sieve_str_to_relcmp (const char *str, mu_sieve_relcmp_t *test, |
185 | mu_sieve_relcmpn_t *stest); | 188 | mu_sieve_relcmpn_t *stest); |
186 | mu_sieve_relcmp_t mu_sieve_get_relcmp (mu_sieve_machine_t mach); | 189 | mu_sieve_relcmp_t mu_sieve_get_relcmp (mu_sieve_machine_t mach); |
187 | 190 | ||
188 | void mu_sieve_require (mu_sieve_machine_t mach, mu_list_t slist); | 191 | void mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list); |
189 | 192 | ||
193 | void mu_sieve_value_get (mu_sieve_machine_t mach, mu_sieve_value_t *val, | ||
194 | mu_sieve_data_type type, void *ret); | ||
195 | |||
190 | int mu_sieve_get_tag (mu_sieve_machine_t mach, char *name, | 196 | int mu_sieve_get_tag (mu_sieve_machine_t mach, char *name, |
191 | mu_sieve_data_type type, void *ret); | 197 | mu_sieve_data_type type, void *ret); |
192 | int mu_sieve_get_tag_untyped (mu_sieve_machine_t mach, | 198 | mu_sieve_value_t *mu_sieve_get_tag_untyped (mu_sieve_machine_t mach, |
193 | char *name, mu_sieve_value_t **ret); | 199 | char const *name); |
200 | mu_sieve_value_t *mu_sieve_get_tag_n (mu_sieve_machine_t mach, size_t n); | ||
194 | 201 | ||
195 | int mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name); | 202 | int mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name); |
196 | int mu_sieve_match_part_checker (mu_sieve_machine_t mach, | 203 | int mu_sieve_match_part_checker (mu_sieve_machine_t mach); |
197 | const char *name, mu_list_t tags, | 204 | |
198 | mu_list_t args); | ||
199 | int mu_sieve_match_part_checker (mu_sieve_machine_t mach, | ||
200 | const char *name, mu_list_t tags, | ||
201 | mu_list_t args); | ||
202 | /* Operations on value lists */ | 205 | /* Operations on value lists */ |
203 | mu_sieve_value_t *mu_sieve_get_arg_optional (mu_sieve_machine_t mach, | 206 | mu_sieve_value_t *mu_sieve_get_arg_optional (mu_sieve_machine_t mach, |
204 | size_t index); | 207 | size_t index); |
205 | mu_sieve_value_t *mu_sieve_get_arg_untyped (mu_sieve_machine_t mach, | 208 | mu_sieve_value_t *mu_sieve_get_arg_untyped (mu_sieve_machine_t mach, |
206 | size_t index); | 209 | size_t index); |
207 | int mu_sieve_get_arg (mu_sieve_machine_t mach, size_t index, | 210 | void mu_sieve_get_arg (mu_sieve_machine_t mach, size_t index, |
208 | mu_sieve_data_type type, void *ret); | 211 | mu_sieve_data_type type, void *ret); |
209 | int mu_sieve_vlist_do (mu_sieve_value_t *val, mu_list_action_t ac, | 212 | |
213 | char *mu_sieve_string (mu_sieve_machine_t mach, | ||
214 | mu_sieve_slice_t slice, | ||
215 | size_t i); | ||
216 | struct mu_sieve_string *mu_sieve_string_raw (mu_sieve_machine_t mach, | ||
217 | mu_sieve_slice_t slice, | ||
218 | size_t i); | ||
219 | |||
220 | |||
221 | int mu_sieve_vlist_do (mu_sieve_machine_t mach, | ||
222 | mu_sieve_value_t *val, mu_list_action_t ac, | ||
210 | void *data); | 223 | void *data); |
211 | int mu_sieve_vlist_compare (mu_sieve_value_t *a, mu_sieve_value_t *b, | 224 | int mu_sieve_vlist_compare (mu_sieve_machine_t mach, |
225 | mu_sieve_value_t *a, mu_sieve_value_t *b, | ||
212 | mu_sieve_comparator_t comp, | 226 | mu_sieve_comparator_t comp, |
213 | mu_sieve_relcmp_t test, mu_sieve_retrieve_t ac, | 227 | mu_sieve_relcmp_t test, mu_sieve_retrieve_t ac, |
214 | void *data, size_t *count); | 228 | void *data, size_t *count); | ... | ... |
... | @@ -42,6 +42,7 @@ libmu_sieve_la_SOURCES = \ | ... | @@ -42,6 +42,7 @@ libmu_sieve_la_SOURCES = \ |
42 | sieve-gram.h\ | 42 | sieve-gram.h\ |
43 | sieve-lex.c\ | 43 | sieve-lex.c\ |
44 | strexp.c\ | 44 | strexp.c\ |
45 | string.c\ | ||
45 | tests.c\ | 46 | tests.c\ |
46 | util.c | 47 | util.c |
47 | libmu_sieve_la_LIBADD = ${MU_LIB_MAILUTILS} @LTDL_LIB@ | 48 | libmu_sieve_la_LIBADD = ${MU_LIB_MAILUTILS} @LTDL_LIB@ | ... | ... |
... | @@ -511,24 +511,22 @@ mu_sieve_data_type fileinto_args[] = { | ... | @@ -511,24 +511,22 @@ mu_sieve_data_type fileinto_args[] = { |
511 | }; | 511 | }; |
512 | 512 | ||
513 | static int | 513 | static int |
514 | perms_tag_checker (mu_sieve_machine_t mach, | 514 | perms_tag_checker (mu_sieve_machine_t mach) |
515 | const char *name, mu_list_t tags, mu_list_t args) | ||
516 | { | 515 | { |
517 | mu_iterator_t itr; | 516 | size_t i; |
518 | int err = 0; | 517 | int err = 0; |
519 | 518 | ||
520 | if (!tags || mu_list_get_iterator (tags, &itr)) | 519 | if (mach->tagcount == 0) |
521 | return 0; | 520 | return 0; |
522 | for (mu_iterator_first (itr); !err && !mu_iterator_is_done (itr); | 521 | for (i = 0; i < mach->tagcount; i++) |
523 | mu_iterator_next (itr)) | ||
524 | { | 522 | { |
525 | int flag; | 523 | int flag; |
526 | const char *p; | 524 | const char *p; |
527 | mu_sieve_runtime_tag_t *t; | 525 | mu_sieve_value_t *t = mu_sieve_get_tag_n (mach, i); |
528 | mu_iterator_current (itr, (void **)&t); | 526 | |
529 | if (strcmp (t->tag, "permissions") == 0) | 527 | if (strcmp (t->tag, "permissions") == 0) |
530 | { | 528 | { |
531 | if (mu_parse_stream_perm_string (&flag, t->arg->v.string, &p)) | 529 | if (mu_parse_stream_perm_string (&flag, t->v.string, &p)) |
532 | { | 530 | { |
533 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, | 531 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, |
534 | _("invalid permissions (near %s)"), p); | 532 | _("invalid permissions (near %s)"), p); |
... | @@ -537,7 +535,6 @@ perms_tag_checker (mu_sieve_machine_t mach, | ... | @@ -537,7 +535,6 @@ perms_tag_checker (mu_sieve_machine_t mach, |
537 | } | 535 | } |
538 | } | 536 | } |
539 | } | 537 | } |
540 | mu_iterator_destroy (&itr); | ||
541 | return err; | 538 | return err; |
542 | } | 539 | } |
543 | 540 | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -81,7 +81,6 @@ sieve_deleteheader (mu_sieve_machine_t mach) | ... | @@ -81,7 +81,6 @@ sieve_deleteheader (mu_sieve_machine_t mach) |
81 | { | 81 | { |
82 | mu_sieve_value_t *val; | 82 | mu_sieve_value_t *val; |
83 | const char *field_name; | 83 | const char *field_name; |
84 | const char *field_pattern; | ||
85 | mu_message_t msg; | 84 | mu_message_t msg; |
86 | mu_header_t hdr; | 85 | mu_header_t hdr; |
87 | int rc; | 86 | int rc; |
... | @@ -91,41 +90,9 @@ sieve_deleteheader (mu_sieve_machine_t mach) | ... | @@ -91,41 +90,9 @@ sieve_deleteheader (mu_sieve_machine_t mach) |
91 | 90 | ||
92 | mu_sieve_get_arg (mach, 0, SVT_STRING, &field_name); | 91 | mu_sieve_get_arg (mach, 0, SVT_STRING, &field_name); |
93 | val = mu_sieve_get_arg_optional (mach, 1); | 92 | val = mu_sieve_get_arg_optional (mach, 1); |
94 | if (!val) | 93 | |
95 | { | 94 | mu_sieve_log_action (mach, "DELETEHEADER", "%s%s", field_name, |
96 | field_pattern = NULL; | 95 | val ? " (values)" : "" ); |
97 | mu_sieve_log_action (mach, "DELETEHEADER", "%s", field_name); | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | switch (val->type) | ||
102 | { | ||
103 | case SVT_STRING_LIST: | ||
104 | if (mu_list_get (val->v.list, 0, (void**)&field_pattern)) | ||
105 | { | ||
106 | mu_sieve_error (mach, "%lu: %s", | ||
107 | (unsigned long) mu_sieve_get_message_num (mach), | ||
108 | _("cannot get list item")); | ||
109 | mu_sieve_abort (mach); | ||
110 | } | ||
111 | mu_sieve_log_action (mach, "DELETEHEADER", "%s: (regexp)", | ||
112 | field_name); | ||
113 | break; | ||
114 | |||
115 | case SVT_STRING: | ||
116 | field_pattern = val->v.string; | ||
117 | mu_sieve_log_action (mach, "DELETEHEADER", "%s: %s", field_name, | ||
118 | field_pattern); | ||
119 | break; | ||
120 | |||
121 | default: | ||
122 | mu_sieve_error (mach, "%lu: %s: %d", | ||
123 | (unsigned long) mu_sieve_get_message_num (mach), | ||
124 | _("unexpected value type"), val->type); | ||
125 | mu_sieve_abort (mach); | ||
126 | |||
127 | } | ||
128 | } | ||
129 | 96 | ||
130 | if (mu_sieve_is_dry_run (mach)) | 97 | if (mu_sieve_is_dry_run (mach)) |
131 | return 0; | 98 | return 0; |
... | @@ -141,7 +108,14 @@ sieve_deleteheader (mu_sieve_machine_t mach) | ... | @@ -141,7 +108,14 @@ sieve_deleteheader (mu_sieve_machine_t mach) |
141 | mu_sieve_abort (mach); | 108 | mu_sieve_abort (mach); |
142 | } | 109 | } |
143 | 110 | ||
144 | mu_header_get_iterator (hdr, &itr); | 111 | rc = mu_header_get_iterator (hdr, &itr); |
112 | if (rc) | ||
113 | { | ||
114 | mu_sieve_error (mach, "mu_header_get_iterator: %s", | ||
115 | mu_strerror (rc)); | ||
116 | mu_sieve_abort (mach); | ||
117 | } | ||
118 | |||
145 | if (mu_sieve_get_tag (mach, "last", SVT_VOID, NULL)) | 119 | if (mu_sieve_get_tag (mach, "last", SVT_VOID, NULL)) |
146 | { | 120 | { |
147 | int backwards = 1; | 121 | int backwards = 1; |
... | @@ -162,10 +136,18 @@ sieve_deleteheader (mu_sieve_machine_t mach) | ... | @@ -162,10 +136,18 @@ sieve_deleteheader (mu_sieve_machine_t mach) |
162 | if (idx && ++i < idx) | 136 | if (idx && ++i < idx) |
163 | continue; | 137 | continue; |
164 | 138 | ||
165 | if (field_pattern) | 139 | if (val) |
166 | { | 140 | { |
167 | if (comp (field_pattern, fv)) | 141 | for (i = 0; i < val->v.list.count; i++) |
168 | mu_iterator_ctl (itr, mu_itrctl_delete, NULL); | 142 | { |
143 | mu_sieve_string_t *s = mu_sieve_string_raw (mach, | ||
144 | &val->v.list, i); | ||
145 | if (comp (mach, s, fv)) | ||
146 | { | ||
147 | mu_iterator_ctl (itr, mu_itrctl_delete, NULL); | ||
148 | break; | ||
149 | } | ||
150 | } | ||
169 | } | 151 | } |
170 | else | 152 | else |
171 | mu_iterator_ctl (itr, mu_itrctl_delete, NULL); | 153 | mu_iterator_ctl (itr, mu_itrctl_delete, NULL); | ... | ... |
... | @@ -159,7 +159,7 @@ list_test (mu_sieve_machine_t mach) | ... | @@ -159,7 +159,7 @@ list_test (mu_sieve_machine_t mach) |
159 | h = mu_sieve_get_arg_untyped (mach, 0); | 159 | h = mu_sieve_get_arg_untyped (mach, 0); |
160 | v = mu_sieve_get_arg_untyped (mach, 1); | 160 | v = mu_sieve_get_arg_untyped (mach, 1); |
161 | mu_message_get_header (mu_sieve_get_message (mach), &clos.header); | 161 | mu_message_get_header (mu_sieve_get_message (mach), &clos.header); |
162 | result = mu_sieve_vlist_compare (h, v, comp, | 162 | result = mu_sieve_vlist_compare (mach, h, v, comp, |
163 | mu_sieve_get_relcmp (mach), | 163 | mu_sieve_get_relcmp (mach), |
164 | list_retrieve_header, | 164 | list_retrieve_header, |
165 | &clos, NULL) > 0; | 165 | &clos, NULL) > 0; | ... | ... |
... | @@ -161,8 +161,8 @@ _compare (void *item, void *data) | ... | @@ -161,8 +161,8 @@ _compare (void *item, void *data) |
161 | of the originating mail. Return non-zero if so and store a pointer | 161 | of the originating mail. Return non-zero if so and store a pointer |
162 | to the matching address in *MY_ADDRESS. */ | 162 | to the matching address in *MY_ADDRESS. */ |
163 | static int | 163 | static int |
164 | match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses, | 164 | match_addresses (mu_sieve_machine_t mach, mu_header_t hdr, char *email, |
165 | char const **my_address) | 165 | mu_sieve_value_t *addresses, char const **my_address) |
166 | { | 166 | { |
167 | int match = 0; | 167 | int match = 0; |
168 | const char *str; | 168 | const char *str; |
... | @@ -176,7 +176,7 @@ match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses, | ... | @@ -176,7 +176,7 @@ match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses, |
176 | if (_compare (email, &ad)) | 176 | if (_compare (email, &ad)) |
177 | match = 1; | 177 | match = 1; |
178 | else if (addresses) | 178 | else if (addresses) |
179 | match += mu_sieve_vlist_do (addresses, _compare, &ad); | 179 | match += mu_sieve_vlist_do (mach, addresses, _compare, &ad); |
180 | mu_address_destroy (&ad.addr); | 180 | mu_address_destroy (&ad.addr); |
181 | } | 181 | } |
182 | } | 182 | } |
... | @@ -188,7 +188,7 @@ match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses, | ... | @@ -188,7 +188,7 @@ match_addresses (mu_header_t hdr, char *email, mu_sieve_value_t *addresses, |
188 | if (_compare (email, &ad)) | 188 | if (_compare (email, &ad)) |
189 | match = 1; | 189 | match = 1; |
190 | else if (addresses) | 190 | else if (addresses) |
191 | match += mu_sieve_vlist_do (addresses, _compare, &ad); | 191 | match += mu_sieve_vlist_do (mach, addresses, _compare, &ad); |
192 | mu_address_destroy (&ad.addr); | 192 | mu_address_destroy (&ad.addr); |
193 | } | 193 | } |
194 | } | 194 | } |
... | @@ -249,8 +249,8 @@ noreply_address_p (mu_sieve_machine_t mach, char *email) | ... | @@ -249,8 +249,8 @@ noreply_address_p (mu_sieve_machine_t mach, char *email) |
249 | for (i = 0; rc == 0 && noreply_sender[i]; i++) | 249 | for (i = 0; rc == 0 && noreply_sender[i]; i++) |
250 | rc = regex_comparator (noreply_sender[i], &rd); | 250 | rc = regex_comparator (noreply_sender[i], &rd); |
251 | 251 | ||
252 | if (!rc && mu_sieve_get_tag_untyped (mach, "noreply", &arg)) | 252 | if (!rc && (arg = mu_sieve_get_tag_untyped (mach, "noreply")) != NULL) |
253 | rc = mu_sieve_vlist_do (arg, regex_comparator, &rd); | 253 | rc = mu_sieve_vlist_do (mach, arg, regex_comparator, &rd); |
254 | 254 | ||
255 | return rc; | 255 | return rc; |
256 | } | 256 | } |
... | @@ -716,12 +716,13 @@ vacation_reply (mu_sieve_machine_t mach, mu_message_t msg, | ... | @@ -716,12 +716,13 @@ vacation_reply (mu_sieve_machine_t mach, mu_message_t msg, |
716 | { | 716 | { |
717 | mu_header_set_value (newhdr, MU_HEADER_TO, to, 0); | 717 | mu_header_set_value (newhdr, MU_HEADER_TO, to, 0); |
718 | 718 | ||
719 | if (mu_sieve_get_tag_untyped (mach, "header", &val)) | 719 | val = mu_sieve_get_tag_untyped (mach, "header"); |
720 | if (val) | ||
720 | { | 721 | { |
721 | struct header_closure hc; | 722 | struct header_closure hc; |
722 | hc.mach = mach; | 723 | hc.mach = mach; |
723 | hc.hdr = newhdr; | 724 | hc.hdr = newhdr; |
724 | mu_sieve_vlist_do (val, add_header, &hc); | 725 | mu_sieve_vlist_do (mach, val, add_header, &hc); |
725 | } | 726 | } |
726 | 727 | ||
727 | vacation_subject (mach, msg, newhdr); | 728 | vacation_subject (mach, msg, newhdr); |
... | @@ -807,9 +808,8 @@ sieve_action_vacation (mu_sieve_machine_t mach) | ... | @@ -807,9 +808,8 @@ sieve_action_vacation (mu_sieve_machine_t mach) |
807 | return_address = my_address; | 808 | return_address = my_address; |
808 | else | 809 | else |
809 | { | 810 | { |
810 | mu_sieve_value_t *val = NULL; | 811 | mu_sieve_value_t *val = mu_sieve_get_tag_untyped (mach, "aliases"); |
811 | mu_sieve_get_tag_untyped (mach, "aliases", &val); | 812 | if (match_addresses (mach, hdr, my_address, val, &return_address) == 0) |
812 | if (match_addresses (hdr, my_address, val, &return_address) == 0) | ||
813 | { | 813 | { |
814 | free (my_address); | 814 | free (my_address); |
815 | return 0; | 815 | return 0; | ... | ... |
... | @@ -196,11 +196,42 @@ mu_sieve_reclaim_value (void *p) | ... | @@ -196,11 +196,42 @@ mu_sieve_reclaim_value (void *p) |
196 | /* For now, the same as _default. Will change in the future */ | 196 | /* For now, the same as _default. Will change in the future */ |
197 | free (p); | 197 | free (p); |
198 | } | 198 | } |
199 | 199 | ||
200 | /* Based on gnulib's x2nrealloc */ | ||
200 | void | 201 | void |
201 | mu_sieve_reclaim_tag (void *p) | 202 | mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb, |
203 | size_t size) | ||
202 | { | 204 | { |
203 | mu_sieve_runtime_tag_t *tag = p; | 205 | void *ptr = *pptr; |
204 | mu_sieve_reclaim_value (tag->arg); | 206 | size_t nmemb = *pnmemb; |
205 | } | 207 | |
208 | if (!ptr) | ||
209 | { | ||
210 | if (!nmemb) | ||
211 | { | ||
212 | /* Initial allocation size */ | ||
213 | nmemb = 16; | ||
214 | } | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | /* Set NMEMB = floor (1.5 * NMEMB) + 1 so that progress is made even | ||
219 | if NMEMB == 0. | ||
220 | Check for overflow, so that NMEMB * SIZE stays in size_t range. | ||
221 | The check may be slightly conservative, but an exact check isn't | ||
222 | worth the trouble. */ | ||
223 | if ((size_t) -1 / 3 * 2 / size <= nmemb) | ||
224 | { | ||
225 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, | ||
226 | _("requested too much memory %zu * %zu"), | ||
227 | nmemb, size); | ||
228 | mu_sieve_abort (mach); | ||
229 | } | ||
230 | nmemb += nmemb / 2 + 1; | ||
231 | } | ||
206 | 232 | ||
233 | ptr = mu_sieve_realloc (mach, ptr, nmemb * size); | ||
234 | |||
235 | *pptr = ptr; | ||
236 | *pnmemb = nmemb; | ||
237 | } | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -38,7 +38,8 @@ DCL(ge,>=) | ... | @@ -38,7 +38,8 @@ DCL(ge,>=) |
38 | DCL(lt,<) | 38 | DCL(lt,<) |
39 | DCL(le,<=) | 39 | DCL(le,<=) |
40 | 40 | ||
41 | static struct reltest_tab { | 41 | static struct reltest_tab |
42 | { | ||
42 | char *name; | 43 | char *name; |
43 | mu_sieve_relcmp_t test; | 44 | mu_sieve_relcmp_t test; |
44 | mu_sieve_relcmpn_t stest; | 45 | mu_sieve_relcmpn_t stest; |
... | @@ -66,7 +67,7 @@ _relcmp_lookup (const char *str) | ... | @@ -66,7 +67,7 @@ _relcmp_lookup (const char *str) |
66 | 67 | ||
67 | int | 68 | int |
68 | mu_sieve_str_to_relcmp (const char *str, | 69 | mu_sieve_str_to_relcmp (const char *str, |
69 | mu_sieve_relcmp_t *test, mu_sieve_relcmpn_t *stest) | 70 | mu_sieve_relcmp_t *test, mu_sieve_relcmpn_t *stest) |
70 | { | 71 | { |
71 | struct reltest_tab *t = _relcmp_lookup (str); | 72 | struct reltest_tab *t = _relcmp_lookup (str); |
72 | if (t) | 73 | if (t) | ... | ... |
... | @@ -27,30 +27,17 @@ | ... | @@ -27,30 +27,17 @@ |
27 | #include <sieve-priv.h> | 27 | #include <sieve-priv.h> |
28 | 28 | ||
29 | void | 29 | void |
30 | mu_sieve_require (mu_sieve_machine_t mach, mu_list_t slist) | 30 | mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list) |
31 | { | 31 | { |
32 | int status; | 32 | size_t i; |
33 | mu_iterator_t itr; | ||
34 | 33 | ||
35 | status = mu_list_get_iterator (slist, &itr); | 34 | for (i = 0; i < list->count; i++) |
36 | if (status) | ||
37 | { | 35 | { |
38 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, | 36 | struct mu_sieve_string *str = mu_sieve_string_raw (mach, list, i); |
39 | _("cannot create iterator: %s"), | 37 | char *name = str->orig; |
40 | mu_strerror (status)); | ||
41 | mu_i_sv_error (mach); | ||
42 | return; | ||
43 | } | ||
44 | |||
45 | for (mu_iterator_first (itr); | ||
46 | !mu_iterator_is_done (itr); mu_iterator_next (itr)) | ||
47 | { | ||
48 | char *name; | ||
49 | int (*reqfn) (mu_sieve_machine_t mach, const char *name) = NULL; | 38 | int (*reqfn) (mu_sieve_machine_t mach, const char *name) = NULL; |
50 | const char *text = NULL; | 39 | const char *text = NULL; |
51 | 40 | ||
52 | mu_iterator_current (itr, (void **)&name); | ||
53 | |||
54 | if (strncmp (name, "comparator-", 11) == 0) | 41 | if (strncmp (name, "comparator-", 11) == 0) |
55 | { | 42 | { |
56 | name += 11; | 43 | name += 11; |
... | @@ -87,6 +74,5 @@ mu_sieve_require (mu_sieve_machine_t mach, mu_list_t slist) | ... | @@ -87,6 +74,5 @@ mu_sieve_require (mu_sieve_machine_t mach, mu_list_t slist) |
87 | mu_i_sv_error (mach); | 74 | mu_i_sv_error (mach); |
88 | } | 75 | } |
89 | } | 76 | } |
90 | mu_iterator_destroy (&itr); | ||
91 | } | 77 | } |
92 | 78 | ... | ... |
... | @@ -24,8 +24,8 @@ | ... | @@ -24,8 +24,8 @@ |
24 | #include <assert.h> | 24 | #include <assert.h> |
25 | #include <sieve-priv.h> | 25 | #include <sieve-priv.h> |
26 | 26 | ||
27 | #define SIEVE_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t) | 27 | #define SIEVE_RT_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t) |
28 | #define SIEVE_ADJUST(m,n) (m)->pc+=(n) | 28 | #define SIEVE_RT_ADJUST(m,n) (m)->pc+=(n) |
29 | 29 | ||
30 | #define INSTR_DISASS(m) ((m)->state == mu_sieve_state_disass) | 30 | #define INSTR_DISASS(m) ((m)->state == mu_sieve_state_disass) |
31 | #define INSTR_DEBUG(m) \ | 31 | #define INSTR_DEBUG(m) \ |
... | @@ -34,49 +34,53 @@ | ... | @@ -34,49 +34,53 @@ |
34 | void | 34 | void |
35 | _mu_i_sv_instr_source (mu_sieve_machine_t mach) | 35 | _mu_i_sv_instr_source (mu_sieve_machine_t mach) |
36 | { | 36 | { |
37 | mach->locus.mu_file = (char*) SIEVE_ARG (mach, 0, string); | 37 | mach->locus.mu_file = (char*) SIEVE_RT_ARG (mach, 0, string); |
38 | mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, | 38 | mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, |
39 | MU_IOCTL_LOGSTREAM_SET_LOCUS, | 39 | MU_IOCTL_LOGSTREAM_SET_LOCUS, |
40 | &mach->locus); | 40 | &mach->locus); |
41 | if (INSTR_DEBUG (mach)) | 41 | if (INSTR_DEBUG (mach)) |
42 | mu_i_sv_debug (mach, mach->pc - 1, "SOURCE %s", mach->locus.mu_file); | 42 | mu_i_sv_debug (mach, mach->pc - 1, "SOURCE %s", mach->locus.mu_file); |
43 | SIEVE_ADJUST (mach, 1); | 43 | SIEVE_RT_ADJUST (mach, 1); |
44 | } | 44 | } |
45 | 45 | ||
46 | void | 46 | void |
47 | _mu_i_sv_instr_line (mu_sieve_machine_t mach) | 47 | _mu_i_sv_instr_line (mu_sieve_machine_t mach) |
48 | { | 48 | { |
49 | mach->locus.mu_line = SIEVE_ARG (mach, 0, line); | 49 | mach->locus.mu_line = SIEVE_RT_ARG (mach, 0, line); |
50 | mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, | 50 | mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, |
51 | MU_IOCTL_LOGSTREAM_SET_LOCUS, | 51 | MU_IOCTL_LOGSTREAM_SET_LOCUS, |
52 | &mach->locus); | 52 | &mach->locus); |
53 | if (INSTR_DEBUG (mach)) | 53 | if (INSTR_DEBUG (mach)) |
54 | mu_i_sv_debug (mach, mach->pc - 1, "LINE %u", | 54 | mu_i_sv_debug (mach, mach->pc - 1, "LINE %u", |
55 | mach->locus.mu_line); | 55 | mach->locus.mu_line); |
56 | SIEVE_ADJUST (mach, 1); | 56 | SIEVE_RT_ADJUST (mach, 1); |
57 | } | 57 | } |
58 | 58 | ||
59 | static int | 59 | static int |
60 | instr_run (mu_sieve_machine_t mach, char const *what) | 60 | instr_run (mu_sieve_machine_t mach, char const *what) |
61 | { | 61 | { |
62 | int rc = 0; | 62 | int rc = 0; |
63 | mu_sieve_handler_t han = SIEVE_ARG (mach, 0, handler); | 63 | mu_sieve_handler_t han = SIEVE_RT_ARG (mach, 0, handler); |
64 | mach->arg_list = SIEVE_ARG (mach, 1, list); | 64 | mach->argstart = SIEVE_RT_ARG (mach, 1, pc); |
65 | mach->tag_list = SIEVE_ARG (mach, 2, list); | 65 | mach->argcount = SIEVE_RT_ARG (mach, 2, pc); |
66 | mach->identifier = SIEVE_ARG (mach, 3, string); | 66 | mach->tagcount = SIEVE_RT_ARG (mach, 3, pc); |
67 | 67 | mach->identifier = SIEVE_RT_ARG (mach, 4, string); | |
68 | SIEVE_ADJUST (mach, 4); | 68 | mach->comparator = SIEVE_RT_ARG (mach, 5, comp); |
69 | |||
70 | SIEVE_RT_ADJUST (mach, 6); | ||
69 | 71 | ||
70 | if (INSTR_DEBUG (mach)) | 72 | if (INSTR_DEBUG (mach)) |
71 | mu_i_sv_debug_command (mach, mach->pc - 1, what); | 73 | mu_i_sv_debug_command (mach, mach->pc - 7, what); |
72 | else | 74 | else |
73 | mu_i_sv_trace (mach, what); | 75 | mu_i_sv_trace (mach, what); |
74 | 76 | ||
75 | if (!INSTR_DISASS (mach)) | 77 | if (!INSTR_DISASS (mach)) |
76 | rc = han (mach); | 78 | rc = han (mach); |
77 | mach->arg_list = NULL; | 79 | mach->argstart = 0; |
78 | mach->tag_list = NULL; | 80 | mach->argcount = 0; |
81 | mach->tagcount = 0; | ||
79 | mach->identifier = NULL; | 82 | mach->identifier = NULL; |
83 | mach->comparator = NULL; | ||
80 | return rc; | 84 | return rc; |
81 | } | 85 | } |
82 | 86 | ||
... | @@ -138,9 +142,9 @@ _mu_i_sv_instr_not (mu_sieve_machine_t mach) | ... | @@ -138,9 +142,9 @@ _mu_i_sv_instr_not (mu_sieve_machine_t mach) |
138 | void | 142 | void |
139 | _mu_i_sv_instr_branch (mu_sieve_machine_t mach) | 143 | _mu_i_sv_instr_branch (mu_sieve_machine_t mach) |
140 | { | 144 | { |
141 | long num = SIEVE_ARG (mach, 0, number); | 145 | long num = SIEVE_RT_ARG (mach, 0, number); |
142 | 146 | ||
143 | SIEVE_ADJUST (mach, 1); | 147 | SIEVE_RT_ADJUST (mach, 1); |
144 | if (INSTR_DEBUG (mach)) | 148 | if (INSTR_DEBUG (mach)) |
145 | mu_i_sv_debug (mach, mach->pc - 2, "BRANCH %lu", | 149 | mu_i_sv_debug (mach, mach->pc - 2, "BRANCH %lu", |
146 | (unsigned long)(mach->pc + num)); | 150 | (unsigned long)(mach->pc + num)); |
... | @@ -153,8 +157,8 @@ _mu_i_sv_instr_branch (mu_sieve_machine_t mach) | ... | @@ -153,8 +157,8 @@ _mu_i_sv_instr_branch (mu_sieve_machine_t mach) |
153 | void | 157 | void |
154 | _mu_i_sv_instr_brz (mu_sieve_machine_t mach) | 158 | _mu_i_sv_instr_brz (mu_sieve_machine_t mach) |
155 | { | 159 | { |
156 | long num = SIEVE_ARG (mach, 0, number); | 160 | long num = SIEVE_RT_ARG (mach, 0, number); |
157 | SIEVE_ADJUST (mach, 1); | 161 | SIEVE_RT_ADJUST (mach, 1); |
158 | 162 | ||
159 | if (INSTR_DEBUG (mach)) | 163 | if (INSTR_DEBUG (mach)) |
160 | mu_i_sv_debug (mach, mach->pc - 2, "BRZ %lu", | 164 | mu_i_sv_debug (mach, mach->pc - 2, "BRZ %lu", |
... | @@ -169,8 +173,8 @@ _mu_i_sv_instr_brz (mu_sieve_machine_t mach) | ... | @@ -169,8 +173,8 @@ _mu_i_sv_instr_brz (mu_sieve_machine_t mach) |
169 | void | 173 | void |
170 | _mu_i_sv_instr_brnz (mu_sieve_machine_t mach) | 174 | _mu_i_sv_instr_brnz (mu_sieve_machine_t mach) |
171 | { | 175 | { |
172 | long num = SIEVE_ARG (mach, 0, number); | 176 | long num = SIEVE_RT_ARG (mach, 0, number); |
173 | SIEVE_ADJUST (mach, 1); | 177 | SIEVE_RT_ADJUST (mach, 1); |
174 | 178 | ||
175 | if (INSTR_DEBUG (mach)) | 179 | if (INSTR_DEBUG (mach)) |
176 | mu_i_sv_debug (mach, mach->pc - 2, "BRNZ %lu", | 180 | mu_i_sv_debug (mach, mach->pc - 2, "BRNZ %lu", | ... | ... |
... | @@ -19,8 +19,7 @@ | ... | @@ -19,8 +19,7 @@ |
19 | #include <mailutils/sieve.h> | 19 | #include <mailutils/sieve.h> |
20 | #include <setjmp.h> | 20 | #include <setjmp.h> |
21 | #include <string.h> | 21 | #include <string.h> |
22 | 22 | #include <regex.h> | |
23 | #define SIEVE_CODE_INCR 128 | ||
24 | 23 | ||
25 | typedef void (*sieve_instr_t) (mu_sieve_machine_t mach); | 24 | typedef void (*sieve_instr_t) (mu_sieve_machine_t mach); |
26 | 25 | ||
... | @@ -29,6 +28,7 @@ typedef union | ... | @@ -29,6 +28,7 @@ typedef union |
29 | sieve_instr_t instr; | 28 | sieve_instr_t instr; |
30 | mu_sieve_handler_t handler; | 29 | mu_sieve_handler_t handler; |
31 | mu_sieve_value_t *val; | 30 | mu_sieve_value_t *val; |
31 | mu_sieve_comparator_t comp; | ||
32 | mu_list_t list; | 32 | mu_list_t list; |
33 | long number; | 33 | long number; |
34 | size_t pc; | 34 | size_t pc; |
... | @@ -37,7 +37,7 @@ typedef union | ... | @@ -37,7 +37,7 @@ typedef union |
37 | char *string; | 37 | char *string; |
38 | unsigned unum; | 38 | unsigned unum; |
39 | } sieve_op_t; | 39 | } sieve_op_t; |
40 | 40 | ||
41 | struct mu_locus_range | 41 | struct mu_locus_range |
42 | { | 42 | { |
43 | struct mu_locus beg; | 43 | struct mu_locus beg; |
... | @@ -73,6 +73,14 @@ struct mu_sieve_machine | ... | @@ -73,6 +73,14 @@ struct mu_sieve_machine |
73 | mu_list_t action_list; /* Actions */ | 73 | mu_list_t action_list; /* Actions */ |
74 | mu_list_t comp_list; /* Comparators */ | 74 | mu_list_t comp_list; /* Comparators */ |
75 | mu_list_t source_list; /* Source names (for diagnostics) */ | 75 | mu_list_t source_list; /* Source names (for diagnostics) */ |
76 | |||
77 | mu_sieve_string_t *stringspace; | ||
78 | size_t stringcount; | ||
79 | size_t stringmax; | ||
80 | |||
81 | mu_sieve_value_t *valspace; | ||
82 | size_t valcount; | ||
83 | size_t valmax; | ||
76 | 84 | ||
77 | size_t progsize; /* Number of allocated program cells */ | 85 | size_t progsize; /* Number of allocated program cells */ |
78 | sieve_op_t *prog; /* Compiled program */ | 86 | sieve_op_t *prog; /* Compiled program */ |
... | @@ -85,8 +93,10 @@ struct mu_sieve_machine | ... | @@ -85,8 +93,10 @@ struct mu_sieve_machine |
85 | 93 | ||
86 | /* Call environment */ | 94 | /* Call environment */ |
87 | const char *identifier; /* Name of action or test being executed */ | 95 | const char *identifier; /* Name of action or test being executed */ |
88 | mu_list_t arg_list; /* Positional arguments */ | 96 | size_t argstart; /* Index of the first argument in valspace */ |
89 | mu_list_t tag_list; /* Tagged arguments */ | 97 | size_t argcount; /* Number of positional arguments */ |
98 | size_t tagcount; /* Number of tagged arguments */ | ||
99 | mu_sieve_comparator_t comparator; /* Comparator (for tests) */ | ||
90 | 100 | ||
91 | int dry_run; /* Dry-run mode */ | 101 | int dry_run; /* Dry-run mode */ |
92 | jmp_buf errbuf; /* Target location for non-local exits */ | 102 | jmp_buf errbuf; /* Target location for non-local exits */ |
... | @@ -146,7 +156,10 @@ struct mu_sieve_node | ... | @@ -146,7 +156,10 @@ struct mu_sieve_node |
146 | struct | 156 | struct |
147 | { | 157 | { |
148 | mu_sieve_register_t *reg; | 158 | mu_sieve_register_t *reg; |
149 | mu_list_t arg; | 159 | size_t argstart; |
160 | size_t argcount; | ||
161 | size_t tagcount; | ||
162 | mu_sieve_comparator_t comparator; /* Comparator (for tests) */ | ||
150 | } command; | 163 | } command; |
151 | } v; | 164 | } v; |
152 | }; | 165 | }; |
... | @@ -161,18 +174,16 @@ void mu_i_sv_lex_finish (struct mu_sieve_machine *mach); | ... | @@ -161,18 +174,16 @@ void mu_i_sv_lex_finish (struct mu_sieve_machine *mach); |
161 | 174 | ||
162 | extern mu_sieve_machine_t mu_sieve_machine; | 175 | extern mu_sieve_machine_t mu_sieve_machine; |
163 | 176 | ||
164 | #define TAG_COMPFUN "__compfun__" | 177 | void mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op); |
165 | |||
166 | int mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op); | ||
167 | 178 | ||
168 | void mu_i_sv_compile_error (struct mu_sieve_machine *mach, | 179 | void mu_i_sv_compile_error (struct mu_sieve_machine *mach, |
169 | const char *fmt, ...) MU_PRINTFLIKE(2,3); | 180 | const char *fmt, ...) MU_PRINTFLIKE(2,3); |
170 | 181 | ||
171 | int mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr); | 182 | int mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr); |
172 | int mu_i_sv_code_action (struct mu_sieve_machine *mach, | 183 | void mu_i_sv_code_action (struct mu_sieve_machine *mach, |
173 | mu_sieve_register_t *reg, mu_list_t arglist); | 184 | struct mu_sieve_node *node); |
174 | int mu_i_sv_code_test (struct mu_sieve_machine *mach, | 185 | void mu_i_sv_code_test (struct mu_sieve_machine *mach, |
175 | mu_sieve_register_t *reg, mu_list_t arglist); | 186 | struct mu_sieve_node *node); |
176 | 187 | ||
177 | /* Opcodes */ | 188 | /* Opcodes */ |
178 | void _mu_i_sv_instr_action (mu_sieve_machine_t mach); | 189 | void _mu_i_sv_instr_action (mu_sieve_machine_t mach); |
... | @@ -203,8 +214,7 @@ void mu_i_sv_debug_command (mu_sieve_machine_t mach, size_t pc, | ... | @@ -203,8 +214,7 @@ void mu_i_sv_debug_command (mu_sieve_machine_t mach, size_t pc, |
203 | char const *what); | 214 | char const *what); |
204 | void mu_i_sv_trace (mu_sieve_machine_t mach, const char *what); | 215 | void mu_i_sv_trace (mu_sieve_machine_t mach, const char *what); |
205 | 216 | ||
206 | void mu_i_sv_argf (mu_stream_t str, mu_list_t list); | 217 | void mu_i_sv_valf (mu_sieve_machine_t mach, mu_stream_t str, mu_sieve_value_t *val); |
207 | void mu_i_sv_valf (mu_stream_t str, mu_sieve_value_t *val); | ||
208 | 218 | ||
209 | typedef int (*mu_i_sv_interp_t) (char const *, size_t, char **, void *); | 219 | typedef int (*mu_i_sv_interp_t) (char const *, size_t, char **, void *); |
210 | 220 | ||
... | @@ -216,4 +226,15 @@ int mu_i_sv_expand_encoded_char (char const *input, size_t len, char **exp, void | ... | @@ -216,4 +226,15 @@ int mu_i_sv_expand_encoded_char (char const *input, size_t len, char **exp, void |
216 | int mu_sieve_require_encoded_character (mu_sieve_machine_t mach, | 226 | int mu_sieve_require_encoded_character (mu_sieve_machine_t mach, |
217 | const char *name); | 227 | const char *name); |
218 | 228 | ||
229 | void mu_i_sv_2nrealloc (mu_sieve_machine_t mach, | ||
230 | void **pptr, size_t *pnmemb, size_t size); | ||
231 | |||
232 | |||
233 | mu_sieve_value_t *mu_i_sv_mach_arg (mu_sieve_machine_t mach, size_t n); | ||
234 | mu_sieve_value_t *mu_i_sv_mach_tagn (mu_sieve_machine_t mach, size_t n); | ||
235 | void mu_i_sv_lint_command (struct mu_sieve_machine *mach, | ||
236 | struct mu_sieve_node *node); | ||
237 | |||
238 | |||
239 | size_t mu_i_sv_string_create (mu_sieve_machine_t mach, char *str); | ||
219 | 240 | ... | ... |
This diff is collapsed.
Click to expand it.
libmu_sieve/string.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999-2002, 2005-2008, 2010-2012, 2014-2016 Free | ||
3 | Software Foundation, Inc. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 3 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General | ||
16 | Public License along with this library. If not, see | ||
17 | <http://www.gnu.org/licenses/>. */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include <config.h> | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <sieve-priv.h> | ||
25 | |||
26 | size_t | ||
27 | mu_i_sv_string_create (mu_sieve_machine_t mach, char *str) | ||
28 | { | ||
29 | size_t n; | ||
30 | mu_sieve_string_t *s; | ||
31 | |||
32 | if (mach->stringcount == mach->stringmax) | ||
33 | { | ||
34 | mu_i_sv_2nrealloc (mach, (void**) &mach->stringspace, | ||
35 | &mach->stringmax, | ||
36 | sizeof mach->stringspace[0]); | ||
37 | } | ||
38 | |||
39 | n = mach->stringcount++; | ||
40 | s = &mach->stringspace[n]; | ||
41 | memset (s, 0, sizeof *s); | ||
42 | s->orig = str; | ||
43 | |||
44 | return n; | ||
45 | } | ||
46 | |||
47 | struct mu_sieve_string * | ||
48 | mu_sieve_string_raw (mu_sieve_machine_t mach, mu_sieve_slice_t slice, | ||
49 | size_t i) | ||
50 | { | ||
51 | if (i >= slice->count) | ||
52 | abort (); | ||
53 | return mach->stringspace + slice->first + i; | ||
54 | } | ||
55 | |||
56 | char * | ||
57 | mu_sieve_string (mu_sieve_machine_t mach, mu_sieve_slice_t slice, | ||
58 | size_t i) | ||
59 | { | ||
60 | return mu_sieve_string_raw (mach, slice, i)->orig; | ||
61 | } |
... | @@ -27,32 +27,24 @@ | ... | @@ -27,32 +27,24 @@ |
27 | 27 | ||
28 | typedef int (*address_aget_t) (mu_address_t addr, size_t no, char **buf); | 28 | typedef int (*address_aget_t) (mu_address_t addr, size_t no, char **buf); |
29 | 29 | ||
30 | static int | ||
31 | _get_address_part (void *item, void *data) | ||
32 | { | ||
33 | mu_sieve_runtime_tag_t *t = item; | ||
34 | address_aget_t ret = NULL; | ||
35 | |||
36 | if (strcmp (t->tag, "all") == 0) | ||
37 | ret = mu_address_aget_email; | ||
38 | else if (strcmp (t->tag, "domain") == 0) | ||
39 | ret = mu_address_aget_domain; | ||
40 | else if (strcmp (t->tag, "localpart") == 0) | ||
41 | ret = mu_address_aget_local_part; | ||
42 | if (ret) | ||
43 | { | ||
44 | *(address_aget_t*)data = ret; | ||
45 | return 1; /* break the loop */ | ||
46 | } | ||
47 | return 0; /* continue */ | ||
48 | } | ||
49 | |||
50 | address_aget_t | 30 | address_aget_t |
51 | sieve_get_address_part (mu_list_t tags) | 31 | sieve_get_address_part (mu_sieve_machine_t mach) |
52 | { | 32 | { |
53 | address_aget_t ret = mu_address_aget_email; | 33 | size_t i; |
54 | mu_list_foreach (tags, _get_address_part, &ret); | 34 | |
55 | return ret; | 35 | for (i = 0; i < mach->tagcount; i++) |
36 | { | ||
37 | mu_sieve_value_t *t = mu_sieve_get_tag_n (mach, i); | ||
38 | if (strcmp (t->tag, "all") == 0) | ||
39 | return mu_address_aget_email; | ||
40 | else if (strcmp (t->tag, "domain") == 0) | ||
41 | return mu_address_aget_domain; | ||
42 | else if (strcmp (t->tag, "localpart") == 0) | ||
43 | return mu_address_aget_local_part; | ||
44 | } | ||
45 | /* RFC 3028, 2.7.4. Comparisons Against Addresses: | ||
46 | If an optional address-part is omitted, the default is ":all". */ | ||
47 | return mu_address_aget_email; | ||
56 | } | 48 | } |
57 | 49 | ||
58 | /* Structure shared between address and envelope tests */ | 50 | /* Structure shared between address and envelope tests */ |
... | @@ -72,11 +64,11 @@ do_count (mu_sieve_machine_t mach, size_t count, int retval) | ... | @@ -72,11 +64,11 @@ do_count (mu_sieve_machine_t mach, size_t count, int retval) |
72 | { | 64 | { |
73 | size_t limit; | 65 | size_t limit; |
74 | char *str; | 66 | char *str; |
75 | mu_list_t list; | 67 | struct mu_sieve_slice slice; |
76 | mu_sieve_relcmpn_t stest; | 68 | mu_sieve_relcmpn_t stest; |
77 | 69 | ||
78 | mu_sieve_get_arg (mach, 1, SVT_STRING_LIST, &list); | 70 | mu_sieve_get_arg (mach, 1, SVT_STRING_LIST, &slice); |
79 | mu_list_get (list, 0, (void **) &str); | 71 | str = mu_sieve_string (mach, &slice, 0); |
80 | limit = strtoul (str, &str, 10); | 72 | limit = strtoul (str, &str, 10); |
81 | 73 | ||
82 | mu_sieve_str_to_relcmp (relcmp, NULL, &stest); | 74 | mu_sieve_str_to_relcmp (relcmp, NULL, &stest); |
... | @@ -117,16 +109,16 @@ sieve_test_address (mu_sieve_machine_t mach) | ... | @@ -117,16 +109,16 @@ sieve_test_address (mu_sieve_machine_t mach) |
117 | mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach); | 109 | mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach); |
118 | struct address_closure clos; | 110 | struct address_closure clos; |
119 | int rc; | 111 | int rc; |
120 | size_t count; | 112 | size_t count = 0; |
121 | 113 | ||
122 | h = mu_sieve_get_arg_untyped (mach, 0); | 114 | h = mu_sieve_get_arg_untyped (mach, 0); |
123 | v = mu_sieve_get_arg_untyped (mach, 1); | 115 | v = mu_sieve_get_arg_untyped (mach, 1); |
124 | 116 | ||
125 | mu_message_get_header (mu_sieve_get_message (mach), &header); | 117 | mu_message_get_header (mu_sieve_get_message (mach), &header); |
126 | clos.data = header; | 118 | clos.data = header; |
127 | clos.aget = sieve_get_address_part (mach->tag_list); | 119 | clos.aget = sieve_get_address_part (mach); |
128 | clos.addr = NULL; | 120 | clos.addr = NULL; |
129 | rc = mu_sieve_vlist_compare (h, v, comp, test, retrieve_address, &clos, | 121 | rc = mu_sieve_vlist_compare (mach, h, v, comp, test, retrieve_address, &clos, |
130 | &count); | 122 | &count); |
131 | mu_address_destroy (&clos.addr); | 123 | mu_address_destroy (&clos.addr); |
132 | 124 | ||
... | @@ -169,7 +161,7 @@ sieve_test_header (mu_sieve_machine_t mach) | ... | @@ -169,7 +161,7 @@ sieve_test_header (mu_sieve_machine_t mach) |
169 | mu_sieve_value_t *h, *v; | 161 | mu_sieve_value_t *h, *v; |
170 | mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach); | 162 | mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach); |
171 | mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach); | 163 | mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach); |
172 | size_t count, mcount = 0; | 164 | size_t count = 0, mcount = 0; |
173 | struct header_closure clos; | 165 | struct header_closure clos; |
174 | 166 | ||
175 | h = mu_sieve_get_arg_untyped (mach, 0); | 167 | h = mu_sieve_get_arg_untyped (mach, 0); |
... | @@ -192,7 +184,7 @@ sieve_test_header (mu_sieve_machine_t mach) | ... | @@ -192,7 +184,7 @@ sieve_test_header (mu_sieve_machine_t mach) |
192 | if (mu_message_get_part (mach->msg, i, &message) == 0) | 184 | if (mu_message_get_part (mach->msg, i, &message) == 0) |
193 | { | 185 | { |
194 | mu_message_get_header (message, &clos.header); | 186 | mu_message_get_header (message, &clos.header); |
195 | if (mu_sieve_vlist_compare (h, v, comp, test, | 187 | if (mu_sieve_vlist_compare (mach, h, v, comp, test, |
196 | retrieve_header, &clos, &mcount)) | 188 | retrieve_header, &clos, &mcount)) |
197 | return 1; | 189 | return 1; |
198 | } | 190 | } |
... | @@ -200,7 +192,7 @@ sieve_test_header (mu_sieve_machine_t mach) | ... | @@ -200,7 +192,7 @@ sieve_test_header (mu_sieve_machine_t mach) |
200 | } | 192 | } |
201 | } | 193 | } |
202 | mu_message_get_header (mach->msg, &clos.header); | 194 | mu_message_get_header (mach->msg, &clos.header); |
203 | if (mu_sieve_vlist_compare (h, v, comp, test, retrieve_header, &clos, | 195 | if (mu_sieve_vlist_compare (mach, h, v, comp, test, retrieve_header, &clos, |
204 | &count)) | 196 | &count)) |
205 | return 1; | 197 | return 1; |
206 | 198 | ||
... | @@ -242,16 +234,16 @@ sieve_test_envelope (mu_sieve_machine_t mach) | ... | @@ -242,16 +234,16 @@ sieve_test_envelope (mu_sieve_machine_t mach) |
242 | mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach); | 234 | mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach); |
243 | struct address_closure clos; | 235 | struct address_closure clos; |
244 | int rc; | 236 | int rc; |
245 | size_t count; | 237 | size_t count = 0; |
246 | 238 | ||
247 | h = mu_sieve_get_arg_untyped (mach, 0); | 239 | h = mu_sieve_get_arg_untyped (mach, 0); |
248 | v = mu_sieve_get_arg_untyped (mach, 1); | 240 | v = mu_sieve_get_arg_untyped (mach, 1); |
249 | 241 | ||
250 | mu_message_get_envelope (mu_sieve_get_message (mach), | 242 | mu_message_get_envelope (mu_sieve_get_message (mach), |
251 | (mu_envelope_t*)&clos.data); | 243 | (mu_envelope_t*)&clos.data); |
252 | clos.aget = sieve_get_address_part (mach->tag_list); | 244 | clos.aget = sieve_get_address_part (mach); |
253 | clos.addr = NULL; | 245 | clos.addr = NULL; |
254 | rc = mu_sieve_vlist_compare (h, v, comp, test, retrieve_envelope, &clos, | 246 | rc = mu_sieve_vlist_compare (mach, h, v, comp, test, retrieve_envelope, &clos, |
255 | &count); | 247 | &count); |
256 | mu_address_destroy (&clos.addr); | 248 | mu_address_destroy (&clos.addr); |
257 | return do_count (mach, count, rc); | 249 | return do_count (mach, count, rc); |
... | @@ -261,19 +253,23 @@ int | ... | @@ -261,19 +253,23 @@ int |
261 | sieve_test_size (mu_sieve_machine_t mach) | 253 | sieve_test_size (mu_sieve_machine_t mach) |
262 | { | 254 | { |
263 | int rc = 1; | 255 | int rc = 1; |
264 | mu_sieve_runtime_tag_t *tag = NULL; | ||
265 | size_t size; | 256 | size_t size; |
266 | size_t arg; | 257 | size_t arg; |
267 | 258 | ||
268 | mu_sieve_get_arg (mach, 0, SVT_NUMBER, &arg); | 259 | mu_sieve_get_arg (mach, 0, SVT_NUMBER, &arg); |
269 | mu_message_size (mu_sieve_get_message (mach), &size); | 260 | mu_message_size (mu_sieve_get_message (mach), &size); |
270 | mu_list_get (mach->tag_list, 0, (void **)&tag); | 261 | if (mach->tagcount) |
271 | if (!tag) | 262 | { |
263 | mu_sieve_value_t *tag = mu_sieve_get_tag_n (mach, 0); | ||
264 | if (strcmp (tag->tag, "over") == 0) | ||
265 | rc = size > arg; | ||
266 | else if (strcmp (tag->tag, "under") == 0) | ||
267 | rc = size < arg; | ||
268 | else | ||
269 | abort (); | ||
270 | } | ||
271 | else | ||
272 | rc = size == arg; | 272 | rc = size == arg; |
273 | else if (strcmp (tag->tag, "over") == 0) | ||
274 | rc = size > arg; | ||
275 | else if (strcmp (tag->tag, "under") == 0) | ||
276 | rc = size < arg; | ||
277 | 273 | ||
278 | return rc; | 274 | return rc; |
279 | } | 275 | } |
... | @@ -295,7 +291,7 @@ sieve_test_exists (mu_sieve_machine_t mach) | ... | @@ -295,7 +291,7 @@ sieve_test_exists (mu_sieve_machine_t mach) |
295 | 291 | ||
296 | mu_message_get_header (mu_sieve_get_message (mach), &header); | 292 | mu_message_get_header (mu_sieve_get_message (mach), &header); |
297 | val = mu_sieve_get_arg_untyped (mach, 0); | 293 | val = mu_sieve_get_arg_untyped (mach, 0); |
298 | return mu_sieve_vlist_do (val, _test_exists, header) == 0; | 294 | return mu_sieve_vlist_do (mach, val, _test_exists, header) == 0; |
299 | } | 295 | } |
300 | 296 | ||
301 | static mu_sieve_tag_def_t address_part_tags[] = { | 297 | static mu_sieve_tag_def_t address_part_tags[] = { | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -125,7 +125,7 @@ Subject: Ping | ... | @@ -125,7 +125,7 @@ Subject: Ping |
125 | Test message, please discard. | 125 | Test message, please discard. |
126 | 126 | ||
127 | ], | 127 | ], |
128 | [DELETEHEADER on msg uid 1: X-Agent: (regexp) | 128 | [DELETEHEADER on msg uid 1: X-Agent (values) |
129 | ]) | 129 | ]) |
130 | 130 | ||
131 | m4_popdef([MUT_SIEVE_EXT_NAME]) | 131 | m4_popdef([MUT_SIEVE_EXT_NAME]) | ... | ... |
... | @@ -19,7 +19,6 @@ AT_KEYWORDS([encoded-character enc-char]) | ... | @@ -19,7 +19,6 @@ AT_KEYWORDS([encoded-character enc-char]) |
19 | 19 | ||
20 | AT_CHECK([ | 20 | AT_CHECK([ |
21 | AT_DATA([prog],[[require ["reject", "encoded-character"]; | 21 | AT_DATA([prog],[[require ["reject", "encoded-character"]; |
22 | |||
23 | reject "$${hex:40}"; | 22 | reject "$${hex:40}"; |
24 | reject "${hex: 40 }"; | 23 | reject "${hex: 40 }"; |
25 | reject "${HEX: 40}"; | 24 | reject "${HEX: 40}"; |
... | @@ -38,25 +37,25 @@ reject "Nested ${hex: 73 65 71 ${hex: 75 65 6E}}ce"; | ... | @@ -38,25 +37,25 @@ reject "Nested ${hex: 73 65 71 ${hex: 75 65 6E}}ce"; |
38 | reject "Invalid ${hex: 73 RE}"; | 37 | reject "Invalid ${hex: 73 RE}"; |
39 | ]]) | 38 | ]]) |
40 | 39 | ||
41 | sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -D prog | grep ACTION | 40 | sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -D prog | sed -n 's/.*ACTION: //p' |
42 | ], | 41 | ], |
43 | [0], | 42 | [0], |
44 | [ 9: ACTION: reject "$@" | 43 | [reject "$@" |
45 | 16: ACTION: reject "@" | 44 | reject "@" |
46 | 23: ACTION: reject "@" | 45 | reject "@" |
47 | 30: ACTION: reject "${hex:40" | 46 | reject "${hex:40" |
48 | 37: ACTION: reject "${hex:400}" | 47 | reject "${hex:400}" |
49 | 44: ACTION: reject "${hex:40}" | 48 | reject "${hex:40}" |
50 | 51: ACTION: reject "@" | 49 | reject "@" |
51 | 58: ACTION: reject "${ unicode:40}" | 50 | reject "${ unicode:40}" |
52 | 65: ACTION: reject "@" | 51 | reject "@" |
53 | 72: ACTION: reject "@" | 52 | reject "@" |
54 | 79: ACTION: reject "@" | 53 | reject "@" |
55 | 86: ACTION: reject "${Unicode:Cool}" | 54 | reject "${Unicode:Cool}" |
56 | 93: ACTION: reject "Now is the time" | 55 | reject "Now is the time" |
57 | 100: ACTION: reject "Unbalanced ${hex: 73 65 71 uence" | 56 | reject "Unbalanced ${hex: 73 65 71 uence" |
58 | 107: ACTION: reject "Nested ${hex: 73 65 71 uen}ce" | 57 | reject "Nested ${hex: 73 65 71 uen}ce" |
59 | 114: ACTION: reject "Invalid ${hex: 73 RE}" | 58 | reject "Invalid ${hex: 73 RE}" |
60 | ]) | 59 | ]) |
61 | 60 | ||
62 | AT_CLEANUP | 61 | AT_CLEANUP | ... | ... |
-
Please register or sign in to post a comment