Skip to content

Commit 4b78f59

Browse files
authored
Merge pull request #956 from LeSuisse/fix-autolink-extension-detection
Fix autolink extension URL detection
2 parents 7354509 + ce719fd commit 4b78f59

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi
66

77
## [Unreleased][unreleased]
88

9+
### Fixed
10+
11+
- Fixed autolink extension not detecting some URIs with underscores (#956)
12+
913
## [2.3.8] - 2022-12-10
1014

1115
### Fixed

src/Extension/Autolink/UrlAutolinkParser.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,22 @@ final class UrlAutolinkParser implements InlineParserInterface
2222
{
2323
private const ALLOWED_AFTER = [null, ' ', "\t", "\n", "\x0b", "\x0c", "\x0d", '*', '_', '~', '('];
2424

25-
// RegEx adapted from https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/Validator/Constraints/UrlValidator.php
25+
// RegEx adapted from https://github.com/symfony/symfony/blob/6.3/src/Symfony/Component/Validator/Constraints/UrlValidator.php
2626
private const REGEX = '~
2727
(
2828
# Must start with a supported scheme + auth, or "www"
2929
(?:
30-
(?:%s):// # protocol
31-
(?:([\.\pL\pN-]+:)?([\.\pL\pN-]+)@)? # basic auth
30+
(?:%s):// # protocol
31+
(?:(?:(?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+:)?((?:[\_\.\pL\pN-]|%%[0-9A-Fa-f]{2})+)@)? # basic auth
3232
|www\.)
3333
(?:
34-
(?:[\pL\pN\pS\-\.])+(?:\.?(?:[\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
34+
(?:
35+
(?:xn--[a-z0-9-]++\.)*+xn--[a-z0-9-]++ # a domain name using punycode
36+
|
37+
(?:[\pL\pN\pS\pM\-\_]++\.)+[\pL\pN\pM]++ # a multi-level domain name
38+
|
39+
[a-z0-9\-\_]++ # a single-level domain name
40+
)\.?
3541
| # or
3642
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address
3743
| # or
@@ -40,9 +46,9 @@ final class UrlAutolinkParser implements InlineParserInterface
4046
\] # an IPv6 address
4147
)
4248
(?::[0-9]+)? # a port (optional)
43-
(?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path
44-
(?:\? (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional)
45-
(?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional)
49+
(?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path
50+
(?:\? (?:[\pL\pN\-._\~!$&\'\[\]()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional)
51+
(?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional)
4652
)~ixu';
4753

4854
/**

tests/functional/Extension/Autolink/UrlAutolinkParserTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function dataProviderForAutolinkTests(): iterable
4444
// Basic examples
4545
yield ['You can search on http://google.com for stuff.', '<p>You can search on <a href="http://google.com">http://google.com</a> for stuff.</p>'];
4646
yield ['https://google.com', '<p><a href="https://google.com">https://google.com</a></p>'];
47+
yield ['https://sub_domain.example.com', '<p><a href="https://sub_domain.example.com">https://sub_domain.example.com</a></p>'];
4748
yield ['ftp://example.com', '<p><a href="ftp://example.com">ftp://example.com</a></p>'];
4849
yield ['www.google.com', '<p><a href="http://www.google.com">www.google.com</a></p>'];
4950
yield [' http://leadingwhitespace.example.com', '<p><a href="http://leadingwhitespace.example.com">http://leadingwhitespace.example.com</a></p>'];

0 commit comments

Comments
 (0)