diff --git a/src/Framework/Framework/Controls/HtmlWriter.cs b/src/Framework/Framework/Controls/HtmlWriter.cs index 38f3e21973..7c97e590f9 100644 --- a/src/Framework/Framework/Controls/HtmlWriter.cs +++ b/src/Framework/Framework/Controls/HtmlWriter.cs @@ -515,7 +515,7 @@ private static int IndexOfHtmlEncodingChars(string input, int startIndex, bool e // An ambiguous ampersand is a U+0026 AMPERSAND character (&) that is followed by one or more ASCII alphanumerics, followed by a U+003B SEMICOLON character (;), where these characters do not match any of the names given in the named character references section. // so if the next character is not alphanumeric, we can leave it there - if (i == input.Length) + if (i + 1 == input.Length) return i; var nextChar = input[i + 1]; if (IsInRange(nextChar, 'a', 'z') || diff --git a/src/Tests/Runtime/HtmlWriterTests.cs b/src/Tests/Runtime/HtmlWriterTests.cs index e6fdf7aa75..79eb1175f3 100644 --- a/src/Tests/Runtime/HtmlWriterTests.cs +++ b/src/Tests/Runtime/HtmlWriterTests.cs @@ -42,5 +42,38 @@ public void ImgTagWithChildren() }); Assert.AreEqual("
", text); } + + [TestMethod] + public void EscapingAmpersandStringEnd() + { + var text = WriteHtml(a => { + a.AddAttribute("a", "&"); + a.AddAttribute("b", "abc &"); + a.RenderSelfClosingTag("img"); + }); + Assert.AreEqual("", text); + } + + [TestMethod] + public void EscapingAmpersandAllowedUnescaped() + { + var text = WriteHtml(a => { + a.AddAttribute("a", "a & b"); + a.AddAttribute("b", "a && b"); + a.RenderSelfClosingTag("img"); + }); + Assert.AreEqual("", text); + } + + [TestMethod] + public void EscapingAmpersandUnallowed() + { + var text = WriteHtml(a => { + a.AddAttribute("a", "&"); + a.AddAttribute("b", "a&b"); + a.RenderSelfClosingTag("img"); + }); + Assert.AreEqual("", text); + } } }