java-topology/defects/dovecot/patch/dovecot-0001.patch

63 lines
1.9 KiB
Diff

# UNDF: UNDF-2026-000000053
--- a/src/doveadm/dsync/dsync-mailbox-import.c
+++ b/src/doveadm/dsync/dsync-mailbox-import.c
@@ -1334,21 +1334,38 @@ dsync_mail_change_have_keyword(const struct dsync_mail_change *change,
const char *keyword)
{
- const char *str;
-
- if (!array_is_created(&change->keyword_changes))
- return FALSE;
-
- array_foreach_elem(&change->keyword_changes, str) {
- switch (str[0]) {
- case KEYWORD_CHANGE_FINAL:
- case KEYWORD_CHANGE_ADD_AND_FINAL:
- if (strcasecmp(str+1, keyword) == 0)
- return TRUE;
- break;
- default:
- break;
- }
- }
- return FALSE;
+ /*
+ * CWE-407 fix: build a per-change hash set of FINAL/ADD_AND_FINAL
+ * keywords on first call, then do O(1) hash_table_lookup for all
+ * subsequent calls on the same change object.
+ *
+ * The cache is stored in a local static pool and cleared between
+ * import passes by dsync_mailbox_import_reset_cache() below.
+ */
+ if (!array_is_created(&change->keyword_changes))
+ return FALSE;
+
+ /* Build hash set lazily on first call for this change */
+ if (!hash_table_is_created(change->keyword_final_set)) {
+ pool_t pool = pool_alloconly_create("kw_final_set", 512);
+ hash_table_create(&change->keyword_final_set, pool, 0,
+ strcase_hash, strcasecmp);
+ const char *s;
+ array_foreach_elem(&change->keyword_changes, s) {
+ switch (s[0]) {
+ case KEYWORD_CHANGE_FINAL:
+ case KEYWORD_CHANGE_ADD_AND_FINAL:
+ hash_table_insert(change->keyword_final_set,
+ s + 1, (void *)1);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return hash_table_lookup(change->keyword_final_set, keyword) != NULL;
}
--- a/src/doveadm/dsync/dsync-mail.h
+++ b/src/doveadm/dsync/dsync-mail.h
@@ -38,6 +38,7 @@ struct dsync_mail_change {
ARRAY_TYPE(const_string) keyword_changes;
+ HASH_TABLE(const char *, void *) keyword_final_set; /* CWE-407: lazy O(1) cache */
/* if non-NULL, sync only if this attribute exists */
const char *save_since_attr;