Skip to content

Commit

Permalink
lib-sieve: Implemented sieve_implicit_extensions setting.
Browse files Browse the repository at this point in the history
The extensions listed in this setting do not need to be enabled explicitly using the Sieve require command.
This behavior voilates the standard, but is necessary for compatibility with some existing implementations of Sieve.
Do not use this setting unless you really need to!
  • Loading branch information
stephanbosch committed Feb 12, 2016
1 parent f37f016 commit 0de2a19
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 19 deletions.
57 changes: 42 additions & 15 deletions src/lib-sieve/sieve-extensions.c
Expand Up @@ -273,13 +273,21 @@ void sieve_extensions_configure(struct sieve_instance *svinst)

/* Apply sieve_extensions configuration */

if ( (extensions=sieve_setting_get(svinst, "sieve_extensions")) != NULL )
sieve_extensions_set_string(svinst, extensions, FALSE);
if ( (extensions=sieve_setting_get
(svinst, "sieve_extensions")) != NULL )
sieve_extensions_set_string(svinst, extensions, FALSE, FALSE);

/* Apply sieve_global_extensions configuration */

if ( (extensions=sieve_setting_get(svinst, "sieve_global_extensions")) != NULL )
sieve_extensions_set_string(svinst, extensions, TRUE);
if ( (extensions=sieve_setting_get
(svinst, "sieve_global_extensions")) != NULL )
sieve_extensions_set_string(svinst, extensions, TRUE, FALSE);

/* Apply sieve_implicit_extensions configuration */

if ( (extensions=sieve_setting_get
(svinst, "sieve_implicit_extensions")) != NULL )
sieve_extensions_set_string(svinst, extensions, FALSE, TRUE);
}

void sieve_extensions_deinit(struct sieve_instance *svinst)
Expand Down Expand Up @@ -494,13 +502,23 @@ void sieve_extension_override
(*mod_ext)->overridden = TRUE;
}

int sieve_extensions_get_count(struct sieve_instance *svinst)
unsigned int sieve_extensions_get_count(struct sieve_instance *svinst)
{
struct sieve_extension_registry *ext_reg = svinst->ext_reg;

return array_count(&ext_reg->extensions);
}

const struct sieve_extension *const *
sieve_extensions_get_all(struct sieve_instance *svinst,
unsigned int *count_r)
{
struct sieve_extension_registry *ext_reg = svinst->ext_reg;

return (const struct sieve_extension *const *)
array_get(&ext_reg->extensions, count_r);
}

