Merge pull request #2805 from michaelstingl/fix-2804-email-double-escape

fix(notifications): don't re-escape email vars for each recipient
This commit is contained in:
Ralf Haferkamp
2026-05-21 11:33:56 +02:00
committed by GitHub
3 changed files with 38 additions and 3 deletions
@@ -0,0 +1,9 @@
Bugfix: Don't re-escape notification email vars for each recipient
When a notification went to several recipients in one call (e.g. a group
invite to a space), each recipient past the first got subjects and bodies
with one extra layer of HTML escaping. escapeStringMap mutated its input
map, and the recipient loop reused the same map across iterations. It now
returns a new map.
https://github.com/opencloud-eu/opencloud/issues/2804
+4 -3
View File
@@ -204,8 +204,9 @@ func validateMime(incipit []byte) bool {
}
func escapeStringMap(vars map[string]string) map[string]string {
for k := range vars {
vars[k] = html.EscapeString(vars[k])
escaped := make(map[string]string, len(vars))
for k, v := range vars {
escaped[k] = html.EscapeString(v)
}
return vars
return escaped
}
@@ -0,0 +1,25 @@
package email
import "testing"
// Regression for #2804: escapeStringMap used to mutate its input map, and the
// recipient render loop reuses that map across iterations.
func TestEscapeStringMapDoesNotMutateInput(t *testing.T) {
const raw = "Test & Demo"
input := map[string]string{"SpaceName": raw}
first := escapeStringMap(input)
second := escapeStringMap(input)
if got, want := first["SpaceName"], "Test & Demo"; got != want {
t.Errorf("first call: got %q, want %q", got, want)
}
if first["SpaceName"] != second["SpaceName"] {
t.Errorf("escapeStringMap not idempotent on shared input: first=%q second=%q",
first["SpaceName"], second["SpaceName"])
}
if input["SpaceName"] != raw {
t.Errorf("escapeStringMap mutated its input: got %q, want %q",
input["SpaceName"], raw)
}
}