summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.adoc1
-rw-r--r--lib/asciidoctor/rx.rb4
-rw-r--r--lib/asciidoctor/substitutors.rb5
-rw-r--r--test/links_test.rb5
4 files changed, 10 insertions, 5 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 4ef2a054..0b4010a7 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -70,6 +70,7 @@ Bug Fixes::
* Don't leave behind empty line inside skipped preprocessor conditional (#4580)
* Don't duplicate block attribute line above detached block that breaks a dlist; fixes duplicate role on detached block (#4565)
+ * Don't crash when parsing xref shorthand if target starts with URL protocol and text is offset by space (#4570)
== 2.0.22 (2024-03-08) - @mojavelinux
diff --git a/lib/asciidoctor/rx.rb b/lib/asciidoctor/rx.rb
index 5ba6ba1f..1d793664 100644
--- a/lib/asciidoctor/rx.rb
+++ b/lib/asciidoctor/rx.rb
@@ -522,9 +522,9 @@ module Asciidoctor
#
if RUBY_ENGINE == 'opal'
# NOTE In JavaScript, a back reference succeeds if not set; invert the logic to give it a match to refute
- InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;(?=\\?(?:https?|file|ftp|irc)(:))|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|(?!\2)([^\s]*?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))
+ InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;(?=\\?(?:https?|file|ftp|irc)(:))|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|(?!\2)([^\s]+?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))
else
- InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;()|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|\2([^\s]*?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
+ InlineLinkRx = %r((^|link:|#{CG_BLANK}|\\?&lt;()|[>\(\)\[\];"'])(\\?(?:https?|file|ftp|irc)://)(?:([^\s\[\]]+)\[(|#{CC_ALL}*?[^\\])\]|\2([^\s]+?)&gt;|([^\s\[\]<]*([^\s,.?!\[\]<\)]))))m
end
# Match a link or e-mail inline macro.
diff --git a/lib/asciidoctor/substitutors.rb b/lib/asciidoctor/substitutors.rb
index 3f5bd6af..e8c6325b 100644
--- a/lib/asciidoctor/substitutors.rb
+++ b/lib/asciidoctor/substitutors.rb
@@ -538,9 +538,8 @@ module Substitutors
# honor the escapes
next $&.slice 1, $&.length if $1.start_with? RS
next %(#{$1}#{$&.slice $1.length + 1, $&.length}) if $3.start_with? RS
- target = $3 + $6
- next $& if target == $3
- doc.register :links, target
+ next $& unless $6
+ doc.register :links, (target = $3 + $6)
link_text = (doc_attrs.key? 'hide-uri-scheme') ? (target.sub UriSniffRx, '') : target
(Inline.new self, :anchor, link_text, type: :link, target: target, attributes: { 'role' => 'bare' }).convert
else
diff --git a/test/links_test.rb b/test/links_test.rb
index 1c8fd4e4..c78b1b9e 100644
--- a/test/links_test.rb
+++ b/test/links_test.rb
@@ -105,6 +105,11 @@ context 'Links' do
assert_xpath '//p[text()="<http://asciidoc.org>"]', convert_string('<\\http://asciidoc.org>'), 1
end
+ test 'xref shorthand with target that starts with URL protocol and has space after comma should not crash parser' do
+ output = convert_string_to_embedded '<<https://example.com, Example>>'
+ assert_include '<a href="#https://example.com">Example</a>', output
+ end
+
test 'autolink containing text enclosed in angle brackets' do
output = convert_string_to_embedded 'https://github.com/<org>/'
assert_include '<a href="https://github.com/&lt;org&gt;/" class="bare">https://github.com/&lt;org&gt;/</a>', output