This commit is contained in:
yuin 2023-07-23 22:07:27 +09:00
parent 31ccfc4039
commit 254b9f8f77
5 changed files with 52 additions and 9 deletions

View file

@ -752,3 +752,22 @@ a <!-- b -->
<pre> <pre>
</pre> </pre>
//= = = = = = = = = = = = = = = = = = = = = = = =// //= = = = = = = = = = = = = = = = = = = = = = = =//
59: Raw HTML tag with one new line
//- - - - - - - - -//
<img src=./.assets/logo.svg
/>
//- - - - - - - - -//
<p><img src=./.assets/logo.svg
/></p>
//= = = = = = = = = = = = = = = = = = = = = = = =//
60: Raw HTML tag with multiple new lines
//- - - - - - - - -//
<img src=./.assets/logo.svg
/>
//- - - - - - - - -//
<p>&lt;img src=./.assets/logo.svg</p>
<p>/&gt;</p>
//= = = = = = = = = = = = = = = = = = = = = = = =//

View file

@ -203,3 +203,19 @@ func TestManyCommentPerformance(t *testing.T) {
t.Error("Parsing processing instructions took too long") t.Error("Parsing processing instructions took too long")
} }
} }
func TestDangerousURLStringCase(t *testing.T) {
markdown := New()
source := []byte(`[Basic](javascript:alert('Basic'))
[CaseInsensitive](JaVaScRiPt:alert('CaseInsensitive'))
`)
expected := []byte(`<p><a href="">Basic</a>
<a href="">CaseInsensitive</a></p>
`)
var b bytes.Buffer
_ = markdown.Convert(source, &b)
if !bytes.Equal(expected, b.Bytes()) {
t.Error("Dangerous URL should ignore cases:\n" + string(testutil.DiffPretty(expected, b.Bytes())))
}
}

View file

@ -48,10 +48,10 @@ func (s *rawHTMLParser) Parse(parent ast.Node, block text.Reader, pc Context) as
} }
var tagnamePattern = `([A-Za-z][A-Za-z0-9-]*)` var tagnamePattern = `([A-Za-z][A-Za-z0-9-]*)`
var spaceOrOneNewline = `(?:[ \t]|(?:\r\n|\n){0,1})`
var attributePattern = `(?:[\r\n \t]+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:[\r\n \t]*=[\r\n \t]*(?:[^\"'=<>` + "`" + `\x00-\x20]+|'[^']*'|"[^"]*"))?)` var attributePattern = `(?:[\r\n \t]+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:[\r\n \t]*=[\r\n \t]*(?:[^\"'=<>` + "`" + `\x00-\x20]+|'[^']*'|"[^"]*"))?)`
var openTagRegexp = regexp.MustCompile("^<" + tagnamePattern + attributePattern + `*[ \t]*/?>`) var openTagRegexp = regexp.MustCompile("^<" + tagnamePattern + attributePattern + `*` + spaceOrOneNewline + `*/?>`)
var closeTagRegexp = regexp.MustCompile("^</" + tagnamePattern + `\s*>`) var closeTagRegexp = regexp.MustCompile("^</" + tagnamePattern + spaceOrOneNewline + `*>`)
var openProcessingInstruction = []byte("<?") var openProcessingInstruction = []byte("<?")
var closeProcessingInstruction = []byte("?>") var closeProcessingInstruction = []byte("?>")

View file

@ -901,20 +901,24 @@ var bVb = []byte("vbscript:")
var bFile = []byte("file:") var bFile = []byte("file:")
var bData = []byte("data:") var bData = []byte("data:")
func hasPrefix(s, prefix []byte) bool {
return len(s) >= len(prefix) && bytes.Equal(bytes.ToLower(s[0:len(prefix)]), bytes.ToLower(prefix))
}
// IsDangerousURL returns true if the given url seems a potentially dangerous url, // IsDangerousURL returns true if the given url seems a potentially dangerous url,
// otherwise false. // otherwise false.
func IsDangerousURL(url []byte) bool { func IsDangerousURL(url []byte) bool {
if bytes.HasPrefix(url, bDataImage) && len(url) >= 11 { if hasPrefix(url, bDataImage) && len(url) >= 11 {
v := url[11:] v := url[11:]
if bytes.HasPrefix(v, bPng) || bytes.HasPrefix(v, bGif) || if hasPrefix(v, bPng) || hasPrefix(v, bGif) ||
bytes.HasPrefix(v, bJpeg) || bytes.HasPrefix(v, bWebp) || hasPrefix(v, bJpeg) || hasPrefix(v, bWebp) ||
bytes.HasPrefix(v, bSvg) { hasPrefix(v, bSvg) {
return false return false
} }
return true return true
} }
return bytes.HasPrefix(url, bJs) || bytes.HasPrefix(url, bVb) || return hasPrefix(url, bJs) || hasPrefix(url, bVb) ||
bytes.HasPrefix(url, bFile) || bytes.HasPrefix(url, bData) hasPrefix(url, bFile) || hasPrefix(url, bData)
} }
func nodeToHTMLText(n ast.Node, source []byte) []byte { func nodeToHTMLText(n ast.Node, source []byte) []byte {

View file

@ -554,6 +554,10 @@ func findSubMatchReader(r Reader, reg *regexp.Regexp) [][]byte {
bs := bb.Bytes() bs := bb.Bytes()
var result [][]byte var result [][]byte
for i := 0; i < len(match); i += 2 { for i := 0; i < len(match); i += 2 {
if match[i] < 0 {
result = append(result, []byte{})
continue
}
result = append(result, bs[match[i]:match[i+1]]) result = append(result, bs[match[i]:match[i+1]])
} }