From dbd48ac5b44c7dcd699e206ce8310d655a3a19ee Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Wed, 3 Aug 2022 10:15:42 +0200 Subject: [PATCH] Fix parsing html tags with starting with slash --- Source/Engine/Utilities/HtmlParser.cs | 40 +++++++++++++------ .../Tools/FlaxEngine.Tests/TestHtmlParser.cs | 19 +++++++++ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/Source/Engine/Utilities/HtmlParser.cs b/Source/Engine/Utilities/HtmlParser.cs index 07296602d..b4ab1e24b 100644 --- a/Source/Engine/Utilities/HtmlParser.cs +++ b/Source/Engine/Utilities/HtmlParser.cs @@ -33,10 +33,20 @@ namespace FlaxEngine.Utilities /// public Dictionary Attributes; + /// + /// True if this tag contained a leading forward slash (begin of the tag). + /// + public bool IsLeadingSlash; + /// /// True if this tag contained a trailing forward slash (end of the tag). /// - public bool IsTrailingSlash; + public bool IsEndingSlash; + + /// + /// True if this tag contained a leading or trailing forward slash. + /// + public bool IsSlash => IsLeadingSlash || IsEndingSlash; }; /// @@ -102,7 +112,6 @@ namespace FlaxEngine.Utilities // Skip opening '<' Move(); - // Examine first tag character char c = Peek(); if (c == '!' && Peek(1) == '-' && Peek(2) == '-') { @@ -112,15 +121,13 @@ namespace FlaxEngine.Utilities NormalizePosition(); Move(endComment.Length); } - else if (c == '/') - { - // Skip over closing tags - _pos = _html.IndexOf('>', _pos); - NormalizePosition(); - Move(); - } else { + // Skip leading slash + bool isLeadingSlash = c == '/'; + if (isLeadingSlash) + Move(); + // Parse tag bool result = ParseTag(ref tag, name); @@ -136,9 +143,16 @@ namespace FlaxEngine.Utilities Move(); } - // Return true if requested tag was found if (result) + { + if (isLeadingSlash) + { + // Tag starts with '/' + tag.StartPosition--; + tag.IsLeadingSlash = true; + } return true; + } } } @@ -188,7 +202,7 @@ namespace FlaxEngine.Utilities { // Handle trailing forward slash if (requested) - tag.IsTrailingSlash = true; + tag.IsEndingSlash = true; Move(); SkipWhitespace(); @@ -250,7 +264,7 @@ namespace FlaxEngine.Utilities private string ParseAttributeName() { int start = _pos; - while (!EOF && !char.IsWhiteSpace(Peek()) && Peek() != '>' && Peek() != '=') + while (!EOF && char.IsLetterOrDigit(Peek())) Move(); return _html.Substring(start, _pos - start); } @@ -284,7 +298,7 @@ namespace FlaxEngine.Utilities { // Parse unquoted value start = _pos; - while (!EOF && !char.IsWhiteSpace(c) && c != '>') + while (!EOF && !char.IsWhiteSpace(c) && c != '>' && c != '/') { Move(); c = Peek(); diff --git a/Source/Tools/FlaxEngine.Tests/TestHtmlParser.cs b/Source/Tools/FlaxEngine.Tests/TestHtmlParser.cs index e48c7e0a6..8ed81478a 100644 --- a/Source/Tools/FlaxEngine.Tests/TestHtmlParser.cs +++ b/Source/Tools/FlaxEngine.Tests/TestHtmlParser.cs @@ -68,8 +68,27 @@ namespace FlaxEngine.Tests return result; } + [TestCase("b", ExpectedResult = false)] + [TestCase("b", ExpectedResult = true)] + [TestCase("b", ExpectedResult = true)] + [TestCase("b", ExpectedResult = true)] + [TestCase("b", ExpectedResult = false)] + [TestCase("b", ExpectedResult = true)] + [TestCase("b", ExpectedResult = true)] + public bool TestEnding(string html) + { + var parser = new HtmlParser(html); + while (parser.ParseNext(out var tag)) + { + return tag.IsSlash; + } + throw new System.Exception(); + } + [TestCase("b", ExpectedResult = 1)] [TestCase("sd b ", ExpectedResult = 5)] + [TestCase("sd b ", ExpectedResult = 5)] + [TestCase("sd b ", ExpectedResult = 5)] public int TestStartPosition(string html) { var parser = new HtmlParser(html);