diff --git a/include/boost/regex/icu.hpp b/include/boost/regex/icu.hpp index 6bb9a48f..772806e9 100644 --- a/include/boost/regex/icu.hpp +++ b/include/boost/regex/icu.hpp @@ -251,7 +251,7 @@ inline u32regex do_make_u32regex(InputIterator i, const boost::mpl::int_<1>*) { typedef boost::u8_to_u32_iterator conv_type; - return u32regex(conv_type(i), conv_type(j), opt); + return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt); } template @@ -261,7 +261,7 @@ inline u32regex do_make_u32regex(InputIterator i, const boost::mpl::int_<2>*) { typedef boost::u16_to_u32_iterator conv_type; - return u32regex(conv_type(i), conv_type(j), opt); + return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt); } template @@ -282,7 +282,7 @@ inline u32regex do_make_u32regex(InputIterator i, typedef boost::u8_to_u32_iterator conv_type; typedef std::vector vector_type; vector_type v; - conv_type a(i), b(j); + conv_type a(i, i, j), b(j, i, j); while(a != b) { v.push_back(*a); @@ -302,7 +302,7 @@ inline u32regex do_make_u32regex(InputIterator i, typedef boost::u16_to_u32_iterator conv_type; typedef std::vector vector_type; vector_type v; - conv_type a(i), b(j); + conv_type a(i, i, j), b(j, i, j); while(a != b) { v.push_back(*a); @@ -425,7 +425,7 @@ bool do_regex_match(BidiIterator first, BidiIterator last, typedef match_results match_type; typedef typename match_type::allocator_type alloc_type; match_type what; - bool result = ::boost::regex_match(conv_type(first), conv_type(last), what, e, flags); + bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags); // copy results across to m: if(result) copy_results(m, what); return result; @@ -441,7 +441,7 @@ bool do_regex_match(BidiIterator first, BidiIterator last, typedef match_results match_type; typedef typename match_type::allocator_type alloc_type; match_type what; - bool result = ::boost::regex_match(conv_type(first), conv_type(last), what, e, flags); + bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags); // copy results across to m: if(result) copy_results(m, what); return result; @@ -600,7 +600,7 @@ bool do_regex_search(BidiIterator first, BidiIterator last, typedef match_results match_type; typedef typename match_type::allocator_type alloc_type; match_type what; - bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags, conv_type(base)); + bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base)); // copy results across to m: if(result) copy_results(m, what); return result; @@ -617,7 +617,7 @@ bool do_regex_search(BidiIterator first, BidiIterator last, typedef match_results match_type; typedef typename match_type::allocator_type alloc_type; match_type what; - bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags, conv_type(base)); + bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base)); // copy results across to m: if(result) copy_results(m, what); return result; diff --git a/include/boost/regex/v4/basic_regex_creator.hpp b/include/boost/regex/v4/basic_regex_creator.hpp index 6c1acd78..c4b1c048 100644 --- a/include/boost/regex/v4/basic_regex_creator.hpp +++ b/include/boost/regex/v4/basic_regex_creator.hpp @@ -1226,7 +1226,7 @@ void basic_regex_creator::create_startmap(re_syntax_base* state, for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i) { charT c = static_cast(i); - if(&c != re_is_set_member(&c, &c + 1, static_cast*>(state), *m_pdata, m_icase)) + if(&c != re_is_set_member(&c, &c + 1, static_cast*>(state), *m_pdata, l_icase)) l_map[i] |= mask; } } diff --git a/include/boost/regex/v4/regex_format.hpp b/include/boost/regex/v4/regex_format.hpp index 4406839f..e05862fa 100644 --- a/include/boost/regex/v4/regex_format.hpp +++ b/include/boost/regex/v4/regex_format.hpp @@ -842,7 +842,15 @@ OutputIterator regex_format_imp(OutputIterator out, BOOST_MPL_HAS_XXX_TRAIT_DEF(const_iterator) -struct any_type { any_type(...); }; +struct any_type +{ + template + any_type(const T&); + template + any_type(const T&, const U&); + template + any_type(const T&, const U&, const V&); +}; typedef char no_type; typedef char (&unary_type)[2]; typedef char (&binary_type)[3]; diff --git a/src/c_regex_traits.cpp b/src/c_regex_traits.cpp index a99de14c..67010201 100644 --- a/src/c_regex_traits.cpp +++ b/src/c_regex_traits.cpp @@ -21,6 +21,7 @@ #include #include +#include "internals.hpp" #if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) @@ -107,26 +108,6 @@ c_regex_traits::string_type BOOST_REGEX_CALL c_regex_traits::transfo return result; } -enum -{ - char_class_space=1<<0, - char_class_print=1<<1, - char_class_cntrl=1<<2, - char_class_upper=1<<3, - char_class_lower=1<<4, - char_class_alpha=1<<5, - char_class_digit=1<<6, - char_class_punct=1<<7, - char_class_xdigit=1<<8, - char_class_alnum=char_class_alpha|char_class_digit, - char_class_graph=char_class_alnum|char_class_punct, - char_class_blank=1<<9, - char_class_word=1<<10, - char_class_unicode=1<<11, - char_class_horizontal=1<<12, - char_class_vertical=1<<13 -}; - c_regex_traits::char_class_type BOOST_REGEX_CALL c_regex_traits::lookup_classname(const char* p1, const char* p2) { static const char_class_type masks[] = diff --git a/src/cregex.cpp b/src/cregex.cpp index 5c27330c..8d69139f 100644 --- a/src/cregex.cpp +++ b/src/cregex.cpp @@ -361,11 +361,24 @@ void BuildFileList(std::list* pl, const char* files, bool recurse) while(dstart != dend) { + // Verify that sprintf will not overflow: + if(std::strlen(dstart.path()) + std::strlen(directory_iterator::separator()) + std::strlen(ptr) >= MAX_PATH) + { + // Oops overflow, skip this item: + ++dstart; + continue; + } #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE) - (::sprintf_s)(buf, sizeof(buf), "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); + int r = (::sprintf_s)(buf, sizeof(buf), "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); #else - (std::sprintf)(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); + int r = (std::sprintf)(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); #endif + if(r < 0) + { + // sprintf failed, skip this item: + ++dstart; + continue; + } BuildFileList(pl, buf, recurse); ++dstart; } diff --git a/src/fileiter.cpp b/src/fileiter.cpp index ff1d1119..38c0d2c3 100644 --- a/src/fileiter.cpp +++ b/src/fileiter.cpp @@ -847,10 +847,16 @@ bool iswild(const char* mask, const char* name) unsigned _fi_attributes(const char* root, const char* name) { char buf[MAX_PATH]; + // verify that we can not overflow: + if(std::strlen(root) + std::strlen(_fi_sep) + std::strlen(name) >= MAX_PATH) + return 0; + int r; if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') ) - (std::sprintf)(buf, "%s%s", root, name); + r = (std::sprintf)(buf, "%s%s", root, name); else - (std::sprintf)(buf, "%s%s%s", root, _fi_sep, name); + r = (std::sprintf)(buf, "%s%s%s", root, _fi_sep, name); + if(r < 0) + return 0; // sprintf failed DIR* d = opendir(buf); if(d) { diff --git a/src/internals.hpp b/src/internals.hpp new file mode 100644 index 00000000..3a15cc67 --- /dev/null +++ b/src/internals.hpp @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2011 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#ifndef BOOST_REGEX_SRC_INTERNALS_HPP +#define BOOST_REGEX_SRC_INTERNALS_HPP + +enum +{ + char_class_space=1<<0, + char_class_print=1<<1, + char_class_cntrl=1<<2, + char_class_upper=1<<3, + char_class_lower=1<<4, + char_class_alpha=1<<5, + char_class_digit=1<<6, + char_class_punct=1<<7, + char_class_xdigit=1<<8, + char_class_alnum=char_class_alpha|char_class_digit, + char_class_graph=char_class_alnum|char_class_punct, + char_class_blank=1<<9, + char_class_word=1<<10, + char_class_unicode=1<<11, + char_class_horizontal=1<<12, + char_class_vertical=1<<13 +}; + +#endif // BOOST_REGEX_SRC_INTERNALS_HPP diff --git a/src/posix_api.cpp b/src/posix_api.cpp index 37ed4221..abafd8f2 100644 --- a/src/posix_api.cpp +++ b/src/posix_api.cpp @@ -167,11 +167,17 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA* { if(std::strcmp(e->re_endp, names[i]) == 0) { + // + // We're converting an integer i to a string, and since i <= REG_E_UNKNOWN + // a five character string is *always* large enough: + // #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE) - (::sprintf_s)(localbuf, 5, "%d", i); + int r = (::sprintf_s)(localbuf, 5, "%d", i); #else - (std::sprintf)(localbuf, "%d", i); + int r = (std::sprintf)(localbuf, "%d", i); #endif + if(r < 0) + return 0; // sprintf failed if(std::strlen(localbuf) < buf_size) re_detail::strcpy_s(buf, buf_size, localbuf); return std::strlen(localbuf) + 1; diff --git a/src/wc_regex_traits.cpp b/src/wc_regex_traits.cpp index a9e96d9e..b3d2c5a2 100644 --- a/src/wc_regex_traits.cpp +++ b/src/wc_regex_traits.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "internals.hpp" #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE) && defined(_NATIVE_WCHAR_T_DEFINED) \ && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) || defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER))\ @@ -147,26 +148,6 @@ c_regex_traits::string_type BOOST_REGEX_CALL c_regex_traits::t return result; } -enum -{ - char_class_space=1<<0, - char_class_print=1<<1, - char_class_cntrl=1<<2, - char_class_upper=1<<3, - char_class_lower=1<<4, - char_class_alpha=1<<5, - char_class_digit=1<<6, - char_class_punct=1<<7, - char_class_xdigit=1<<8, - char_class_alnum=char_class_alpha|char_class_digit, - char_class_graph=char_class_alnum|char_class_punct, - char_class_blank=1<<9, - char_class_word=1<<10, - char_class_unicode=1<<11, - char_class_horizontal=1<<12, - char_class_vertical=1<<13 -}; - c_regex_traits::char_class_type BOOST_REGEX_CALL c_regex_traits::lookup_classname(const wchar_t* p1, const wchar_t* p2) { static const char_class_type masks[] = diff --git a/src/wide_posix_api.cpp b/src/wide_posix_api.cpp index 3c693c67..ff5c90d8 100644 --- a/src/wide_posix_api.cpp +++ b/src/wide_posix_api.cpp @@ -74,7 +74,7 @@ const wchar_t* wnames[] = { }; } -typedef boost::basic_regex > c_regex_type; +typedef boost::basic_regex > wc_regex_type; BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wchar_t* ptr, int f) { @@ -84,7 +84,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha #ifndef BOOST_NO_EXCEPTIONS try{ #endif - expression->guts = new c_regex_type(); + expression->guts = new wc_regex_type(); #ifndef BOOST_NO_EXCEPTIONS } catch(...) { @@ -134,9 +134,9 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha try{ #endif expression->re_magic = wmagic_value; - static_cast(expression->guts)->set_expression(ptr, p2, flags); - expression->re_nsub = static_cast(expression->guts)->mark_count() - 1; - result = static_cast(expression->guts)->error_code(); + static_cast(expression->guts)->set_expression(ptr, p2, flags); + expression->re_nsub = static_cast(expression->guts)->mark_count() - 1; + result = static_cast(expression->guts)->error_code(); #ifndef BOOST_NO_EXCEPTIONS } catch(const boost::regex_error& be) @@ -215,7 +215,7 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW* { std::string p; if((e) && (e->re_magic == wmagic_value)) - p = static_cast(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code)); + p = static_cast(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code)); else { p = re_detail::get_default_error_string(static_cast< ::boost::regex_constants::error_type>(code)); @@ -264,7 +264,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW* expression, cons #endif if(expression->re_magic == wmagic_value) { - result = regex_search(start, end, m, *static_cast(expression->guts), flags); + result = regex_search(start, end, m, *static_cast(expression->guts), flags); } else return result; @@ -301,7 +301,7 @@ BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW* expression) { if(expression->re_magic == wmagic_value) { - delete static_cast(expression->guts); + delete static_cast(expression->guts); } expression->re_magic = 0; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2c0d386a..a7b689f7 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -189,6 +189,8 @@ test-suite regex ; +compile test_consolidated.cpp ; + build-project ../example ; diff --git a/test/regress/test_perl_ex.cpp b/test/regress/test_perl_ex.cpp index 8a14b826..9e1ddd30 100644 --- a/test/regress/test_perl_ex.cpp +++ b/test/regress/test_perl_ex.cpp @@ -216,6 +216,10 @@ void test_options2() TEST_REGEX_SEARCH("(a(?i)b)c", perl, "ABc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(a(?i)b)c", perl, "ABC", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(a(?i)b)c", perl, "AbC", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "hog", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "dog", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "Hog", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "Dog", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("(a(?i)B)c", perl, "abc", match_default, make_array(0, 3, 0, 2, -2, -2)); TEST_REGEX_SEARCH("(a(?i)B)c", perl, "aBc", match_default, make_array(0, 3, 0, 2, -2, -2)); diff --git a/test/test_consolidated.cpp b/test/test_consolidated.cpp new file mode 100644 index 00000000..188033f7 --- /dev/null +++ b/test/test_consolidated.cpp @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2011 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/test/unicode/unicode_iterator_test.cpp b/test/unicode/unicode_iterator_test.cpp index 30957970..a6facb2c 100644 --- a/test/unicode/unicode_iterator_test.cpp +++ b/test/unicode/unicode_iterator_test.cpp @@ -30,7 +30,7 @@ template typename I::value_type iterate_over(I a, I b) { - typedef I::value_type value_type; + typedef typename I::value_type value_type; value_type v = 0; while(a != b) {