Skip to content

Commit 015ef54

Browse files
authored
Merge pull request #868 from Idclip/sdf2fog_crash
Fixed undefined behaviour with empty vector accesses
2 parents 78da23f + 2c8c4b9 commit 015ef54

File tree

3 files changed

+18
-14
lines changed

3 files changed

+18
-14
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Version 7.2.0 - In Development
3434
TypeList objects, manifesting in longer compile times.
3535
- Deprecated util::PagedArray::push_back due to a race condition. Instead
3636
use util::PagedArray::ValueBuffer::push_back which is faster and thread-safe.
37+
- Fixed various cases of undefined behavior in some LevelSetUtil methods
38+
[Reported by fkemmler]
3739

3840
API changes:
3941
- Deprecated tree::LeafManager::getNodes. This method is no longer used when

doc/changes.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Bug Fixes:
4949
due to a race condition. Instead use
5050
@vdblink::util::PagedArray::ValueBuffer::push_back util::PagedArray::ValueBuffer::push_back@endlink
5151
which is faster and thread-safe.
52+
- Fixed various cases of undefined behavior in some LevelSetUtil methods
53+
[Reported by fkemmler]
5254

5355
@par
5456
API changes:

openvdb/openvdb/tools/LevelSetUtil.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -993,12 +993,12 @@ computeEnclosedRegionMask(const TreeType& tree, typename TreeType::ValueType iso
993993
std::unique_ptr<CharLeafNodeType*[]> maskNodes(new CharLeafNodeType*[numLeafNodes]);
994994

995995
tbb::parallel_for(tbb::blocked_range<size_t>(0, numLeafNodes),
996-
LabelBoundaryVoxels<LeafNodeType>(isovalue, &nodes[0], maskNodes.get()));
996+
LabelBoundaryVoxels<LeafNodeType>(isovalue, nodes.data(), maskNodes.get()));
997997

998998
// create mask grid
999999
typename CharTreeType::Ptr maskTree(new CharTreeType(1));
10001000

1001-
PopulateTree<CharTreeType> populate(*maskTree, maskNodes.get(), &leafnodeCount[0], 1);
1001+
PopulateTree<CharTreeType> populate(*maskTree, maskNodes.get(), leafnodeCount.data(), 1);
10021002
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, numInternalNodes), populate);
10031003

10041004
// optionally evaluate the fill mask
@@ -1014,7 +1014,7 @@ computeEnclosedRegionMask(const TreeType& tree, typename TreeType::ValueType iso
10141014
new BoolLeafNodeType*[fillMaskNodes.size()]);
10151015

10161016
tbb::parallel_for(tbb::blocked_range<size_t>(0, fillMaskNodes.size()),
1017-
FillMaskBoundary<TreeType>(tree, isovalue, *fillMask, &fillMaskNodes[0],
1017+
FillMaskBoundary<TreeType>(tree, isovalue, *fillMask, fillMaskNodes.data(),
10181018
boundaryMaskNodes.get()));
10191019

10201020
tree::ValueAccessor<CharTreeType> maskAcc(*maskTree);
@@ -1053,7 +1053,7 @@ computeEnclosedRegionMask(const TreeType& tree, typename TreeType::ValueType iso
10531053

10541054
if (!extraMaskNodes.empty()) {
10551055
tbb::parallel_for(tbb::blocked_range<size_t>(0, extraMaskNodes.size()),
1056-
FlipRegionSign<CharLeafNodeType>(&extraMaskNodes[0]));
1056+
FlipRegionSign<CharLeafNodeType>(extraMaskNodes.data()));
10571057
}
10581058

10591059
// propagate sign information into tile region
@@ -1120,13 +1120,13 @@ computeInteriorMask(const TreeType& tree, typename TreeType::ValueType iso)
11201120
std::unique_ptr<BoolLeafNodeType*[]> maskNodes(new BoolLeafNodeType*[numLeafNodes]);
11211121

11221122
tbb::parallel_for(tbb::blocked_range<size_t>(0, numLeafNodes),
1123-
MaskInteriorVoxels<LeafNodeType>(iso, &nodes[0], maskNodes.get()));
1123+
MaskInteriorVoxels<LeafNodeType>(iso, nodes.data(), maskNodes.get()));
11241124

11251125

11261126
// create mask grid
11271127
typename BoolTreeType::Ptr maskTree(new BoolTreeType(false));
11281128

1129-
PopulateTree<BoolTreeType> populate(*maskTree, maskNodes.get(), &leafnodeCount[0], false);
1129+
PopulateTree<BoolTreeType> populate(*maskTree, maskNodes.get(), leafnodeCount.data(), false);
11301130
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, numInternalNodes), populate);
11311131

