peetonn
peetonn

Reputation: 3052

Boost regex throws complexity exception while std::regex does not

I've faced a weird problem - the library I use uses regular expressions, which can be either boost or std, depending on options provided during configuration. Due to other reasons, I can't use std::regex in my code and use boost instead. When I started to call library functions that internally use regular expressions, my code blocked. After many hours of debugging the problem, I located it. In short, this code blocks:

std::string str = "/a/b/c/d/e/KEY/h/dsk-1474591592/ID-CERT";
std::string pattern = "^((?:(?!/KEY)(?:/.*)*)*)/KEY((?:/.+?)*)/ksk-.+/ID-CERT";
boost::regex re = regex(pattern);
boost::sregex_iterator iterator = boost::sregex_iterator(str.begin(), str.end(), re);

When I made a little test program with this code, I got exception:

libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::runtime_error> >: The complexity of matching the regular expression exceeded predefined bounds.  Try refactoring the regular expression to make each choice made by the state machine unambiguous.  This exception is thrown to prevent "eternal" matches that take an indefinite period time to locate.
Abort trap: 6

Same code, doesn't throw if std::regex is used instead.

I tried several boost versions - 1.54, 1.58, 1.59 - all throw. I need to find a workaround for this - either suppress throwing this exact exception from boost (which might be dangerous) or make regex simpler (preferred). Unfortunately, I didn't have much experience with regexes and any advice on how to make it simpler would be highly appreciated!

UPDATE (ADDITIONAL INFO):

How the regular expression mentioned above was cretead: it is the resulting regex that is processed by the library. It uses NDN-regex in this function and passes it through this sanitizing function.

Upvotes: 1

Views: 1455

Answers (1)

Marshall Clow
Marshall Clow

Reputation: 16690

boost::regex (and std::regex) will throw an exception when they decide an expression is too complex. See [re.err] in the standard for a description of error_complexity and the related error_stack.

error_complexity The complexity of an attempted match against a regular expression exceeded a pre-set level.

How it decides that, and what is "too complex" is implementation-defined.

So, what you're seeing is "perfectly fine", but that is not really a helpful answer for you.

Upvotes: 1

Related Questions