diff --git a/OpenDreamClient/Interface/Html/HtmlParser.cs b/OpenDreamClient/Interface/Html/HtmlParser.cs
index 8d3b2904df..6be483a5ca 100644
--- a/OpenDreamClient/Interface/Html/HtmlParser.cs
+++ b/OpenDreamClient/Interface/Html/HtmlParser.cs
@@ -1,6 +1,8 @@
-using System.Text;
-using OpenDreamShared.Dream;
+using OpenDreamShared.Dream;
using Robust.Shared.Utility;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
namespace OpenDreamClient.Interface.Html;
@@ -11,6 +13,9 @@ public static class HtmlParser {
private static readonly ISawmill Sawmill;
private static readonly HashSet WarnedAttributes = new();
+ private static Regex? _attributeMatchRegex;
+ private static Regex AttributeMatchRegex => _attributeMatchRegex ??= new Regex(@"[^ =]+(?:=(?:\w+|""[^""]*""|'[^']*'))?");
+
static HtmlParser() {
Sawmill = IoCManager.Resolve().GetSawmill("opendream.html_parser");
}
@@ -33,6 +38,11 @@ void PushCurrentText() {
currentText.Clear();
}
+ void SkipComment() {
+ while ((i - 2 < 0 || (text[i - 2] != '-' || text[i - 1] != '-' || text[i] != '>')) && text.Length > 2)
+ i++;
+ }
+
for (i = 0; i < text.Length; i++) {
char c = text[i];
@@ -67,7 +77,10 @@ void PushCurrentText() {
}
string insideTag = currentText.ToString();
- string[] attributes = insideTag.Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ string[] attributes = AttributeMatchRegex.Matches(insideTag)
+ .Where(x => x.Length > 0)
+ .Select(x => x.Value)
+ .ToArray();
string tagType = attributes[0].ToLowerInvariant();
currentText.Clear();
@@ -98,6 +111,12 @@ void PushCurrentText() {
appendTo.Pop();
tags.Pop();
} else {
+ // If a comment contained other HTML tags, we need to make sure those also
+ // get skipped.
+ if (tagType == "!--") {
+ SkipComment();
+ continue;
+ }
if (!isSelfClosing) {
tags.Push(tagType);
}
@@ -123,7 +142,7 @@ void PushCurrentText() {
if (insideEntity.StartsWith('#')) {
if (int.TryParse(insideEntity.Substring(1), out int result)) {
- currentText.Append((char) result);
+ currentText.Append((char)result);
}
} else {
switch (insideEntity) {