From 15674723f772cbd43ae71d3b2a248f6f1bb1ead3 Mon Sep 17 00:00:00 2001 From: Vivek Patel Date: Thu, 7 Oct 2021 19:54:08 +0530 Subject: [PATCH] Removes html from translation message string --- system/types/resource_translation.go | 58 ++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) 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 +}