Browse Source

Honor markdown escapes when matching inline linkify autolinks.

The inline rule passed raw source to linkify-it, so a backslash before
punctuation (a valid CommonMark escape) truncated the URL at the host,
e.g. https://git\-scm.com became https://git. Unescape before matching
and advance pos by the escaped source length. Fuzzy/email linkify and
escapes that break :// are unchanged.

Fixes #1058
pull/1200/head
Arron Zou 2 months ago
parent
commit
c0df97eeff
  1. 23
      src/rules_inline/linkify.ts
  2. 8
      test/fixtures/markdown-it/linkify.txt

23
src/rules_inline/linkify.ts

@ -1,10 +1,28 @@
// Process links like https://example.org/
import { isMdAsciiPunct, unescapeMd } from '../common/utils.ts'
import type StateInline from './state_inline.ts'
// RFC3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
const SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i
// `\` + ASCII punct is one character after CommonMark unescape.
function srcLengthForUnescaped (src: string, start: number, unescapedLength: number): number {
let i = start
let consumed = 0
while (consumed < unescapedLength && i < src.length) {
if (src.charCodeAt(i) === 0x5C/* \ */ && i + 1 < src.length && isMdAsciiPunct(src.charCodeAt(i + 1))) {
i += 2
} else {
i++
}
consumed++
}
return i - start
}
export default function linkify (state: StateInline, silent: boolean): boolean {
if (!state.md.options.linkify) return false
if (state.linkLevel > 0) return false
@ -22,7 +40,8 @@ export default function linkify (state: StateInline, silent: boolean): boolean {
const proto = match[1]
const link = state.md.linkify.matchAtStart(state.src.slice(pos - proto.length))
// matchAtStart on raw source stops at `\`; unescape so git\-scm.com stays one URL
const link = state.md.linkify.matchAtStart(unescapeMd(state.src.slice(pos - proto.length, max)))
if (!link) return false
let url = link.url
@ -60,6 +79,6 @@ export default function linkify (state: StateInline, silent: boolean): boolean {
token_c.info = 'auto'
}
state.pos += url.length - proto.length
state.pos += srcLengthForUnescaped(state.src, pos, url.length - proto.length)
return true
}

8
test/fixtures/markdown-it/linkify.txt

@ -151,3 +151,11 @@ https://www.sell.fi/sites/default/files/elainlaakarilehti/tieteelliset_artikkeli
.
<p><a href="https://www.sell.fi/sites/default/files/elainlaakarilehti/tieteelliset_artikkelit/kahkonen_t._et_al.canine_pancreatitis-_review.pdf">https://www.sell.fi/sites/default/files/elainlaakarilehti/tieteelliset_artikkelit/kahkonen_t._et_al.canine_pancreatitis-_review.pdf</a></p>
.
linkify escaped characters inside url
.
See https://git\-scm.com/docs/gitignore\#\_pattern\_format.
.
<p>See <a href="https://git-scm.com/docs/gitignore#_pattern_format">https://git-scm.com/docs/gitignore#_pattern_format</a>.</p>
.

Loading…
Cancel
Save