From 60fddce474b9fcf57356f77598f46a2682faf8f9 Mon Sep 17 00:00:00 2001 From: abv Date: Fri, 25 May 2018 21:26:45 +0300 Subject: [PATCH] 0029669: Crash on opening a document with same Ocaf attributes with different IDs Added protection against clash of attributes with the same GUID when more than one attribute of the same type but with different GUIDs are stored in the file. If attribute with default GUID has already been read, then adding next empty attribute of the same type (done at start of its reading) will fail; in such case another attempt is made with Null GUID. --- .../BinLDrivers_DocumentRetrievalDriver.cxx | 18 +++++++- src/XmlMDF/XmlMDF.cxx | 21 +++++++++- tests/bugs/caf/bug29669 | 41 +++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 tests/bugs/caf/bug29669 diff --git a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx index 54d45b6311..434a971a7b 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx +++ b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx @@ -358,8 +358,24 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree tAtt = Handle(TDF_Attribute)::DownCast(myRelocTable.Find(anID)); else tAtt = aDriver->NewEmpty(); + if (tAtt->Label().IsNull()) - theLabel.AddAttribute (tAtt); + { + try + { + theLabel.AddAttribute (tAtt); + } + catch (const Standard_DomainError&) + { + // For attributes that can have arbitrary GUID (e.g. TDataStd_Integer), exception + // will be raised in valid case if attribute of that type with default GUID is already + // present on the same label; the reason is that actual GUID will be read later. + // To avoid this, set invalid (null) GUID to the newly added attribute (see #29669) + static const Standard_GUID fbidGuid; + tAtt->SetID (fbidGuid); + theLabel.AddAttribute (tAtt); + } + } else myMsgDriver->Send (aMethStr + "warning: attempt to attach attribute " + diff --git a/src/XmlMDF/XmlMDF.cxx b/src/XmlMDF/XmlMDF.cxx index dd6588e0a7..da52376a5b 100644 --- a/src/XmlMDF/XmlMDF.cxx +++ b/src/XmlMDF/XmlMDF.cxx @@ -36,6 +36,7 @@ #include #include #include +#include IMPLEMENT_DOMSTRING (TagString, "tag") IMPLEMENT_DOMSTRING (LabelString, "label") @@ -257,8 +258,24 @@ Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element& theElement, tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID)); else tAtt = driver -> NewEmpty(); - if (tAtt->Label().IsNull()) - theLabel.AddAttribute (tAtt); + + if (tAtt->Label().IsNull()) + { + try + { + theLabel.AddAttribute (tAtt); + } + catch (const Standard_DomainError&) + { + // For attributes that can have arbitrary GUID (e.g. TDataStd_Integer), exception + // will be raised in valid case if attribute of that type with default GUID is already + // present on the same label; the reason is that actual GUID will be read later. + // To avoid this, set invalid (null) GUID to the newly added attribute (see #29669) + static const Standard_GUID fbidGuid; + tAtt->SetID (fbidGuid); + theLabel.AddAttribute (tAtt); + } + } else driver->myMessageDriver->Send (TCollection_ExtendedString("XmlDriver warning: ") + diff --git a/tests/bugs/caf/bug29669 b/tests/bugs/caf/bug29669 new file mode 100644 index 0000000000..be0c470b4f --- /dev/null +++ b/tests/bugs/caf/bug29669 @@ -0,0 +1,41 @@ +puts " =================================================================== " +puts " 0029669: Crash on opening a document with same Ocaf attributes with different IDs" +puts " =================================================================== " +puts "" + +set aLabel 0:1 + +set aVal1 123 +set aVal2 321 + +set aGuid1 "12e94541-6dbc-11d4-b9c8-0060b0ee281b" +set aGuid2 "12e94541-6dbc-11d4-b9c8-0060b0ee281d" + +foreach format {{XmlOcaf xml} {BinOcaf cbf}} { + + NewDocument D [lindex $format 0] + + SetInteger D $aLabel $aVal1 $aGuid1 + SetInteger D $aLabel 100 + SetInteger D $aLabel $aVal2 $aGuid2 + + set aFile ${imagedir}/${casename}.[lindex $format 1] + SaveAs D $aFile + Close D + + if { ! [file exists $aFile] } { + puts "Error: cannot find file $aFile, document not saved" + } + + Open $aFile D + set val1 [GetInteger D $aLabel $aGuid1] + set val2 [GetInteger D $aLabel $aGuid2] + if { $val1 != $aVal1 } { + puts "Error: found $val1 while expected $aVal1" + } + if { $val2 != $aVal2 } { + puts "Error: found $val2 while expected $aVal2" + } + Close D +} + -- 2.39.5