diff --git a/NEWS.md b/NEWS.md index 5497ea1..953a56a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,6 +16,8 @@ * Replace call to `Rf_error()` with `Rcpp::stop()`; RcppCore/Rcpp#1247 +* Fix UBs in the C++ glue code; #380 + # version 0.8-5 * avoid -Wformat-security warning on CRAN diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 8db11f2..71afde4 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -40,28 +40,28 @@ BEGIN_RCPP END_RCPP } // ud_compare -IntegerVector ud_compare(NumericVector x, NumericVector y, CharacterVector xn, CharacterVector yn); +IntegerVector ud_compare(NumericVector x, NumericVector y, std::string xn, std::string yn); RcppExport SEXP _units_ud_compare(SEXP xSEXP, SEXP ySEXP, SEXP xnSEXP, SEXP ynSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< NumericVector >::type x(xSEXP); Rcpp::traits::input_parameter< NumericVector >::type y(ySEXP); - Rcpp::traits::input_parameter< CharacterVector >::type xn(xnSEXP); - Rcpp::traits::input_parameter< CharacterVector >::type yn(ynSEXP); + Rcpp::traits::input_parameter< std::string >::type xn(xnSEXP); + Rcpp::traits::input_parameter< std::string >::type yn(ynSEXP); rcpp_result_gen = Rcpp::wrap(ud_compare(x, y, xn, yn)); return rcpp_result_gen; END_RCPP } // ud_convert -NumericVector ud_convert(NumericVector val, CharacterVector from, CharacterVector to); +NumericVector ud_convert(NumericVector val, std::string from, std::string to); RcppExport SEXP _units_ud_convert(SEXP valSEXP, SEXP fromSEXP, SEXP toSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< NumericVector >::type val(valSEXP); - Rcpp::traits::input_parameter< CharacterVector >::type from(fromSEXP); - Rcpp::traits::input_parameter< CharacterVector >::type to(toSEXP); + Rcpp::traits::input_parameter< std::string >::type from(fromSEXP); + Rcpp::traits::input_parameter< std::string >::type to(toSEXP); rcpp_result_gen = Rcpp::wrap(ud_convert(val, from, to)); return rcpp_result_gen; END_RCPP @@ -232,48 +232,48 @@ BEGIN_RCPP END_RCPP } // R_ut_raise -SEXP R_ut_raise(SEXP a, IntegerVector i); +SEXP R_ut_raise(SEXP a, int i); RcppExport SEXP _units_R_ut_raise(SEXP aSEXP, SEXP iSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< SEXP >::type a(aSEXP); - Rcpp::traits::input_parameter< IntegerVector >::type i(iSEXP); + Rcpp::traits::input_parameter< int >::type i(iSEXP); rcpp_result_gen = Rcpp::wrap(R_ut_raise(a, i)); return rcpp_result_gen; END_RCPP } // R_ut_root -SEXP R_ut_root(SEXP a, IntegerVector i); +SEXP R_ut_root(SEXP a, int i); RcppExport SEXP _units_R_ut_root(SEXP aSEXP, SEXP iSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< SEXP >::type a(aSEXP); - Rcpp::traits::input_parameter< IntegerVector >::type i(iSEXP); + Rcpp::traits::input_parameter< int >::type i(iSEXP); rcpp_result_gen = Rcpp::wrap(R_ut_root(a, i)); return rcpp_result_gen; END_RCPP } // R_ut_log -SEXP R_ut_log(SEXP a, NumericVector base); +SEXP R_ut_log(SEXP a, double base); RcppExport SEXP _units_R_ut_log(SEXP aSEXP, SEXP baseSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< SEXP >::type a(aSEXP); - Rcpp::traits::input_parameter< NumericVector >::type base(baseSEXP); + Rcpp::traits::input_parameter< double >::type base(baseSEXP); rcpp_result_gen = Rcpp::wrap(R_ut_log(a, base)); return rcpp_result_gen; END_RCPP } // R_ut_parse -SEXP R_ut_parse(CharacterVector name); +SEXP R_ut_parse(std::string name); RcppExport SEXP _units_R_ut_parse(SEXP nameSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< CharacterVector >::type name(nameSEXP); + Rcpp::traits::input_parameter< std::string >::type name(nameSEXP); rcpp_result_gen = Rcpp::wrap(R_ut_parse(name)); return rcpp_result_gen; END_RCPP diff --git a/src/udunits.cpp b/src/udunits.cpp index 11260ab..9036868 100644 --- a/src/udunits.cpp +++ b/src/udunits.cpp @@ -80,7 +80,7 @@ void ud_set_encoding(std::string enc_str) { // [[Rcpp::export]] IntegerVector ud_compare(NumericVector x, NumericVector y, - CharacterVector xn, CharacterVector yn) + std::string xn, std::string yn) { bool swapped = false; @@ -91,11 +91,12 @@ IntegerVector ud_compare(NumericVector x, NumericVector y, } IntegerVector out(x.size()); + if (y.size() == 0) return IntegerVector(0); for (std::string &attr : x.attributeNames()) out.attr(attr) = x.attr(attr); - ut_unit *ux = ut_parse(sys, ut_trim(xn[0], enc), enc); - ut_unit *uy = ut_parse(sys, ut_trim(yn[0], enc), enc); + ut_unit *ux = ut_parse(sys, ut_trim(xn.data(), enc), enc); + ut_unit *uy = ut_parse(sys, ut_trim(yn.data(), enc), enc); if (ut_compare(ux, uy) != 0) { NumericVector y_cv = clone(y); @@ -127,9 +128,11 @@ IntegerVector ud_compare(NumericVector x, NumericVector y, } // [[Rcpp::export]] -NumericVector ud_convert(NumericVector val, CharacterVector from, CharacterVector to) { - ut_unit *u_from = ut_parse(sys, ut_trim(from[0], enc), enc); - ut_unit *u_to = ut_parse(sys, ut_trim(to[0], enc), enc); +NumericVector ud_convert(NumericVector val, std::string from, std::string to) { + if (val.size() == 0) return val; + + ut_unit *u_from = ut_parse(sys, ut_trim(from.data(), enc), enc); + ut_unit *u_to = ut_parse(sys, ut_trim(to.data(), enc), enc); cv_converter *cv = ut_get_converter(u_from, u_to); cv_convert_doubles(cv, &(val[0]), val.size(), &(val[0])); @@ -256,35 +259,27 @@ SEXP R_ut_divide(SEXP numer, SEXP denom) { } // [[Rcpp::export]] -SEXP R_ut_raise(SEXP a, IntegerVector i) { - if (i.length() != 1) - stop("i should have length 1"); - return ut_wrap(ut_raise(ut_unwrap(a), i[0])); +SEXP R_ut_raise(SEXP a, int i) { + return ut_wrap(ut_raise(ut_unwrap(a), i)); } // [[Rcpp::export]] -SEXP R_ut_root(SEXP a, IntegerVector i) { - if (i.length() != 1) - stop("i should have length 1"); - return ut_wrap(ut_root(ut_unwrap(a), i[0])); +SEXP R_ut_root(SEXP a, int i) { + return ut_wrap(ut_root(ut_unwrap(a), i)); } // # nocov end // [[Rcpp::export]] -SEXP R_ut_log(SEXP a, NumericVector base) { - if (base.length() != 1) - stop("base should have length 1"); - if (base[0] <= 0) - stop("base should be positive"); - return ut_wrap(ut_log(base[0], ut_unwrap(a))); +SEXP R_ut_log(SEXP a, double base) { + return ut_wrap(ut_log(base, ut_unwrap(a))); } // [[Rcpp::export]] -SEXP R_ut_parse(CharacterVector name) { - ut_unit *u = ut_parse(sys, ut_trim(name[0], enc), enc); +SEXP R_ut_parse(std::string name) { + ut_unit *u = ut_parse(sys, ut_trim(name.data(), enc), enc); if (u == NULL) - stop("syntax error, cannot parse '%s'", (char*)name[0]); + stop("syntax error, cannot parse '%s'", name); return ut_wrap(u); }