const struct sieve_extension *sieve_extension_get_by_id
(struct sieve_instance *svinst, unsigned int ext_id)
{
Expand Down Expand Up @@ -580,7 +598,6 @@ static void sieve_extension_set_enabled
{
if ( enabled ) {
ext->enabled = TRUE;
ext->global = FALSE;

if ( !ext->loaded ) {
(void)_sieve_extension_load(ext);
Expand All @@ -596,21 +613,27 @@ static void sieve_extension_set_global
(struct sieve_extension *ext, bool enabled)
{
if ( enabled ) {
ext->enabled = TRUE;
sieve_extension_set_enabled(ext, TRUE);
ext->global = TRUE;

if ( !ext->loaded ) {
(void)_sieve_extension_load(ext);
}

ext->loaded = TRUE;
} else {
ext->global = FALSE;
}
}

static void sieve_extension_set_implicit
(struct sieve_extension *ext, bool enabled)
{
if ( enabled ) {
sieve_extension_set_enabled(ext, TRUE);
ext->implicit = TRUE;
} else {
ext->implicit = FALSE;
}
}

void sieve_extensions_set_string
(struct sieve_instance *svinst, const char *ext_string, bool global)
(struct sieve_instance *svinst, const char *ext_string,
bool global, bool implicit)
{
struct sieve_extension_registry *ext_reg = svinst->ext_reg;
ARRAY(const struct sieve_extension *) enabled_extensions;
Expand All @@ -623,7 +646,7 @@ void sieve_extensions_set_string
bool relative = FALSE;

if ( ext_string == NULL ) {
if ( global ) return;
if ( global || implicit ) return;

/* Enable all */
exts = array_get_modifiable(&ext_reg->extensions, &ext_count);
Expand Down Expand Up @@ -696,6 +719,8 @@ void sieve_extensions_set_string
if ( relative ) {
if ( global )
enabled = exts[i]->global;
else if ( implicit )
enabled = exts[i]->implicit;
else
enabled = exts[i]->enabled;

Expand All @@ -722,6 +747,8 @@ void sieve_extensions_set_string
/* Perform actual activation/deactivation */
if ( global ) {
sieve_extension_set_global(exts[i], enabled);
} else if ( implicit ) {
sieve_extension_set_implicit(exts[i], enabled);
} else {
sieve_extension_set_enabled(exts[i], enabled);
}
Expand Down
9 changes: 7 additions & 2 deletions src/lib-sieve/sieve-extensions.h
Expand Up @@ -95,6 +95,7 @@ struct sieve_extension {
unsigned int enabled:1;
unsigned int dummy:1;
unsigned int global:1;
unsigned int implicit:1;
unsigned int overridden:1;
};

Expand Down Expand Up @@ -142,7 +143,10 @@ void sieve_extension_override
(struct sieve_instance *svinst, const char *name,
const struct sieve_extension *ext);

int sieve_extensions_get_count(struct sieve_instance *svinst);
unsigned int sieve_extensions_get_count(struct sieve_instance *svinst);
const struct sieve_extension *const *
sieve_extensions_get_all(struct sieve_instance *svinst,
unsigned int *count_r);

const struct sieve_extension *sieve_extension_get_by_id
(struct sieve_instance *svinst, unsigned int ext_id);
Expand All @@ -152,7 +156,8 @@ const struct sieve_extension *sieve_extension_get_by_name
const char *sieve_extensions_get_string
(struct sieve_instance *svinst);
void sieve_extensions_set_string
(struct sieve_instance *svinst, const char *ext_string, bool global);
(struct sieve_instance *svinst, const char *ext_string,
bool global, bool implicit);

const struct sieve_extension *sieve_get_match_type_extension
(struct sieve_instance *svinst);
Expand Down
10 changes: 10 additions & 0 deletions src/lib-sieve/sieve-validator.c
Expand Up @@ -1372,10 +1372,20 @@ static bool sieve_validate_block
&& !valdtr->finished_require &&
strcasecmp(cmd_node->identifier, cmd_require.identifier) != 0 ) {
const struct sieve_validator_extension_reg *extrs;
const struct sieve_extension *const *exts;
unsigned int ext_count, i;

valdtr->finished_require = TRUE;

/* Load implicit extensions */
exts = sieve_extensions_get_all(valdtr->svinst, &ext_count);
for (i = 0; i < ext_count; i++) {
if ( exts[i]->implicit ) {
(void)sieve_validator_extension_load
(valdtr, NULL, NULL, exts[i]);
}
}

/* Validate all 'require'd extensions */
extrs = array_get(&valdtr->extensions, &ext_count);
for ( i = 0; i < ext_count; i++ ) {
Expand Down
3 changes: 2 additions & 1 deletion src/lib-sieve/sieve-validator.h
Expand Up @@ -138,7 +138,8 @@ struct sieve_validator_extension {

bool sieve_validator_extension_load
(struct sieve_validator *valdtr, struct sieve_command *cmd,
struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext);
struct sieve_ast_argument *ext_arg, const struct sieve_extension *ext)
ATTR_NULL(2, 3);
const struct sieve_extension *sieve_validator_extension_load_by_name
(struct sieve_validator *valdtr, struct sieve_command *cmd,
struct sieve_ast_argument *ext_arg, const char *ext_name);
Expand Down
2 changes: 1 addition & 1 deletion src/lib-sieve/sieve.c
Expand Up @@ -132,7 +132,7 @@ void sieve_deinit(struct sieve_instance **_svinst)
void sieve_set_extensions
(struct sieve_instance *svinst, const char *extensions)
{
sieve_extensions_set_string(svinst, extensions, FALSE);
sieve_extensions_set_string(svinst, extensions, FALSE, FALSE);
}

const char *sieve_get_capabilities
Expand Down

0 comments on commit 0de2a19

Please sign in to comment.