vtkOBJReader crash on reading OBJ that does not contain vertex normal
I tried to visualize an OBJ file with VTK 9.2.2 and found vtkOBJReader crash upon reading it, while Blender can import the same OBJ.
The backtrace is:
1 vtkAOSDataArrayTemplate<float>::GetTuple vtkAOSDataArrayTemplate.txx 275 0x7ffff6ee05e5
2 vtkOBJReader::RequestData vtkOBJReader.cxx 978 0x7ffff7b4c793
3 vtkPolyDataAlgorithm::ProcessRequest vtkPolyDataAlgorithm.cxx 87 0x7ffff28aaec6
4 vtkExecutive::CallAlgorithm vtkExecutive.cxx 734 0x7ffff287faf9
5 vtkDemandDrivenPipeline::ExecuteData vtkDemandDrivenPipeline.cxx 461 0x7ffff2876004
6 vtkCompositeDataPipeline::ExecuteData vtkCompositeDataPipeline.cxx 162 0x7ffff2869321
7 vtkDemandDrivenPipeline::ProcessRequest vtkDemandDrivenPipeline.cxx 260 0x7ffff28755b1
8 vtkStreamingDemandDrivenPipeline::ProcessRequest vtkStreamingDemandDrivenPipeline.cxx 343 0x7ffff2943429
9 vtkDemandDrivenPipeline::UpdateData vtkDemandDrivenPipeline.cxx 418 0x7ffff2875de9
10 vtkStreamingDemandDrivenPipeline::Update vtkStreamingDemandDrivenPipeline.cxx 417 0x7ffff29437c4
11 vtkStreamingDemandDrivenPipeline::Update vtkStreamingDemandDrivenPipeline.cxx 380 0x7ffff294364d
12 vtkAlgorithm::Update vtkAlgorithm.cxx 1406 0x7ffff285f3b4
13 vtkAlgorithm::Update vtkAlgorithm.cxx 1400 0x7ffff285f37f
14 main main.cpp 7 0x555555555297
After some debugging, it turns out it crashed since the buffer is null, so data
pointer is invalid:
template <class ValueTypeT>
double* vtkAOSDataArrayTemplate<ValueTypeT>::GetTuple(vtkIdType tupleIdx)
{
ValueTypeT* data = this->Buffer->GetBuffer() + tupleIdx * this->NumberOfComponents;
double* tuple = &this->LegacyTuple[0];
// See note in SetTuple about std::copy vs for loops on MSVC.
for (int i = 0; i < this->NumberOfComponents; ++i)
{
tuple[i] = static_cast<double>(data[i]);
}
return &this->LegacyTuple[0];
}
In vtkOBJReader::RequestData
, normals
has never been inserted since the OBJ file does contain any vn
field (yet n_normal_pts
is 3, I didn't figure out why it isn't 0). This accounts why normals->GetTuple
crashed in vtkOBJReader::RequestData
:
// copy the normal for this point across (if there is one)
if (n_normal_pts > 0)
{
new_normals->InsertNextTuple(normals->GetTuple(normal_pts[pointi]));
}
The OBJ is generated by an AI trained model so it may not be standard. But according to http://paulbourke.net/dataformats/obj/ and http://netghost.narod.ru/gff/graphics/summary/waveobj.htm, the vertex normals data is optional in an OBJ file, so vtkOBJReader
should not assume normals must be valid.
The bug-reproducing project, together with the OBJ file, is in the attachment: