diff --git a/system/types/resource_translation.go b/system/types/resource_translation.go
index cd531f266..5bbaa11c1 100644
--- a/system/types/resource_translation.go
+++ b/system/types/resource_translation.go
@@ -2,8 +2,10 @@ package types
import (
"database/sql/driver"
+ "html"
"strings"
"time"
+ "unicode/utf8"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/locale"
@@ -86,7 +88,7 @@ outer:
Lang: Lang{Tag: language.Make(b.Lang)},
Resource: b.Resource,
K: b.Key,
- Message: b.Msg,
+ Message: sanitizeHtml(b.Msg),
})
}
return
@@ -97,7 +99,7 @@ func (set ResourceTranslationSet) Old(bb locale.ResourceTranslationSet) (out Res
for _, a := range set {
// It's not new
if a.Compare(b) {
- a.Message = b.Msg
+ a.Message = sanitizeHtml(b.Msg)
out = append(out, a)
break
}
@@ -112,9 +114,59 @@ func FromLocale(ll locale.ResourceTranslationSet) (out ResourceTranslationSet) {
Lang: Lang{Tag: language.Make(l.Lang)},
Resource: l.Resource,
K: l.Key,
- Message: l.Msg,
+ Message: sanitizeHtml(l.Msg),
})
}
return out
}
+
+// sanitizeHtml Aggressively strips HTML tags from a string.
+// It will only keep anything between `>` and `<`.
+func sanitizeHtml(s string) string {
+ const (
+ htmlTagStart = 60 // Unicode `<`
+ htmlTagEnd = 62 // Unicode `>`
+ )
+
+ // Unescape string with any html tags
+ s = html.UnescapeString(s)
+
+ // Set up a string builder and allocate enough memory for the new string.
+ var builder strings.Builder
+ builder.Grow(len(s) + utf8.UTFMax)
+
+ in := false // True if we are inside an HTML tag.
+ start := 0 // The index of the previous start tag character `<`
+ end := 0 // The index of the previous end tag character `>`
+
+ for i, c := range s {
+ // If this is the last character, and we are not in an HTML tag, save it.
+ if (i+1) == len(s) && end >= start {
+ builder.WriteString(s[end:])
+ }
+
+ // Keep going if the character is not `<` or `>`
+ if c != htmlTagStart && c != htmlTagEnd {
+ continue
+ }
+
+ if c == htmlTagStart {
+ // Only update the start if we are not in a tag.
+ // This make sure we strip `<
` not just `
`
+ if !in {
+ start = i
+ }
+ in = true
+
+ // Write the valid string between the close and start of the two tags.
+ builder.WriteString(s[end:start])
+ continue
+ }
+ // else c == htmlTagEnd
+ in = false
+ end = i + 1
+ }
+ s = builder.String()
+ return s
+}