Skip to content

Commit

Permalink
Fix out-of-bounds reads in low level spline tests.
Browse files Browse the repository at this point in the history
Enable tests to compare things which aren't floating point numbers.
  • Loading branch information
cnweaver committed Dec 2, 2017
1 parent cbe6955 commit 0b2bf26
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 20 deletions.
45 changes: 33 additions & 12 deletions test/test.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <cmath>
#include <map>
#include <string>
#include <sstream>
Expand All @@ -11,22 +12,42 @@ void emit_error(const std::string& file, size_t line,
emit_error(__FILE__,__LINE__,#cond,##__VA_ARGS__); \
}while(0)

template<typename T>
std::string express_comparison(const std::string& e1, const T& v1,
const std::string& e2, const T& v2,
const T& tolerance=0){
std::ostringstream ss;
ss.precision(16);
ss << v1 << " (" << e1 << ") != " << v2 << " (" << e2 << ")";
if(tolerance!=0)
ss << " to within " << tolerance;
return(ss.str());
namespace{
template<typename T1, typename T2>
std::string express_comparison(const std::string& e1, const T1& v1,
const std::string& e2, const T2& v2){
std::ostringstream ss;
ss.precision(16);
ss << v1 << " (" << e1 << ") != " << v2 << " (" << e2 << ")";
return(ss.str());
}
template<typename T>
std::string express_comparison(const std::string& e1, const T& v1,
const std::string& e2, const T& v2,
const T& tolerance=0){
std::ostringstream ss;
ss.precision(16);
ss << v1 << " (" << e1 << ") != " << v2 << " (" << e2 << ")";
if(tolerance!=0)
ss << " to within " << tolerance;
return(ss.str());
}

bool ensure_equal_impl(float v1, float v2){
return(v1==v2 || (std::isnan(v1) && std::isnan(v2)));
}
bool ensure_equal_impl(double v1, double v2){
return(v1==v2 || (std::isnan(v1) && std::isnan(v2)));
}
template<typename T1, typename T2>
bool ensure_equal_impl(const T1& v1, const T2& v2){
return(v1==v2);
}
}

#define ENSURE_EQUAL(first,second,...) \
do{ \
if(!((first)==(second) || \
(std::isnan(first) && std::isnan(second)))) \
if(!ensure_equal_impl(first,second)) \
emit_error(__FILE__,__LINE__, \
express_comparison(#first,first,#second,second),##__VA_ARGS__); \
}while(0)
Expand Down
28 changes: 20 additions & 8 deletions test/test_eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,15 @@ TEST(bsplvb_simple_vs_bspline){

// Generate a random knot field.
{
//insert dummy knots in anticipation of what would otherwise be out-of-bounds accesses
knotvec.insert(knotvec.end(),order,0.);
std::uniform_real_distribution<> uniform(0,1);
for (size_t i = 0; i < n_knots; i++)
knotvec.push_back(uniform(rng));
knotvec.insert(knotvec.end(),order,0.); //more dummy knots
}
std::sort(knotvec.begin(), knotvec.end());
knots = knotvec.data();
std::sort(knotvec.begin()+order, knotvec.begin()+order+n_knots);
knots = knotvec.data()+order; //offset past inital dummy knots

// Before the first fully-supported knot.
for (size_t i = 0; i < order+1; i++) {
Expand Down Expand Up @@ -248,12 +251,15 @@ TEST(bspline_deriv_nonzero_vs_bspline_deriv){

// Generate a random knot field.
{
//insert dummy knots in anticipation of what would otherwise be out-of-bounds accesses
knotvec.insert(knotvec.end(),order,0.);
std::uniform_real_distribution<> uniform(0,1);
for (size_t i = 0; i < n_knots; i++)
knotvec.push_back(uniform(rng));
knotvec.insert(knotvec.end(),order,0.); //more dummy knots
}
std::sort(knotvec.begin(), knotvec.end());
knots = knotvec.data();
std::sort(knotvec.begin()+order, knotvec.begin()+order+n_knots);
knots = knotvec.data()+order; //offset past inital dummy knots

// Before the first fully-supported knot.
for (size_t i = 0; i < order+1; i++) {
Expand Down Expand Up @@ -333,12 +339,15 @@ TEST(bspline_nonzero_vs_bspline){

// Generate a random knot field.
{
//insert dummy knots in anticipation of what would otherwise be out-of-bounds accesses
knotvec.insert(knotvec.end(),order,0.);
std::uniform_real_distribution<> uniform(0,1);
for (size_t i = 0; i < n_knots; i++)
knotvec.push_back(uniform(rng));
knotvec.insert(knotvec.end(),order,0.); //more dummy knots
}
std::sort(knotvec.begin(), knotvec.end());
knots = knotvec.data();
std::sort(knotvec.begin()+order, knotvec.begin()+order+n_knots);
knots = knotvec.data()+order; //offset past inital dummy knots

// Before the first fully-supported knot.
for (size_t i = 0; i < order+1; i++) {
Expand Down Expand Up @@ -435,12 +444,15 @@ TEST(single_basis_vs_multi){

// Generate a random knot field.
{
//insert dummy knots in anticipation of what would otherwise be out-of-bounds accesses
knotvec.insert(knotvec.end(),order,0.);
std::uniform_real_distribution<> uniform(0,1);
for (size_t i = 0; i < n_knots; i++)
knotvec.push_back(uniform(rng));
knotvec.insert(knotvec.end(),order,0.); //more dummy knots
}
std::sort(knotvec.begin(), knotvec.end());
knots = knotvec.data();
std::sort(knotvec.begin()+order, knotvec.begin()+order+n_knots);
knots = knotvec.data()+order; //offset past inital dummy knots

// Before the first fully-supported knot.
for (size_t i = 0; i < order+1; i++) {
Expand Down

0 comments on commit 0b2bf26

Please sign in to comment.