Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[filters] Potentially undefined behavior in VoxelGridCovariance #6174

Open
thallerod opened this issue Nov 19, 2024 · 3 comments
Open

[filters] Potentially undefined behavior in VoxelGridCovariance #6174

thallerod opened this issue Nov 19, 2024 · 3 comments
Labels

Comments

@thallerod
Copy link
Contributor

Undefined behavior if floating-point expression doesn't fit into an int.

min_b_[0] = static_cast<int> (std::floor (min_p[0] * inverse_leaf_size_[0]));

@thallerod thallerod added kind: bug Type of issue status: triage Labels incomplete labels Nov 19, 2024
@mvieth
Copy link
Member

mvieth commented Nov 19, 2024

Hi, how did you become aware that this could be a problem? Did you encounter this in practice, or was there a compiler warning, or something else?
And why exactly would it not fit into an int? Because min_p is very large, or because inverse_leaf_size_ is very large?

@mvieth mvieth added module: filters and removed status: triage Labels incomplete labels Nov 19, 2024
@thallerod
Copy link
Contributor Author

Purely by inspection. But something like this would trigger it:

#include <iostream>
#include <pcl/filters/voxel_grid_covariance.h>

int dummy(double offset, double leafsize) {
  pcl::PointCloud<pcl::PointXYZ>::Ptr pc(new pcl::PointCloud<pcl::PointXYZ>);

  for(int i = 0; i < 10; ++i)
  {
    pc->emplace_back(offset + i, 0.0, 0.0);
  }

  pcl::VoxelGridCovariance<pcl::PointXYZ> vgc;
  vgc.setInputCloud(pc);
  vgc.setLeafSize(leafsize, 1.0, 1.0);
  vgc.filter();
  return vgc.getLeaves().size();
}

int main()
{
  std::cout << dummy(1e5, 1e-3) << "\n";
  std::cout << dummy(1e6, 1e-3) << "\n";
  std::cout << dummy(1e7, 1e-3) << "\n";  // (offset / leafsize) > std::numeric_limits<int>::max()
  std::cout << dummy(1e6, 1e-4) << "\n";  // (offset / leafsize) > std::numeric_limits<int>::max()
}

Output (expecting 10 leaves):

10
10
1
1

@mvieth
Copy link
Member

mvieth commented Nov 22, 2024

Thanks for the additional information. So a combination of a point cloud that is far away from (0, 0, 0), and a small leaf size could potentially trigger this. I will look into it further when I have time. Maybe, instead of using min_b_, it might be an option to subtract min_p from every point, then multiply with inverse_leaf_size_. But we need to make sure that this does not change the behaviour of VoxelGridCovariance, and does not make it slower.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants