Description
ShapedNeighborhoodIterator has a constructor that accepts a pointer to a const Image:
ShapedNeighborhoodIterator(const SizeType & radius, const ImageType * ptr, const RegionType & region)
At
|
ShapedNeighborhoodIterator(const SizeType & radius, const ImageType * ptr, const RegionType & region) |
This offers a "backdoor" for users to modify an image via a pointer-to-const, thereby breaking logical const-correctness. It is also unusual within ITK. Constructors of other non-const ITK iterators do not have such a const ImageType * parameter.
Steps to Reproduce
The following code shows how to modify an image via a const ImageType, by exploiting this ShapedNeighborhoodIterator bug. It does so by calling shapedNeighborhoodIterator.SetCenterPixel(1), but it might as well do so iteratively, by setting the pixel values from shapedNeighborhoodIterator.Begin() to shapedNeighborhoodIterator.End()
#include "itkShapedNeighborhoodIterator.h"
#include "itkImageBufferRange.h"
void
TestModifyingConstImage()
{
static constexpr unsigned int dimension{ 2 };
using ImageType = itk::Image<int, dimension>;
constexpr auto modifyConstImage = [](const ImageType * const constImage) {
constexpr auto radius = itk::Size<dimension>::Filled(1);
const auto region = constImage->GetBufferedRegion();
itk::ShapedNeighborhoodIterator<ImageType> shapedNeighborhoodIterator(radius, constImage, region);
shapedNeighborhoodIterator.SetLocation(itk::Index<dimension>::Filled(1));
shapedNeighborhoodIterator.SetCenterPixel(1);
};
const auto image = ImageType::New();
image->SetRegions(itk::Size<dimension>::Filled(3));
image->AllocateInitialized();
const auto printImage = [image] {
for (const int pixelValue : itk::ImageBufferRange<ImageType>(*image))
{
std::cout << pixelValue;
}
std::cout << '\n';
};
printImage(); // Prints "000000000".
modifyConstImage(image);
printImage(); // Prints "000010000"!
}
Expected behavior
The following line should not compile. ShapedNeighborhoodIterator should not accept a "const" image as argument.
itk::ShapedNeighborhoodIterator<ImageType> shapedNeighborhoodIterator(radius, constImage, region);
Actual behavior
It prints the following lines, indicating the center pixel value of the 3x3 test image has changed.
Reproducibility
100%
Versions
Today's main revision: commit 056f5eb
Environment
Any supported ITK platform
Additional Information
I'm considering to submit a pull request to fix this issue.
For the record, it appears that this mistake (having a const ImageType * constructor parameter) was there already when ShapedNeighborhoodIterator was introduced, with commit fc6d1b2, Jan 8, 2003:
|
ShapedNeighborhoodIterator(const SizeType &radius, |
|
const ImageType * ptr, |
|
const RegionType ®ion |
Description
ShapedNeighborhoodIterator has a constructor that accepts a pointer to a const
Image:At
ITK/Modules/Core/Common/include/itkShapedNeighborhoodIterator.h
Line 222 in 056f5eb
This offers a "backdoor" for users to modify an image via a pointer-to-const, thereby breaking logical const-correctness. It is also unusual within ITK. Constructors of other non-const ITK iterators do not have such a
const ImageType *parameter.Steps to Reproduce
The following code shows how to modify an image via a
const ImageType, by exploiting this ShapedNeighborhoodIterator bug. It does so by callingshapedNeighborhoodIterator.SetCenterPixel(1), but it might as well do so iteratively, by setting the pixel values fromshapedNeighborhoodIterator.Begin()toshapedNeighborhoodIterator.End()Expected behavior
The following line should not compile.
ShapedNeighborhoodIteratorshould not accept a "const" image as argument.itk::ShapedNeighborhoodIterator<ImageType> shapedNeighborhoodIterator(radius, constImage, region);Actual behavior
It prints the following lines, indicating the center pixel value of the 3x3 test image has changed.
Reproducibility
100%
Versions
Today's main revision: commit 056f5eb
Environment
Any supported ITK platform
Additional Information
I'm considering to submit a pull request to fix this issue.
For the record, it appears that this mistake (having a
const ImageType *constructor parameter) was there already when ShapedNeighborhoodIterator was introduced, with commit fc6d1b2, Jan 8, 2003:ITK/Code/Common/itkShapedNeighborhoodIterator.h
Lines 181 to 183 in fc6d1b2