strings = array_get(array, &count);
i_assert(strings[count] == NULL);
#ifdef DEBUG
- i_assert(strings[count+1] == boollist_eol_sentry);
+ i_assert(strings[count+1] == boollist_eol_sentry ||
+ (strings[count+1] == set_array_stop &&
+ strings[count+2] == boollist_eol_sentry));
#endif
}
return strings;
return value;
}
-static void boollist_null_terminate(ARRAY_TYPE(const_string) *array)
+static void boollist_null_terminate(ARRAY_TYPE(const_string) *array, bool stop)
{
array_append_zero(array);
+ if (stop)
+ array_push_back(array, &set_array_stop);
#ifdef DEBUG
array_push_back(array, &boollist_eol_sentry);
array_pop_back(array);
#endif
+ if (stop)
+ array_pop_back(array);
array_pop_back(array);
}
if (!array_is_created(array))
p_array_init(array, ctx->set_pool, 5);
+ else {
+ /* The first element after the visible array is NULL. If the
+ next element after the NULL is set_array_stop, then the
+ boollist should not be modified any further. */
+ unsigned int old_count;
+ const char *const *old_values =
+ array_get(array, &old_count);
+ i_assert(old_values[old_count] == NULL);
+ if (old_values[old_count + 1] == set_array_stop)
+ return 0;
+ }
key = strrchr(key, SETTINGS_SEPARATOR);
if (key == NULL) {
return -1;
}
/* keep it NULL-terminated for each access */
- boollist_null_terminate(array);
+ boollist_null_terminate(array, FALSE);
return 0;
}
key = settings_section_unescape(key + 1);
removal->key_suffix = key;
}
/* keep it NULL-terminated for each access */
- boollist_null_terminate(array);
+ boollist_null_terminate(array, FALSE);
return 0;
}
void settings_parse_array_stop(struct setting_parser_context *ctx,
unsigned int key_idx)
{
- i_assert(ctx->info->defines[key_idx].type == SET_FILTER_ARRAY);
+ i_assert(ctx->info->defines[key_idx].type == SET_FILTER_ARRAY ||
+ ctx->info->defines[key_idx].type == SET_BOOLLIST);
ARRAY_TYPE(const_string) *arr =
PTR_OFFSET(ctx->set_struct, ctx->info->defines[key_idx].offset);
if (!array_is_created(arr))
p_array_init(arr, ctx->set_pool, 1);
- /* Use the next element hidden after the array to keep the stop-state */
- array_push_back(arr, &set_array_stop);
- array_pop_back(arr);
+
+ if (ctx->info->defines[key_idx].type == SET_BOOLLIST)
+ boollist_null_terminate(arr, TRUE);
+ else {
+ /* Use the next element hidden after the array to keep
+ the stop-state */
+ array_push_back(arr, &set_array_stop);
+ array_pop_back(arr);
+ }
}
static int boollist_removal_cmp(const struct boollist_removal *r1,