@@ -32,7 +32,11 @@ Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, {
32
32
tagNameRegex = / [ 0 - 9 a - z A - Z ] [ 0 - 9 a - z A - Z : ] * / ,
33
33
attrNameRegex = / [ ^ \s " ' > \/ = \x00 - \x1F \x7F ] + / , // the unicode range accounts for excluding control chars, and the delete char
34
34
attrValueRegex = / (?: " [ ^ " ] * ?" | ' [ ^ ' ] * ?' | [ ^ ' " = < > ` \s ] + ) / , // double quoted, single quoted, or unquoted attribute values
35
- nameEqualsValueRegex = attrNameRegex . source + '(?:\\s*=\\s*' + attrValueRegex . source + ')?' ; // optional '=[value]'
35
+ optionalAttrValueRegex = '(?:\\s*?=\\s*?' + attrValueRegex . source + ')?' ; // optional '=[value]'
36
+
37
+ var getNameEqualsValueRegex = function ( group ) {
38
+ return '(?=(' + attrNameRegex . source + '))\\' + group + optionalAttrValueRegex ;
39
+ } ;
36
40
37
41
return new RegExp ( [
38
42
// for <!DOCTYPE> tag. Ex: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">)
@@ -46,7 +50,8 @@ Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, {
46
50
// Either:
47
51
// A. attr="value", or
48
52
// B. "value" alone (To cover example doctype tag: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">)
49
- '(?:' , nameEqualsValueRegex , '|' , attrValueRegex . source + ')' ,
53
+ // *** Capturing Group 2 - Pseudo-atomic group for attrNameRegex
54
+ '(?:' , getNameEqualsValueRegex ( 2 ) , '|' , attrValueRegex . source + ')' ,
50
55
')*' ,
51
56
'>' ,
52
57
')' ,
@@ -56,10 +61,10 @@ Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, {
56
61
// All other HTML tags (i.e. tags that are not <!DOCTYPE>)
57
62
'(?:' ,
58
63
'<(/)?' , // Beginning of a tag or comment. Either '<' for a start tag, or '</' for an end tag.
59
- // *** Capturing Group 2 : The slash or an empty string. Slash ('/') for end tag, empty string for start or self-closing tag.
64
+ // *** Capturing Group 3 : The slash or an empty string. Slash ('/') for end tag, empty string for start or self-closing tag.
60
65
61
66
'(?:' ,
62
- commentTagRegex . source , // *** Capturing Group 3 - A Comment Tag's Text
67
+ commentTagRegex . source , // *** Capturing Group 4 - A Comment Tag's Text
63
68
64
69
'|' ,
65
70
@@ -68,7 +73,7 @@ Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, {
68
73
// to fix a regex time complexity issue seen with the
69
74
// example in https://github.com/gregjacobs/Autolinker.js/issues/172
70
75
'(?:' ,
71
- // *** Capturing Group 4 - The tag name for a tag without attributes
76
+ // *** Capturing Group 5 - The tag name for a tag without attributes
72
77
'(' + tagNameRegex . source + ')' ,
73
78
74
79
'\\s*/?' , // any trailing spaces and optional '/' before the closing '>'
@@ -81,15 +86,16 @@ Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, {
81
86
// to fix a regex time complexity issue seen with the
82
87
// example in https://github.com/gregjacobs/Autolinker.js/issues/172
83
88
'(?:' ,
84
- // *** Capturing Group 5 - The tag name for a tag with attributes
89
+ // *** Capturing Group 6 - The tag name for a tag with attributes
85
90
'(' + tagNameRegex . source + ')' ,
86
91
87
92
'\\s+' , // must have at least one space after the tag name to prevent ReDoS issue (issue #172)
88
93
89
94
// Zero or more attributes following the tag name
90
95
'(?:' ,
91
96
'(?:\\s+|\\b)' , // any number of whitespace chars before an attribute. NOTE: Using \s* here throws Chrome into an infinite loop for some reason, so using \s+|\b instead
92
- nameEqualsValueRegex , // attr="value" (with optional ="value" part)
97
+ // *** Capturing Group 7 - Pseudo-atomic group for attrNameRegex
98
+ getNameEqualsValueRegex ( 7 ) , // attr="value" (with optional ="value" part)
93
99
')*' ,
94
100
95
101
'\\s*/?' , // any trailing spaces and optional '/' before the closing '>'
@@ -127,9 +133,9 @@ Autolinker.htmlParser.HtmlParser = Autolinker.Util.extend( Object, {
127
133
128
134
while ( ( currentResult = htmlRegex . exec ( html ) ) !== null ) {
129
135
var tagText = currentResult [ 0 ] ,
130
- commentText = currentResult [ 3 ] , // if we've matched a comment
131
- tagName = currentResult [ 1 ] || currentResult [ 4 ] || currentResult [ 5 ] , // The <!DOCTYPE> tag (ex: "!DOCTYPE"), or another tag (ex: "a" or "img")
132
- isClosingTag = ! ! currentResult [ 2 ] ,
136
+ commentText = currentResult [ 4 ] , // if we've matched a comment
137
+ tagName = currentResult [ 1 ] || currentResult [ 5 ] || currentResult [ 6 ] , // The <!DOCTYPE> tag (ex: "!DOCTYPE"), or another tag (ex: "a" or "img")
138
+ isClosingTag = ! ! currentResult [ 3 ] ,
133
139
offset = currentResult . index ,
134
140
inBetweenTagsText = html . substring ( lastIndex , offset ) ;
135
141
0 commit comments