Skip to content

Commit f47324d

Browse files
authored
Update RegExps in documentation_comment.dart (#3571)
* Update RegExps in documentation_comment.dart Some pure clean-up and simplification. Some "catastrophic backtracking"-protection. One real change, from `[^ ]+` to `\S+`, to not allow tabs or newlines in an unquoted argument. * Update documentation_comment.dart Avoid `{@template }}` being parsed.
1 parent 3e3f9d2 commit f47324d

File tree

1 file changed

+10
-13
lines changed

1 file changed

+10
-13
lines changed

lib/src/model/documentation_comment.dart

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,19 @@ import 'package:meta/meta.dart';
1414
import 'package:path/path.dart' as p show Context;
1515

1616
final _templatePattern = RegExp(
17-
r'[ ]*{@template\s+(.+?)}([\s\S]+?){@endtemplate}[ ]*(\n?)',
18-
multiLine: true);
17+
r'[ ]*\{@template\s+([^\s}].*?)\}([^]+?)\{@endtemplate\}[ ]*(\n?)');
1918
final _htmlPattern = RegExp(
20-
r'[ ]*{@inject-html\s*}([\s\S]+?){@end-inject-html}[ ]*\n?',
21-
multiLine: true);
19+
r'[ ]*\{@inject-html\s*\}([^]+?)\{@end-inject-html\}[ ]*\n?');
2220

2321
/// Matches all tool directives (even some invalid ones). This is so
2422
/// we can give good error messages if the directive is malformed, instead of
2523
/// just silently emitting it as-is.
2624
final _basicToolPattern = RegExp(
27-
r'[ ]*{@tool\s+([^}]+)}\n?([\s\S]+?)\n?{@end-tool}[ ]*\n?',
28-
multiLine: true);
25+
r'[ ]*{@tool\s+([^\s}][^}]*)}\n?([^]+?)\n?{@end-tool}[ ]*\n?');
2926

30-
final _examplePattern = RegExp(r'{@example\s+([^}]+)}');
27+
final _examplePattern = RegExp(r'{@example\s+([^\s}][^}]*)}');
3128

32-
final _macroRegExp = RegExp(r'{@macro\s+([^}]+)}');
29+
final _macroRegExp = RegExp(r'{@macro\s+([^\s}][^}]*)}');
3330

3431
final _htmlInjectRegExp = RegExp(r'<dartdoc-html>([a-f0-9]+)</dartdoc-html>');
3532

@@ -169,7 +166,7 @@ mixin DocumentationComment
169166
'required',
170167
};
171168

172-
static final _nameBreak = RegExp('[\\s}]');
169+
static final _nameBreak = RegExp(r'[\s}]');
173170

174171
// TODO(srawlins): Implement more checks; see
175172
// https://github.com/dart-lang/dartdoc/issues/1814.
@@ -391,7 +388,7 @@ mixin DocumentationComment
391388
/// Matches all youtube directives (even some invalid ones). This is so
392389
/// we can give good error messages if the directive is malformed, instead of
393390
/// just silently emitting it as-is.
394-
static final _basicYouTubePattern = RegExp(r'''{@youtube\s+([^}]+)}''');
391+
static final _basicYouTubePattern = RegExp(r'{@youtube\s+([^\s}][^}]*)}');
395392

396393
/// Matches YouTube IDs from supported YouTube URLs.
397394
static final _validYouTubeUrlPattern =
@@ -476,7 +473,7 @@ mixin DocumentationComment
476473
/// Matches all animation directives (even some invalid ones). This is so we
477474
/// can give good error messages if the directive is malformed, instead of
478475
/// just silently emitting it as-is.
479-
static final _basicAnimationPattern = RegExp(r'''{@animation\s+([^}]+)}''');
476+
static final _basicAnimationPattern = RegExp(r'{@animation\s+([^\s}][^}]*)}');
480477

481478
/// Matches valid JavaScript identifiers.
482479
static final _validIdPattern = RegExp(r'^[a-zA-Z_]\w*$');
@@ -675,8 +672,8 @@ mixin DocumentationComment
675672
/// Match group 4 is the unquoted arg, if any.
676673
static final RegExp _argPattern = RegExp(r'([a-zA-Z\-_0-9]+=)?' // option name
677674
r'(?:' // Start a new non-capture group for the two possibilities.
678-
r'''(["'])((?:\\{2})*|(?:.*?[^\\](?:\\{2})*))\2|''' // with quotes.
679-
r'([^ ]+))'); // without quotes.
675+
r'''(["'])((?:[^\\\r\n]|\\.)*?)\2|''' // with quotes.
676+
r'(\S+))'); // without quotes.
680677

681678
/// Helper to process arguments given as a (possibly quoted) string.
682679
///

0 commit comments

Comments
 (0)