diff --git a/src/lib-sieve/plugins/variables/Makefile.am b/src/lib-sieve/plugins/variables/Makefile.am index 354bad2a6f61404ad58292d235d0a455aae147ad..d5c9c7b8ea288fe2653a5f584ac970b50c5ec044 100644 --- a/src/lib-sieve/plugins/variables/Makefile.am +++ b/src/lib-sieve/plugins/variables/Makefile.am @@ -11,6 +11,7 @@ tsts = \ tst-string.c libsieve_ext_variables_la_SOURCES = \ + ext-variables-settings.c \ ext-variables-common.c \ ext-variables-name.c \ ext-variables-namespaces.c \ @@ -26,6 +27,7 @@ public_headers = \ sieve-ext-variables.h headers = \ + ext-variables-settings.h \ ext-variables-common.h \ ext-variables-limits.h \ ext-variables-name.h \ diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index aca892089477f21df544c3ac3c3b2d6b1071eb54..a33efc9d3d0d69e721d7a382db958f60746a1524 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -5,9 +5,9 @@ #include "hash.h" #include "str.h" #include "array.h" +#include "settings.h" #include "sieve-common.h" -#include "sieve-settings.old.h" #include "sieve-ast.h" #include "sieve-binary.h" @@ -22,7 +22,6 @@ #include "sieve-interpreter.h" #include "ext-variables-common.h" -#include "ext-variables-limits.h" #include "ext-variables-name.h" #include "ext-variables-modifiers.h" @@ -36,7 +35,7 @@ sieve_variables_get_max_scope_size(const struct sieve_extension *var_ext) const struct ext_variables_context *extctx = ext_variables_get_context(var_ext); - return extctx->max_scope_size; + return extctx->set->max_scope_size; } size_t sieve_variables_get_max_variable_size( @@ -45,7 +44,7 @@ size_t sieve_variables_get_max_variable_size( const struct ext_variables_context *extctx = ext_variables_get_context(var_ext); - return extctx->max_variable_size; + return extctx->set->max_variable_size; } /* @@ -55,42 +54,18 @@ size_t sieve_variables_get_max_variable_size( int ext_variables_load(const struct sieve_extension *ext, void **context_r) { struct sieve_instance *svinst = ext->svinst; + const struct ext_variables_settings *set; struct ext_variables_context *extctx; - unsigned long long int uint_setting; - size_t size_setting; + const char *error; - extctx = i_new(struct ext_variables_context, 1); - - /* Get limits */ - extctx->max_scope_size = EXT_VARIABLES_DEFAULT_MAX_SCOPE_SIZE; - extctx->max_variable_size = EXT_VARIABLES_DEFAULT_MAX_VARIABLE_SIZE; - - if (sieve_setting_get_uint_value( - svinst, "sieve_variables_max_scope_size", &uint_setting)) { - if (uint_setting < EXT_VARIABLES_REQUIRED_MAX_SCOPE_SIZE) { - e_warning(svinst->event, "variables: " - "setting sieve_variables_max_scope_size " - "is lower than required by standards " - "(>= %llu items)", - (unsigned long long) - EXT_VARIABLES_REQUIRED_MAX_SCOPE_SIZE); - } else { - extctx->max_scope_size = (unsigned int)uint_setting; - } + if (settings_get(svinst->event, &ext_variables_setting_parser_info, 0, + &set, &error) < 0) { + e_error(svinst->event, "%s", error); + return -1; } - if (sieve_setting_get_size_value( - svinst, "sieve_variables_max_variable_size", &size_setting)) { - if (size_setting < EXT_VARIABLES_REQUIRED_MAX_VARIABLE_SIZE) { - e_warning(svinst->event, "variables: " - "setting sieve_variables_max_variable_size " - "is lower than required by standards " - "(>= %zu bytes)", - (size_t)EXT_VARIABLES_REQUIRED_MAX_VARIABLE_SIZE); - } else { - extctx->max_variable_size = size_setting; - } - } + extctx = i_new(struct ext_variables_context, 1); + extctx->set = set; *context_r = extctx; return 0; @@ -100,6 +75,9 @@ void ext_variables_unload(const struct sieve_extension *ext) { struct ext_variables_context *extctx = ext->context; + if (extctx == NULL) + return; + settings_free(extctx->set); i_free(extctx); } @@ -627,8 +605,8 @@ bool sieve_variable_assign(struct sieve_variable_storage *storage, str_append_str(varval, value); /* Just a precaution, caller should prevent this in the first place */ - if (str_len(varval) > extctx->max_variable_size) - str_truncate_utf8(varval, extctx->max_variable_size); + if (str_len(varval) > extctx->set->max_variable_size) + str_truncate_utf8(varval, extctx->set->max_variable_size); return TRUE; } @@ -647,8 +625,8 @@ bool sieve_variable_assign_cstr(struct sieve_variable_storage *storage, str_append(varval, value); /* Just a precaution, caller should prevent this in the first place */ - if (str_len(varval) > extctx->max_variable_size) - str_truncate_utf8(varval, extctx->max_variable_size); + if (str_len(varval) > extctx->set->max_variable_size) + str_truncate_utf8(varval, extctx->set->max_variable_size); return TRUE; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.h b/src/lib-sieve/plugins/variables/ext-variables-common.h index 16c6dab9a39d529792b848a2acba1414d120ed18..5a389a26bf6b806d3fd7762b895e929a7cc2c0c4 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.h +++ b/src/lib-sieve/plugins/variables/ext-variables-common.h @@ -5,16 +5,14 @@ #include "sieve-validator.h" #include "sieve-ext-variables.h" +#include "ext-variables-settings.h" /* * Extension */ struct ext_variables_context { - /* Maximum number of variables (in a scope) */ - unsigned int max_scope_size; - /* Maximum size of variable value */ - size_t max_variable_size; + const struct ext_variables_settings *set; }; extern const struct sieve_extension_def variables_extension; diff --git a/src/lib-sieve/plugins/variables/ext-variables-limits.h b/src/lib-sieve/plugins/variables/ext-variables-limits.h index 61260c8223f78f55122707e17cabdedcb6ee6bcf..c525c176e7b12fe41565c74ecf1977a847df9542 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-limits.h +++ b/src/lib-sieve/plugins/variables/ext-variables-limits.h @@ -21,9 +21,6 @@ * as a syntax error, which SHOULD be discovered at compile-time. */ -#define EXT_VARIABLES_DEFAULT_MAX_SCOPE_SIZE 255 -#define EXT_VARIABLES_DEFAULT_MAX_VARIABLE_SIZE (4 * 1024) - #define EXT_VARIABLES_REQUIRED_MAX_SCOPE_SIZE 128 #define EXT_VARIABLES_REQUIRED_MAX_VARIABLE_SIZE 4000 diff --git a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c index 37ebe920b52568fd1850a5c6dd49458a506ead78..b48c8ce9ad97d7f8f119e5d84752b7cae3f0cb46 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c +++ b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c @@ -545,12 +545,13 @@ int sieve_variables_modifiers_apply( unsigned int i, modf_count; /* Hold value within limits */ - if (str_len(*value) > extctx->max_variable_size) { + if (str_len(*value) > extctx->set->max_variable_size) { /* assume variable originates from code, so copy it first */ - string_t *new_value = t_str_new(extctx->max_variable_size+3); + string_t *new_value = + t_str_new(extctx->set->max_variable_size+3); str_append_str(new_value, *value); *value = new_value; - str_truncate_utf8(*value, extctx->max_variable_size); + str_truncate_utf8(*value, extctx->set->max_variable_size); } if (!array_is_created(modifiers)) @@ -580,9 +581,9 @@ int sieve_variables_modifiers_apply( str_sanitize(str_c(new_value), 256)); /* Hold value within limits */ - if (str_len(*value) > extctx->max_variable_size) { - str_truncate_utf8(*value, - extctx->max_variable_size); + if (str_len(*value) > extctx->set->max_variable_size) { + str_truncate_utf8( + *value, extctx->set->max_variable_size); } } } diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c index 6e4d28c645f00bfde73b3ba0fe17f00fe89de9c7..1f2a46b270ee49fc4370ae098d6685efed078738 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.c +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c @@ -278,9 +278,10 @@ opr_match_value_read(const struct sieve_runtime_env *renv, if (*str_r == NULL) *str_r = t_str_new(0); - else if (str_len(*str_r) > extctx->max_variable_size) { - str_truncate_utf8(*str_r, - extctx->max_variable_size); + else if (str_len(*str_r) > + extctx->set->max_variable_size) { + str_truncate_utf8( + *str_r, extctx->set->max_variable_size); } } return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/plugins/variables/ext-variables-settings.c b/src/lib-sieve/plugins/variables/ext-variables-settings.c new file mode 100644 index 0000000000000000000000000000000000000000..c2615b357e73dc8d906e8dc6fe8a36b957f644fd --- /dev/null +++ b/src/lib-sieve/plugins/variables/ext-variables-settings.c @@ -0,0 +1,74 @@ +/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file + */ + +#include "lib.h" +#include "array.h" +#include "settings.h" +#include "settings-parser.h" + +#include "ext-variables-limits.h" +#include "ext-variables-settings.h" + +static bool +ext_variables_settings_check(void *_set, pool_t pool ATTR_UNUSED, + const char **error_r); + +#undef DEF +#define DEF(type, name) \ + SETTING_DEFINE_STRUCT_##type("sieve_variables_"#name, name, \ + struct ext_variables_settings) + +static const struct setting_define ext_variables_setting_defines[] = { + DEF(UINT, max_scope_size), + DEF(SIZE, max_variable_size), + + SETTING_DEFINE_LIST_END, +}; + +static const struct ext_variables_settings ext_variables_default_settings = { + .max_scope_size = 255, + .max_variable_size = (4 * 1024), +}; + +const struct setting_parser_info ext_variables_setting_parser_info = { + .name = "sieve_variables", + + .defines = ext_variables_setting_defines, + .defaults = &ext_variables_default_settings, + + .struct_size = sizeof(struct ext_variables_settings), + + .check_func = ext_variables_settings_check, + + .pool_offset1 = 1 + offsetof(struct ext_variables_settings, pool), +}; + +/* <settings checks> */ +static bool +ext_variables_settings_check(void *_set, pool_t pool ATTR_UNUSED, + const char **error_r) +{ + struct ext_variables_settings *set = _set; + + if (set->max_scope_size < EXT_VARIABLES_REQUIRED_MAX_SCOPE_SIZE) { + *error_r = t_strdup_printf( + "Setting sieve_variables_max_scope_size " + "is lower than required by standards " + "(>= %llu items)", + (unsigned long long) + EXT_VARIABLES_REQUIRED_MAX_SCOPE_SIZE); + return FALSE; + } + if (set->max_variable_size < EXT_VARIABLES_REQUIRED_MAX_VARIABLE_SIZE) { + *error_r = t_strdup_printf( + "Setting sieve_variables_max_variable_size " + "is lower than required by standards " + "(>= %zu bytes)", + (size_t)EXT_VARIABLES_REQUIRED_MAX_VARIABLE_SIZE); + return FALSE; + } + + return TRUE; +} +/* </settings checks> */ + diff --git a/src/lib-sieve/plugins/variables/ext-variables-settings.h b/src/lib-sieve/plugins/variables/ext-variables-settings.h new file mode 100644 index 0000000000000000000000000000000000000000..4ba9eae9f31212a38f06c9711692b09f62b42152 --- /dev/null +++ b/src/lib-sieve/plugins/variables/ext-variables-settings.h @@ -0,0 +1,15 @@ +#ifndef EXT_VARIABLES_SETTINGS_H +#define EXT_VARIABLES_SETTINGS_H + +struct ext_variables_settings { + pool_t pool; + + /* Maximum number of variables (in a scope) */ + unsigned int max_scope_size; + /* Maximum size of variable value */ + size_t max_variable_size; +}; + +extern const struct setting_parser_info ext_variables_setting_parser_info; + +#endif