vendor/github.com/russross/blackfriday/v2/esc.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
--- a/vendor/github.com/russross/blackfriday/v2/esc.go	Tue Aug 23 22:33:28 2022 +0200
+++ b/vendor/github.com/russross/blackfriday/v2/esc.go	Tue Aug 23 22:39:43 2022 +0200
@@ -13,13 +13,27 @@
 }
 
 func escapeHTML(w io.Writer, s []byte) {
+	escapeEntities(w, s, false)
+}
+
+func escapeAllHTML(w io.Writer, s []byte) {
+	escapeEntities(w, s, true)
+}
+
+func escapeEntities(w io.Writer, s []byte, escapeValidEntities bool) {
 	var start, end int
 	for end < len(s) {
 		escSeq := htmlEscaper[s[end]]
 		if escSeq != nil {
-			w.Write(s[start:end])
-			w.Write(escSeq)
-			start = end + 1
+			isEntity, entityEnd := nodeIsEntity(s, end)
+			if isEntity && !escapeValidEntities {
+				w.Write(s[start : entityEnd+1])
+				start = entityEnd + 1
+			} else {
+				w.Write(s[start:end])
+				w.Write(escSeq)
+				start = end + 1
+			}
 		}
 		end++
 	}
@@ -28,6 +42,28 @@
 	}
 }
 
+func nodeIsEntity(s []byte, end int) (isEntity bool, endEntityPos int) {
+	isEntity = false
+	endEntityPos = end + 1
+
+	if s[end] == '&' {
+		for endEntityPos < len(s) {
+			if s[endEntityPos] == ';' {
+				if entities[string(s[end:endEntityPos+1])] {
+					isEntity = true
+					break
+				}
+			}
+			if !isalnum(s[endEntityPos]) && s[endEntityPos] != '&' && s[endEntityPos] != '#' {
+				break
+			}
+			endEntityPos++
+		}
+	}
+
+	return isEntity, endEntityPos
+}
+
 func escLink(w io.Writer, text []byte) {
 	unesc := html.UnescapeString(string(text))
 	escapeHTML(w, []byte(unesc))