sizeof(struct rspamd_regexp_map_pending));
}
+ /* Replace existing entry with the same name to avoid stale re_map pointers
+ * after map reload (the old re_map gets destroyed but the pending entry
+ * would still reference it, causing use-after-free) */
+ for (unsigned int i = 0; i < pending_regexp_maps->len; i++) {
+ struct rspamd_regexp_map_pending *existing;
+
+ existing = &g_array_index(pending_regexp_maps,
+ struct rspamd_regexp_map_pending, i);
+ if (strcmp(existing->name, name) == 0) {
+ existing->re_map = re_map;
+ rspamd_regexp_map_get_hash(re_map, existing->hash);
+
+ msg_info_map("updated pending regexp map '%s' (%ud patterns) in compilation queue",
+ name, re_map->regexps ? re_map->regexps->len : 0);
+ return;
+ }
+ }
+
entry.re_map = re_map;
entry.name = g_strdup(name);
rspamd_regexp_map_get_hash(re_map, entry.hash);
sizeof(struct rspamd_multipattern_pending));
}
+ /* Replace existing entry with the same name to avoid stale mp pointers
+ * after reload (the old mp gets destroyed but the pending entry
+ * would still reference it, causing use-after-free) */
+ for (unsigned int i = 0; i < pending_compilations->len; i++) {
+ struct rspamd_multipattern_pending *existing;
+
+ existing = &g_array_index(pending_compilations,
+ struct rspamd_multipattern_pending, i);
+ if (strcmp(existing->name, name) == 0) {
+ existing->mp = mp;
+ rspamd_multipattern_get_hash(mp, existing->hash);
+
+ msg_info("updated pending multipattern '%s' (%ud patterns) in compilation queue",
+ name, mp->cnt);
+ return;
+ }
+ }
+
entry.mp = mp;
entry.name = g_strdup(name);
rspamd_multipattern_get_hash(mp, entry.hash);