/* full file size is 7 bytes, which makes the first block size
truncated, since it needs 8 bytes */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x22") // full size
+ NUM64("\x26") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
"\x00\x00\x00\x00\x00\x00\x00"), // block size
"Area too small when reading size of 'block size'" },
/* first block size is 0, which is too small */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x23") // full size
+ NUM64("\x27") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x00")), // block size
"'block name' points outside area" },
/* first block size is 1, but full file size is too small */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x23") // full size
+ NUM64("\x27") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x01")), // block size
"'block size' points outside are" },
/* block name is not NUL-terminated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x25") // full size
+ NUM64("\x29") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x01") // block size
"N"
"\x00"), // trailing garbage so we can have NUL
/* settings count is truncated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x28") // full size
+ NUM64("\x2C") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x05") // block size
"N\x00" // block name
"\x00\x00\x00"),
/* settings keys are truncated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x29") // full size
+ NUM64("\x2D") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x06") // block size
"N\x00" // block name
NUM32("\x01")), // settings count
/* filter count is truncated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x2E") // full size
+ NUM64("\x32") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x0B") // block size
"N\x00" // block name
NUM32("\x01") // settings count
/* filter settings size is truncated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x36") // full size
+ NUM64("\x3A") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x12") // block size
"N\x00" // block name
NUM32("\x01") // settings count
/* filter settings is truncated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x37") // full size
+ NUM64("\x3B") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x14") // block size
"N\x00" // block name
NUM32("\x01") // settings count
"'filter settings size' points outside area" },
/* filter error is missing */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x44") // full size
+ NUM64("\x48") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x21") // block size
"N\x00" // block name
NUM32("\x01") // settings count
"'filter error string' points outside area" },
/* filter error is not NUL-terminated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x52") // full size
+ NUM64("\x56") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x2F") // block size
"master_service\x00" // block name
NUM32("\x01") // settings count
"'filter error string' points outside area" },
/* include group count is truncated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x55") // full size
+ NUM64("\x59") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x32") // block size
"master_service\x00" // block name
NUM32("\x01") // settings count
"Area too small when reading uint of 'include group count'" },
/* include group count is too large */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x56") // full size
+ NUM64("\x5A") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x33") // block size
"master_service\x00" // block name
NUM32("\x01") // settings count
"'group label string' points outside area" },
/* group label not NUL-terminated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x57") // full size
+ NUM64("\x5B") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x34") // block size
"master_service\x00" // block name
NUM32("\x01") // settings count
"'group label string' points outside area" },
/* group name not NUL-terminated */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x59") // full size
+ NUM64("\x5D") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x36") // block size
"master_service\x00" // block name
NUM32("\x01") // settings count
"'group name string' points outside area" },
/* invalid filter string */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x4B") // full size
+ NUM64("\x4F") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"F\x00" // event filter[0]
"F\x00" // override event filter[0]
+ NUM32("\x00") // number of named list filter elements
NUM64("\x26") // block size
"N\x00" // block name
NUM32("\x01") // settings count
/* Duplicate block name */
{ DATA("DOVECOT-CONFIG\t1.0\n"
- NUM64("\x54") // full size
+ NUM64("\x5C") // full size
NUM32("\x00") // cache path count
NUM32("\x0D") // all keys size
"\x00" // 32bit padding
NUM32("\x01") // event filter count
"\x00" // event filter[0]
"\x00" // override event filter[0]
- NUM64("\x27") // block size
+ NUM32("\x00") // number of named list filter elements
+ NUM64("\x2B") // block size
"N\x00" // block name
NUM32("\x01") // settings count
"K\x00" // setting[0] key
NUM64("\x05") // filter settings size
"\x00" // filter error string
NUM32("\x00") // include group count
- "\x00" // 64bit padding
+ "\x00\x00\x00\x00\x00" // 64bit padding
NUM64("\x00") // filter[0] settings offset
NUM32("\x00") // filter[0] event filter index
"\x00" // safety NUL
unsigned int filter_element_count;
/* key += value is used, i.e. append this value to existing value */
bool append;
- /* Always apply this override, regardless of any filters. */
- bool always_match;
bool array_default_added;
/* Original key for the overridden setting, e.g.
namespace/inbox/mailbox/Sent/mail_attribute/dict_driver */
struct event_filter *filter;
struct event_filter *override_filter;
bool is_group;
+
+ uint32_t named_list_filter_count;
};
struct settings_mmap {
static int
settings_instance_override(struct settings_apply_ctx *ctx,
- struct event_filter *event_filter,
+ struct settings_mmap_event_filter *set_filter,
bool *defaults, const char **error_r);
static bool settings_local_name_cmp(const char *value, const char *wanted_value)
"filter string", &filter_string,
error_r) < 0)
return -1;
+ if (i % 2 != 0) {
+ if (settings_block_read_uint32(mmap, offset, mmap->mmap_size,
+ "named list filter element count",
+ &set_filter->named_list_filter_count,
+ error_r) < 0)
+ return -1;
+ }
+
if (filter_string[0] == '\0') {
*filter_dest = EVENT_FILTER_MATCH_ALWAYS;
continue;
override is specifically using the filter name
as prefix. */
bool defaults = FALSE;
- int ret = settings_instance_override(ctx, set_filter->override_filter,
+ int ret = settings_instance_override(ctx, set_filter,
&defaults, error_r);
if (ret < 0)
return -1;
error_r) < 0)
return -1;
if (defaults) {
- ret = settings_instance_override(ctx,
- set_filter->override_filter,
- &defaults, error_r);
+ ret = settings_instance_override(ctx, set_filter,
+ &defaults, error_r);
if (ret < 0)
return -1;
if (ret > 0)
return set2->order - set1->order;
}
+static int
+settings_override_cmp_filter_order(const struct settings_override *set,
+ struct settings_mmap_event_filter *set_filter)
+{
+ return (int)set->filter_array_element_count -
+ (int)set_filter->named_list_filter_count;
+}
+
static bool
settings_mmap_registered_lookup_key(const char *key, enum setting_type *type_r)
{
set, error_r);
if (ret <= 0)
return ret;
+ /* Sort this as the first */
+ set->filter_array_element_count = INT_MAX;
set->filter = EVENT_FILTER_MATCH_ALWAYS;
- set->always_match = TRUE;
return setting_override_match_info(ctx, set) ? 1 : 0;
}
static int
settings_instance_override(struct settings_apply_ctx *ctx,
- struct event_filter *event_filter,
+ struct settings_mmap_event_filter *set_filter,
bool *defaults, const char **error_r)
{
struct settings_apply_override *override;
struct settings_override *set;
- const struct failure_context failure_ctx = {
- .type = LOG_TYPE_DEBUG
- };
enum setting_apply_flags apply_flags = SETTING_APPLY_FLAG_OVERRIDE |
((ctx->flags & SETTINGS_GET_FLAG_NO_EXPAND) == 0 ? 0 :
SETTING_APPLY_FLAG_NO_EXPAND);
/* If we're being called while applying filters, only apply
the overrides that have a matching filter. This preserves
the expected order in which settings are applied. */
- if (!set->always_match &&
- event_filter != EVENT_FILTER_MATCH_ALWAYS &&
- (set->filter_event == NULL ||
- !event_filter_match(event_filter, set->filter_event,
- &failure_ctx)))
- continue;
+ if (set_filter->filter != EVENT_FILTER_MATCH_ALWAYS &&
+ settings_override_cmp_filter_order(set, set_filter) < 0)
+ break;
if (set->type == SETTINGS_OVERRIDE_TYPE_DEFAULT) {
seen_defaults = TRUE;
} else {
/* No configuration file - apply all overrides */
bool defaults = TRUE;
- ret = settings_instance_override(ctx, EVENT_FILTER_MATCH_ALWAYS,
+ struct settings_mmap_event_filter set_filter = {
+ };
+ ret = settings_instance_override(ctx, &set_filter,
&defaults, error_r);
}
if (ret > 0)