diff options
author | Benjamin Barenblat <bbaren@mit.edu> | 2015-07-28 10:38:10 -0400 |
---|---|---|
committer | Benjamin Barenblat <bbaren@mit.edu> | 2015-07-28 10:38:10 -0400 |
commit | 2f6799a42360a995b665244b922ebd3b2275c839 (patch) | |
tree | 23102228a85e96561f1ce20c5321d31b573b94d7 /src | |
parent | a8b108619083c2088269ea8071c7958f277ed41f (diff) |
Replace my bounds-checked numeric conversion with Boost’s
Boost provides numeric_cast, which is much better than what I was using for
safe numeric type conversion. This does introduce a Boost dependency, but that
tends to be true of most nontrivial C++ programs, so it’s pretty reasonable.
Diffstat (limited to 'src')
-rw-r--r-- | src/regex__FFI.cc | 32 |
1 files changed, 11 insertions, 21 deletions
diff --git a/src/regex__FFI.cc b/src/regex__FFI.cc index 0ea3455..c2f8a4b 100644 --- a/src/regex__FFI.cc +++ b/src/regex__FFI.cc @@ -14,12 +14,10 @@ #include "regex__FFI.h" -#include <regex.h> - #include <cstring> -#include <limits> #include <regex> +#include <boost/numeric/conversion/cast.hpp> extern "C" { #include <urweb/urweb_cpp.h> } @@ -54,18 +52,13 @@ void DeleteMatchResults(void* match_result, } // Bounds-checked numeric type conversion -template<typename T, typename U> -U Number(uw_context* const context, const T input) { - Assert(context, input <= std::numeric_limits<U>::max(), - "regex: detected overflow during numeric conversion"); - if (std::numeric_limits<T>::is_signed == std::numeric_limits<U>::is_signed) { - Assert(context, std::numeric_limits<U>::lowest() <= input, - "regex: detected underflow during numeric conversion"); - } else if (std::numeric_limits<T>::is_signed) { - Assert(context, 0 <= input, - "regex: detected underflow during numeric conversion"); +template<typename Target, typename Source> +Target Number(uw_context* const context, Source arg) { + try { + return boost::numeric_cast<Target>(arg); + } catch (const boost::numeric::bad_numeric_cast& e) { + uw_error(context, FATAL, "regex: %s", e.what()); } - return static_cast<U>(input); } } // namespace @@ -90,7 +83,7 @@ uw_Basis_int uw_Regex__FFI_n_subexpression_matches( } else { // At least one match occurred. Compute the number of parenthesized // subexpressions that got matched, and return it. - return Number<std::cmatch::size_type, uw_Basis_int>(context, n_matches) - 1; + return Number<uw_Basis_int>(context, n_matches) - 1; } } @@ -101,18 +94,15 @@ uw_Basis_string uw_Regex__FFI_subexpression_match( const std::cmatch* const match_result = reinterpret_cast<std::cmatch*>(match.result); const std::size_t match_index = - Number<uw_Basis_int, std::size_t>(context, match_index_signed); + Number<std::size_t>(context, match_index_signed); Assert(context, match_index < match_result->size(), "regex: match does not exist"); const auto matched_substring = (*match_result)[match_index + 1]; // Save the matched substring. const std::size_t result_length = - Number<std::csub_match::difference_type, std::size_t>( - context, - matched_substring.length()); + Number<std::size_t>(context,matched_substring.length()); uw_Basis_string result = - reinterpret_cast<uw_Basis_string>( - uw_malloc(context, result_length + 1)); + reinterpret_cast<uw_Basis_string>(uw_malloc(context, result_length + 1)); std::strcpy(result, matched_substring.str().c_str()); return result; } |