Multiple problems with vtkXMLDataParser::ReadCompressedData
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
(This problem was found with VTK 5.6.0, but could not be reported as such through the web page. I have deep suspicion that it was not resolved at least in the 5.x.x versions).
The problem showed up when I was using vtkXMLImageReader to read a vti file in a concurrent environment: one application was writing a series of vti files, and another one (mine) attempted to find them and read them.
At some stage, my application would encounter a file whose header may have been incomplete or corrupted, so that when getting into vtkXMLDataParser::ReadCompressedData , the class member BlockUncompressedSize (which is read from the "incomplete" vti file) was 0. This triggered a division by zero error in this function, and crashed my application.
So a first problem to fix is to prevent the division by zero, possibly by detecting and reporting the failure in another way.
Next, I tried a workaround in Visual C++ to catch the DBZ exception in a __try/__except mechanism. This was successful. However, the premature termination of the reading left the file open, so I could not do anything with it while my application was running. Rather than continue smoothly and report the error to the user, my application had to be terminated to deal with the bad file.
I was using a read function based on the VTK demo program DumpXMLFile.cxx, that has the following structure:
template vtkDataSet ReadAnXMLFile(const charfileName) { vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(fileName); reader->Update(); reader->GetOutput()->Register(reader); return vtkDataSet::SafeDownCast(reader->GetOutput()); }
In this case, after catching the exception, I'd expect the destructor of TReader (where TReader = vtkXMLIMageDataReader) to be called when the smart pointer goes out of scope, and close the file. Apparently, this did not happen. I suspect that the problem of not closing the file is not in the derived class but in one of the base classes.
Explicitly closing the file with the CloseVTKFile method is impossible because the method is declared protected. My only option, at this stage, was to derive my own class and include in it a public ForceCloseVTKFile method to do this. This is dirty programming as one would ever imagine.
To summarize, these are the issues on the plate:
- Detect zeros while decompressing XML data and prevent division by zero
- Make sure that the XML reader closes the file in the reader's destructor
- Maybe provide public access to the file object or its open/close methods so that a class user can do this on will, not using dirty tricks.
Attached is an example file that crashes the code snippet above.