Skip to content

Commit

Permalink
fix: uRL-escaping should be left alone inside the destination
Browse files Browse the repository at this point in the history
By the Rule "URL-escaping should be left alone inside the destination", Reimplement
`normalizeLinkDestination` util function with splitting by URL escapings and concat them
  • Loading branch information
mym0404 committed Mar 18, 2024
1 parent 9190b6b commit 368db1c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
28 changes: 21 additions & 7 deletions lib/src/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,31 @@ String normalizeLinkLabel(String label) {
}

/// Normalizes a link destination, including the process of HTML characters
/// decoding and percent encoding.
/// decoding and percent encoding.
// See the description of these examples:
// https://spec.commonmark.org/0.30/#example-501
// https://spec.commonmark.org/0.30/#example-502
String normalizeLinkDestination(String destination) {
// Decode first, because the destination might have been partly encoded.
// For example https://spec.commonmark.org/0.30/#example-502.
// With this function, `foo%20bä` will be parsed in the following steps:
// 1. foo bä
// 2. foo bä
// 3. foo%20b%C3%A4
// Split by url escaping characters
// Concat them with unmodified URL-escaping.
// URL-escaping should be left alone inside the destination
// Refer: https://spec.commonmark.org/0.30/#example-502.

final regex = RegExp('%[0-9A-Fa-f]{2}');
final matches = regex.allMatches(destination).toList();
final substrings = destination
.split(regex)
.map((e) => Uri.encodeFull(decodeHtmlCharacters(e)))
.toList();

final buffer = StringBuffer(substrings[0]);
for (var i = 0; i < matches.length; i++) {
buffer.write(matches[i].match);
buffer.write(substrings[i + 1]);
}

return buffer.toString();

try {
destination = Uri.decodeFull(destination);
} catch (_) {}
Expand Down
6 changes: 5 additions & 1 deletion test/original/inline_images.unit
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@
![Uh oh...]("onerror="alert('XSS'))

<<<
<p><img src="%22onerror=%22alert('XSS')" alt="Uh oh..." /></p>
<p><img src="%22onerror=%22alert('XSS')" alt="Uh oh..." /></p>
>>> image %2F shouldn't be encoded
![](https://example/foo%2Fvar)
<<<
<p><img src="https://example/foo%2Fvar" alt="" /></p>

0 comments on commit 368db1c

Please sign in to comment.