10000 Fix #1: regex_iterator will infinitely recurse if an empty match matches · AmesianX/docopt.cpp@981200c · GitHub
[go: up one dir, main page]

Skip to content

Commit 981200c

Browse files
committed
Fix docopt#1: regex_iterator will infinitely recurse if an empty match matches
1 parent ea59a92 commit 981200c

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

docopt.cpp

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -174,23 +174,33 @@ Option Option::parse(std::string const& option_description)
174174
}
175175

176176
static const std::regex pattern {"(--|-)?(.*?)([,= ]|$)"};
177-
std::for_each(std::sregex_iterator{option_description.begin(), options_end, pattern},
178-
std::sregex_iterator{},
179-
[&](std::smatch const& match)
180-
{
181-
if (match[1].matched) {
182-
if (match[1].length()==1) {
183-
shortOption = "-" + match[2].str();
184-
} else {
185-
longOption = "--" + match[2].str();
186-
}
187-
} else if (match[2].matched && match[2].length()) {
188-
argcount = 1;
189-
} else {
190-
// delimeter
191-
}
192-
});
193-
177+
for(std::sregex_iterator i {option_description.begin(), options_end, pattern, std::regex_constants::match_not_null},
178+
e{};
179+
i != e;
180+
++i)
181+
{
182+
std::smatch const& match = *i;
183+
if (match[1].matched) { // [1] is optional.
184+
if (match[1].length()==1) {
185+
shortOption = "-" + match[2].str();
186+
} else {
187+
longOption = "--" + match[2].str();
188+
}
189+
} else if (match[2].length() > 0) { // [2] always matches.
190+
std::string m = match[2];
191+
argcount = 1;
192+
} else {
193+
// delimeter
194+
}
195+
196+
if (match[3].length() == 0) { // [3] always matches.
197+
// Hit end of string. For some reason 'match_not_null' will let us match empty
198+
// at the end, and then we'll spin in an infinite loop. So, if we hit an empty
199+
// match, we know we must be at the end.
200+
break;
201+
}
202+
}
203+
194204
if (argcount) {
195205
std::smatch match;
196206
if (std::regex_search(options_end, option_description.end(),

0 commit comments

Comments
 (0)
0