Skip to content

Commit

Permalink
FIX: Avoid segfault if saving an empty index
Browse files Browse the repository at this point in the history
Closes #205
  • Loading branch information
jlblancoc committed Jun 15, 2023
1 parent e5c97fe commit 5494a86
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ nanoflann 1.5.0: UNRELEASED
- Add examples with GUI (requires [mrpt-gui](https://docs.mrpt.org/reference/latest/group_mrpt_gui_grp.html)):
- nanoflann_gui_example_R3: Radius search on R³ Euclidean space.
- nanoflann_gui_example_bearings: NN search on non-Euclidean spaces.
* BUGFIXES:
- Avoid segfault if saving an empty index (Closes [#205](https://github.com/jlblancoc/nanoflann/issues/205)).

nanoflann 1.4.3: Released Jul 24, 2022
* Added flag SkipInitialBuildIndex to allow not wasting time building a tree when it will be loaded from a file later on ([PR #171](https://github.com/jlblancoc/nanoflann/pull/171)).
Expand Down
10 changes: 10 additions & 0 deletions examples/saveload_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ void kdtree_save_load_demo(const size_t N)
std::cout << "ret_index=" << ret_index
<< " out_dist_sqr=" << out_dist_sqr << std::endl;
}

// Stress test: try to save an empty index
{
PointCloud<double> emptyCloud;
my_kd_tree_t index(3 /*dim*/, emptyCloud);
std::ofstream f("index2.bin", std::ofstream::binary);
if (f.bad()) throw std::runtime_error("Error writing index file!");
index.saveIndex(f);
f.close();
}
}

int main()
Expand Down
20 changes: 11 additions & 9 deletions include/nanoflann.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,9 @@ struct L1_Adaptor
/* Process last 0-3 components. Not needed for standard vector lengths.
*/
while (a < last)
{ result += std::abs(*a++ - data_source.kdtree_get_pt(b_idx, d++)); }
{
result += std::abs(*a++ - data_source.kdtree_get_pt(b_idx, d++));
}
return result;
}

Expand Down Expand Up @@ -1362,7 +1364,7 @@ class KDTreeBaseClass
save_value(stream, obj.root_bbox_);
save_value(stream, obj.leaf_max_size_);
save_value(stream, obj.vAcc_);
save_tree(obj, stream, obj.root_node_);
if (obj.root_node_) save_tree(obj, stream, obj.root_node_);
}

/** Loads a previous index from a binary file.
Expand Down Expand Up @@ -1784,16 +1786,15 @@ class KDTreeSingleIndexAdaptor
}

/* Call recursively to search next level down. */
if (!searchLevel(
result_set, vec, bestChild, mindist, dists, epsError))
if (!searchLevel(result_set, vec, bestChild, mindist, dists, epsError))
{
// the resultset doesn't want to receive any more points, we're done
// searching!
return false;
}

DistanceType dst = dists[idx];
mindist = mindist + cut_dist - dst;
mindist = mindist + cut_dist - dst;
dists[idx] = cut_dist;
if (mindist * epsError <= result_set.worstDist())
{
Expand Down Expand Up @@ -2217,12 +2218,11 @@ class KDTreeSingleIndexDynamicAdaptor_
searchLevel(result_set, vec, bestChild, mindist, dists, epsError);

DistanceType dst = dists[idx];
mindist = mindist + cut_dist - dst;
mindist = mindist + cut_dist - dst;
dists[idx] = cut_dist;
if (mindist * epsError <= result_set.worstDist())
{
searchLevel(
result_set, vec, otherChild, mindist, dists, epsError);
searchLevel(result_set, vec, otherChild, mindist, dists, epsError);
}
dists[idx] = dst;
}
Expand Down Expand Up @@ -2440,7 +2440,9 @@ class KDTreeSingleIndexDynamicAdaptor
const SearchParameters& searchParams = {}) const
{
for (size_t i = 0; i < treeCount_; i++)
{ index_[i].findNeighbors(result, &vec[0], searchParams); }
{
index_[i].findNeighbors(result, &vec[0], searchParams);
}
return result.full();
}
};
Expand Down

0 comments on commit 5494a86

Please sign in to comment.