From e565693821474af0e96456afb6580c902afb3e4d Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Tue, 26 Nov 2024 15:42:27 -0800 Subject: [PATCH 1/4] add failing test case --- test/Jamfile.v2 | 1 + test/issue232.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 test/issue232.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1fd6cc3d0..9140e2db3 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -136,3 +136,4 @@ compile test_windows_defs_4.cpp ; run issue153.cpp : : : "msvc:-STACK:2097152" ; run issue227.cpp ; +run issue232.cpp ; diff --git a/test/issue232.cpp b/test/issue232.cpp new file mode 100644 index 000000000..a8c2b2ccd --- /dev/null +++ b/test/issue232.cpp @@ -0,0 +1,71 @@ +#include + +#include +#include +#include + +template +void tester( char const (&str)[ N0 ] ) +{ + std::vector s(N, '\0'); + std::memcpy(s.data(), str, N); + boost::regex rx(s.begin(), s.end()); + + std::vector wheres; + wheres.push_back(std::string(15, 'H')); + wheres.push_back(""); + wheres.push_back(" "); + + // Perl-style matching + for (auto const& where : wheres) { + boost::match_results what; + bool match = boost::regex_match(where, what, rx, boost::match_default | boost::match_partial | boost::match_any | boost::match_perl); + (void) match; + } + + // POSIX-style matching + for (auto const& where : wheres) { + try { + boost::match_results what; + bool match = boost::regex_match(where, what, rx, boost::match_default | boost::match_partial | boost::match_any | boost::match_posix); + (void) match; + } catch(...) {} + } + +} + +int main() +{ + // test strings derived from fuzzing + // we keep a simple human-readable version + char const str1[] = "(Y(*COMMIT)|\\K\\D|.)+"; + char const str2[] = "(Y(*COMMIT){||\\K\\D|||||||||\\K|||ss|||||.|\232*(?(50)\027\0204657|H)\020}\031\000.* 6.'?-i)+[L??.\000\000\000\004\000\000\000\000?..<[\000\024R]*+"; + char const str3[] = "(Y(*COMMIT)\xFF\x80|\\L\\K||||||||||.|||||\x84|||||\x00\x00\x10||||||.* .'?-i)[L??...-i)[L??...[\x00\x14R]*+"; + char const str4[] = "(Y(*COMMIT)\x96||.* .* .\\K|||\x9F||||\x9C|.|||||\x84\x99|||\x01\x00\x00\x00|||'?-i#PL\x00\x01.\x86??OMMIT)?...[\x00\x14R]*+"; + + tester(str1); + tester(str2); + tester(str3); + tester(str4); + + // prove that we catch certain impossible scenarios + + { + char const* str = "abcd"; + boost::regex rx(str); + boost::match_results what; + std::string where(15, 'H'); + BOOST_TEST_THROWS(boost::regex_match(where, rx, boost::match_posix | boost::match_perl), std::logic_error); + } + + { + char const* str = "ab(*COMMIT)cd"; + boost::regex rx(str); + boost::match_results what; + std::string where(15, 'H'); + BOOST_TEST_THROWS(boost::regex_match(where, rx, boost::match_posix), std::logic_error); + } + + return boost::report_errors(); +} + From dbbd7c9170a6b23eb33efeb6313cf84c53eeb009 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Tue, 26 Nov 2024 15:42:39 -0800 Subject: [PATCH 2/4] fix issue #232 Credit to OSS-Fuzz for finding the problematic test regexes and configurations. --- include/boost/regex/v5/perl_matcher.hpp | 25 +++++++++++++------ .../boost/regex/v5/perl_matcher_common.hpp | 11 ++++---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/boost/regex/v5/perl_matcher.hpp b/include/boost/regex/v5/perl_matcher.hpp index e48171085..207daedd8 100644 --- a/include/boost/regex/v5/perl_matcher.hpp +++ b/include/boost/regex/v5/perl_matcher.hpp @@ -39,25 +39,34 @@ #endif #endif +#ifndef BOOST_REGEX_STANDALONE +# define BOOST_REGEX_DETAIL_THROW(ex) boost::throw_exception(ex) +#else +# define BOOST_REGEX_DETAIL_THROW(ex) throw ex +#endif + namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ // // error checking API: // -inline void verify_options(boost::regex_constants::syntax_option_type, match_flag_type mf) +inline void verify_options(boost::regex_constants::syntax_option_type, match_flag_type mf) { + auto is_perl = (mf & match_perl); + auto is_posix = (mf & match_posix); + + if (is_perl && is_posix) + { + BOOST_REGEX_DETAIL_THROW(std::logic_error("Usage Error: Can't mix Perl and POSIX matching rules")); + } + // // can't mix match_extra with POSIX matching rules: // - if ((mf & match_extra) && (mf & match_posix)) + if ((mf & match_extra) && is_posix) { - std::logic_error msg("Usage Error: Can't mix regular expression captures with POSIX matching rules"); -#ifndef BOOST_REGEX_STANDALONE - throw_exception(msg); -#else - throw msg; -#endif + BOOST_REGEX_DETAIL_THROW(std::logic_error("Usage Error: Can't mix regular expression captures with POSIX matching rules")); } } // diff --git a/include/boost/regex/v5/perl_matcher_common.hpp b/include/boost/regex/v5/perl_matcher_common.hpp index 4e9119e3e..ff3a69e88 100644 --- a/include/boost/regex/v5/perl_matcher_common.hpp +++ b/include/boost/regex/v5/perl_matcher_common.hpp @@ -60,12 +60,7 @@ void perl_matcher::construct_init(const basic_r if(e.empty()) { // precondition failure: e is not a valid regex. - std::invalid_argument ex("Invalid regular expression object"); -#ifndef BOOST_REGEX_STANDALONE - boost::throw_exception(ex); -#else - throw e; -#endif + BOOST_REGEX_DETAIL_THROW(std::invalid_argument("Invalid regular expression object")); } pstate = 0; m_match_flags = f; @@ -98,7 +93,11 @@ void perl_matcher::construct_init(const basic_r match_any_mask = static_cast((f & match_not_dot_newline) ? BOOST_REGEX_DETAIL_NS::test_not_newline : BOOST_REGEX_DETAIL_NS::test_newline); // Disable match_any if requested in the state machine: if(e.get_data().m_disable_match_any) + { + if (m_match_flags & match_posix) + BOOST_REGEX_DETAIL_THROW(std::logic_error("Invalid regex for POSIX-style matching")); m_match_flags &= regex_constants::match_not_any; + } } #ifdef BOOST_REGEX_MSVC # pragma warning(pop) From 02c4616955dee085166380f390c3d7a5b5dc136b Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 5 Dec 2024 11:47:36 +0000 Subject: [PATCH 3/4] Use BOOST_THROW_EXCEPTION. --- include/boost/regex/v5/perl_matcher.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/regex/v5/perl_matcher.hpp b/include/boost/regex/v5/perl_matcher.hpp index 207daedd8..4096fdb30 100644 --- a/include/boost/regex/v5/perl_matcher.hpp +++ b/include/boost/regex/v5/perl_matcher.hpp @@ -40,7 +40,7 @@ #endif #ifndef BOOST_REGEX_STANDALONE -# define BOOST_REGEX_DETAIL_THROW(ex) boost::throw_exception(ex) +# define BOOST_REGEX_DETAIL_THROW(ex) BOOST_THROW_EXCEPTION(ex) #else # define BOOST_REGEX_DETAIL_THROW(ex) throw ex #endif From 9ba397070bcca11de37dc7b56ce129f73ffa9857 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 5 Dec 2024 12:03:49 +0000 Subject: [PATCH 4/4] Revert last change --- include/boost/regex/v5/perl_matcher.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/regex/v5/perl_matcher.hpp b/include/boost/regex/v5/perl_matcher.hpp index 4096fdb30..207daedd8 100644 --- a/include/boost/regex/v5/perl_matcher.hpp +++ b/include/boost/regex/v5/perl_matcher.hpp @@ -40,7 +40,7 @@ #endif #ifndef BOOST_REGEX_STANDALONE -# define BOOST_REGEX_DETAIL_THROW(ex) BOOST_THROW_EXCEPTION(ex) +# define BOOST_REGEX_DETAIL_THROW(ex) boost::throw_exception(ex) #else # define BOOST_REGEX_DETAIL_THROW(ex) throw ex #endif