11321132

@@ -1135,7 +1135,7 @@ computeInteriorMask(const TreeType& tree, typename TreeType::ValueType iso)
11351135
maskTree->getNodes(internalMaskNodes);
11361136

11371137
tbb::parallel_for(tbb::blocked_range<size_t>(0, internalMaskNodes.size()),
1138-
MaskInteriorTiles<TreeType, BoolInternalNodeType>(iso, tree, &internalMaskNodes[0]));
1138+
MaskInteriorTiles<TreeType, BoolInternalNodeType>(iso, tree, internalMaskNodes.data()));
11391139

11401140
tree::ValueAccessor<const TreeType> acc(tree);
11411141

@@ -1929,7 +1929,7 @@ struct FloodFillSign
19291929
tree.getNodes(nodes);
19301930

19311931
if (!nodes.empty()) {
1932-
FindMinTileValue<InternalNodeType> minOp(&nodes[0]);
1932+
FindMinTileValue<InternalNodeType> minOp(nodes.data());
19331933
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, nodes.size()), minOp);
19341934
minSDFValue = std::min(minSDFValue, minOp.minValue);
19351935
}
@@ -1939,7 +1939,7 @@ struct FloodFillSign
19391939
std::vector<const LeafNodeType*> nodes;
19401940
tree.getNodes(nodes);
19411941
if (!nodes.empty()) {
1942-
FindMinVoxelValue<LeafNodeType> minOp(&nodes[0]);
1942+
FindMinVoxelValue<LeafNodeType> minOp(nodes.data());
19431943
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, nodes.size()), minOp);
19441944
minSDFValue = std::min(minSDFValue, minOp.minValue);
19451945
}
@@ -2194,13 +2194,13 @@ sdfToFogVolume(GridType& grid, typename GridType::ValueType cutoffDistance)
21942194
ValueType minSDFValue = std::numeric_limits<ValueType>::max();
21952195

21962196
{
2197-
level_set_util_internal::FindMinTileValue<InternalNodeType> minOp(&internalNodes[0]);
2197+
level_set_util_internal::FindMinTileValue<InternalNodeType> minOp(internalNodes.data());
21982198
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, internalNodes.size()), minOp);
21992199
minSDFValue = std::min(minSDFValue, minOp.minValue);
22002200
}
22012201

22022202
if (minSDFValue > ValueType(0.0)) {
2203-
level_set_util_internal::FindMinVoxelValue<LeafNodeType> minOp(&nodes[0]);
2203+
level_set_util_internal::FindMinVoxelValue<LeafNodeType> minOp(nodes.data());
22042204
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, nodes.size()), minOp);
22052205
minSDFValue = std::min(minSDFValue, minOp.minValue);
22062206
}
@@ -2213,13 +2213,13 @@ sdfToFogVolume(GridType& grid, typename GridType::ValueType cutoffDistance)
22132213
// (Positive values are set to zero with inactive state and negative values are remapped
22142214
// from zero to one with active state.)
22152215
tbb::parallel_for(tbb::blocked_range<size_t>(0, nodes.size()),
2216-
level_set_util_internal::SDFVoxelsToFogVolume<LeafNodeType>(&nodes[0], cutoffDistance));
2216+
level_set_util_internal::SDFVoxelsToFogVolume<LeafNodeType>(nodes.data(), cutoffDistance));
22172217

22182218
// Populate a new tree with the remaining leafnodes
22192219
typename TreeType::Ptr newTree(new TreeType(ValueType(0.0)));
22202220

22212221
level_set_util_internal::PopulateTree<TreeType> populate(
2222-
*newTree, &nodes[0], &leafnodeCount[0], 0);
2222+
*newTree, nodes.data(), leafnodeCount.data(), 0);
22232223
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, numInternalNodes), populate);
22242224

22252225
// Transform tile values (Negative valued tiles are set to 1.0 with active state.)
@@ -2228,7 +2228,7 @@ sdfToFogVolume(GridType& grid, typename GridType::ValueType cutoffDistance)
22282228

22292229
tbb::parallel_for(tbb::blocked_range<size_t>(0, internalNodes.size()),
22302230
level_set_util_internal::SDFTilesToFogVolume<TreeType, InternalNodeType>(
2231-
tree, &internalNodes[0]));
2231+
tree, internalNodes.data()));
22322232

22332233
{
22342234
tree::ValueAccessor<const TreeType> acc(tree);

0 commit comments

Comments
 (0)