1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0033320: Data Exchange - Reading of a VRML file with a long line fails

Implement rolling back input stream to split on possible logical parts by comma or space.
This commit is contained in:
vro 2023-01-24 09:48:33 +00:00 committed by vglukhik
parent 0ca21a9112
commit 14b64f123d
2 changed files with 69 additions and 19 deletions

View File

@ -194,29 +194,63 @@ const Handle(VrmlData_WorldInfo)& VrmlData_Scene::WorldInfo() const
//purpose :
//=======================================================================
VrmlData_ErrorStatus VrmlData_Scene::readLine (VrmlData_InBuffer& theBuffer)
VrmlData_ErrorStatus VrmlData_Scene::readLine(VrmlData_InBuffer& theBuffer)
{
VrmlData_ErrorStatus aStatus = VrmlData_StatusOK;
if (theBuffer.Input.eof())
aStatus = VrmlData_EndOfFile;
else {
theBuffer.Input.getline (theBuffer.Line, sizeof(theBuffer.Line));
theBuffer.LineCount++;
const int stat = theBuffer.Input.rdstate();
if (stat & std::ios::badbit) {
aStatus = VrmlData_UnrecoverableError;
}
else if (stat & std::ios::failbit) {
if (stat & std::ios::eofbit) {
aStatus = VrmlData_EndOfFile;
}
else {
aStatus = VrmlData_GeneralError;
}
}
theBuffer.LinePtr = &theBuffer.Line[0];
theBuffer.IsProcessed = Standard_False;
{
return VrmlData_EndOfFile;
}
// Read a line.
theBuffer.Input.getline(theBuffer.Line, sizeof(theBuffer.Line));
// Check the number of read symbols.
// If maximum number is read, process the array of symbols separately
// rolling back the array to the last comma or space symbol.
std::streamsize aNbChars = theBuffer.Input.gcount();
if (theBuffer.Input.rdstate() & std::ios::failbit &&
aNbChars == sizeof(theBuffer.Line) - 1)
{
// Clear the error.
// We will fix it here below.
theBuffer.Input.clear();
size_t anInd = aNbChars - 1;
for (; anInd > 0; anInd--)
{
Standard_Character aChar = theBuffer.Line[anInd];
if (aChar == ',' || aChar == ' ')
{
theBuffer.Line[anInd + 1] = '\0';
break;
}
}
if (anInd == 0) // no possible to rolling back
{
return VrmlData_UnrecoverableError;
}
theBuffer.Input.seekg(-(aNbChars - anInd - 1), std::ios::cur);
}
// Check the reading status.
theBuffer.LineCount++;
const int stat = theBuffer.Input.rdstate();
if (stat & std::ios::badbit)
{
aStatus = VrmlData_UnrecoverableError;
}
else if (stat & std::ios::failbit)
{
if (stat & std::ios::eofbit)
{
aStatus = VrmlData_EndOfFile;
}
else
{
aStatus = VrmlData_GeneralError;
}
}
theBuffer.LinePtr = &theBuffer.Line[0];
theBuffer.IsProcessed = Standard_False;
return aStatus;
}

View File

@ -0,0 +1,16 @@
puts "============"
puts "0033320: Data Exchange - Reading of a VRML file with a long line fails"
puts "============"
puts ""
set aFile [locate_data_file bug33320_wM_BugBlender_2.wrl]
catch { Close D }
ReadVrml D $aFile
vinit Driver1/View_${casename}/${casename}
XDisplay D -dispMode 1
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png
Close D