Skip to content

Commit f2b722b

Browse files
committed
Fixed logic for validating HTML Tag and Attribute names
Apparently, < is a valid tag name character based on the HTML5 tokenizer specification. Fixes #1136
1 parent 9787693 commit f2b722b

File tree

4 files changed

+32
-11
lines changed

4 files changed

+32
-11
lines changed

MimeKit/Text/HtmlAttribute.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public HtmlAttribute (string name, string value)
8080
if (name.Length == 0)
8181
throw new ArgumentException ("The attribute name cannot be empty.", nameof (name));
8282

83-
if (!HtmlUtils.IsValidTokenName (name))
83+
if (!HtmlUtils.IsValidAttributeName (name))
8484
throw new ArgumentException ("Invalid attribute name.", nameof (name));
8585

8686
Value = value;

MimeKit/Text/HtmlUtils.cs

+21-6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ namespace MimeKit.Text {
3737
/// </remarks>
3838
public static class HtmlUtils
3939
{
40+
// https://dev.w3.org/html5/spec-LC/tokenization.html#attribute-name-state
41+
static readonly string InvalidAttributeNameCharacters = "\0\t\r\n\f /=>\"\'<";
42+
43+
// https://dev.w3.org/html5/spec-LC/tokenization.html#tag-name-state
44+
static readonly string InvalidTagNameCharacters = "\0\t\r\n\f />";
45+
4046
#if NETSTANDARD2_0 || NETFRAMEWORK
4147
static void Write (this TextWriter writer, ReadOnlySpan<char> value)
4248
{
@@ -51,18 +57,27 @@ static void Write (this TextWriter writer, ReadOnlySpan<char> value)
5157
}
5258
#endif
5359

54-
internal static bool IsValidTokenName (string name)
60+
internal static bool IsValidAttributeName (string name)
5561
{
5662
if (string.IsNullOrEmpty (name))
5763
return false;
5864

5965
for (int i = 0; i < name.Length; i++) {
60-
switch (name[i]) {
61-
case '\t': case '\r': case '\n': case '\f': case ' ':
62-
case '<': case '>': case '\'': case '"':
63-
case '/': case '=':
66+
if (InvalidAttributeNameCharacters.IndexOf (name[i]) != -1)
67+
return false;
68+
}
69+
70+
return true;
71+
}
72+
73+
internal static bool IsValidTagName (string name)
74+
{
75+
if (string.IsNullOrEmpty (name))
76+
return false;
77+
78+
for (int i = 0; i < name.Length; i++) {
79+
if (InvalidTagNameCharacters.IndexOf (name[i]) != -1)
6480
return false;
65-
}
6681
}
6782

6883
return true;

MimeKit/Text/HtmlWriter.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static void ValidateAttributeName (string name)
135135
if (name.Length == 0)
136136
throw new ArgumentException ("The attribute name cannot be empty.", nameof (name));
137137

138-
if (!HtmlUtils.IsValidTokenName (name))
138+
if (!HtmlUtils.IsValidAttributeName (name))
139139
throw new ArgumentException ($"Invalid attribute name: {name}", nameof (name));
140140
}
141141

@@ -147,7 +147,7 @@ static void ValidateTagName (string name)
147147
if (name.Length == 0)
148148
throw new ArgumentException ("The tag name cannot be empty.", nameof (name));
149149

150-
if (!HtmlUtils.IsValidTokenName (name))
150+
if (!HtmlUtils.IsValidTagName (name))
151151
throw new ArgumentException ($"Invalid tag name: {name}", nameof (name));
152152
}
153153

UnitTests/Text/HtmlUtilsTests.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,15 @@ public void TestHtmlNamespaces ()
267267
}
268268

269269
[Test]
270-
public void TestIsValidTokenName ()
270+
public void TestIsValidAttributeName ()
271271
{
272-
Assert.That (HtmlUtils.IsValidTokenName (string.Empty), Is.False, "string.Empty");
272+
Assert.That (HtmlUtils.IsValidAttributeName (string.Empty), Is.False, "string.Empty");
273+
}
274+
275+
[Test]
276+
public void TestIsValidTagName ()
277+
{
278+
Assert.That (HtmlUtils.IsValidTagName (string.Empty), Is.False, "string.Empty");
273279
}
274280
}
275281
}

0 commit comments

Comments
 (0)