diff --git a/v2/pkg/buildassets/buildassets.go b/v2/pkg/buildassets/buildassets.go
index 6934b98bd00..b1186ffb74b 100644
--- a/v2/pkg/buildassets/buildassets.go
+++ b/v2/pkg/buildassets/buildassets.go
@@ -5,10 +5,10 @@ import (
"embed"
"errors"
"fmt"
+ "html/template"
iofs "io/fs"
"os"
"path/filepath"
- "text/template"
"github.com/leaanthony/gosod"
"github.com/samber/lo"
diff --git a/v2/pkg/buildassets/buildassets_test.go b/v2/pkg/buildassets/buildassets_test.go
new file mode 100644
index 00000000000..f77f73aea11
--- /dev/null
+++ b/v2/pkg/buildassets/buildassets_test.go
@@ -0,0 +1,73 @@
+package buildassets
+
+import (
+ "testing"
+
+ "github.com/wailsapp/wails/v2/internal/project"
+)
+
+func strPtr(s string) *string { return &s }
+
+func TestResolveProjectData_XMLEscaping(t *testing.T) {
+ tests := []struct {
+ name string
+ template string
+ project *project.Project
+ want string
+ }{
+ {
+ name: "ampersand in name",
+ template: `{{.Name}}`,
+ project: &project.Project{
+ Name: "Tom & Jerry",
+ },
+ want: `Tom & Jerry`,
+ },
+ {
+ name: "ampersand in copyright pointer",
+ template: `{{.Info.Copyright}}`,
+ project: &project.Project{
+ Info: project.Info{
+ Copyright: strPtr("Joe & Bill, Inc."),
+ },
+ },
+ want: `Joe & Bill, Inc.`,
+ },
+ {
+ name: "angle brackets in name",
+ template: `{{.Name}}`,
+ project: &project.Project{
+ Name: "",
+ },
+ want: `<script>alert(1)</script>`,
+ },
+ {
+ name: "plain text no escaping needed",
+ template: `{{.Name}}`,
+ project: &project.Project{
+ Name: "MyApp",
+ },
+ want: `MyApp`,
+ },
+ {
+ name: "multiple ampersands",
+ template: `{{.Name}}`,
+ project: &project.Project{
+ Name: "A&B&C & Co",
+ },
+ want: `A&B&C & Co`,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := resolveProjectData([]byte(tt.template), tt.project)
+ if err != nil {
+ t.Fatalf("resolveProjectData() error = %v", err)
+ }
+ if string(got) != tt.want {
+ t.Errorf("resolveProjectData() = %q, want %q", string(got), tt.want)
+ }
+ })
+ }
+}