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 +} +