From: msv Date: Fri, 10 Jan 2020 17:59:51 +0000 (+0300) Subject: 0031292: Data Exchange - SIGSEGV on reading STEP file with references to invalid... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=068969acefda7e7062a12e3a048c618dd5278b54;p=occt-copy.git 0031292: Data Exchange - SIGSEGV on reading STEP file with references to invalid entities Changes: - in StepData_StepReaderData::ReadEntity, make sure that entity handle is not null before calling IsKind() of it. - in StepData_StepReaderData::SetEntityNumbers, do not invert the sign of entity number of referenced parameter if the second pass is not required. Otherwise, the number -1 (obviously invalid) becomes 1 (invalid, but not obviously) without further correction of it. - in StepData_UndefinedEntity::ReadRecord, consider the case when the entity number is positive but refers to non-existing entity. In this case literal value will be used instead of null entity for the problematic parameter. --- diff --git a/src/StepData/StepData_StepReaderData.cxx b/src/StepData/StepData_StepReaderData.cxx index 3c64208060..69bcda5903 100644 --- a/src/StepData/StepData_StepReaderData.cxx +++ b/src/StepData/StepData_StepReaderData.cxx @@ -1038,7 +1038,7 @@ Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num, if (entent.IsNull() || !entent->IsKind(atype)) { errmess = new String("Parameter n0.%d (%s) : Entity has illegal type"); - if (entent->IsKind(STANDARD_TYPE(StepData_UndefinedEntity))) + if (!entent.IsNull() && entent->IsKind(STANDARD_TYPE(StepData_UndefinedEntity))) ent = entent; } else ent = entent; @@ -1087,7 +1087,7 @@ Standard_Boolean StepData_StepReaderData::ReadEntity(const Standard_Integer num, { errmess = new String("Parameter n0.%d (%s) : Entity has illegal type"); //fot not suppported STEP entity - if (entent->IsKind(STANDARD_TYPE(StepData_UndefinedEntity))) + if (!entent.IsNull() && entent->IsKind(STANDARD_TYPE(StepData_UndefinedEntity))) sel.SetValue(entent); } else @@ -1583,8 +1583,10 @@ void StepData_StepReaderData::SetEntityNumbers(const Standard_Boolean withmap) if (num0 > 0) FP.SetEntityNumber(num0); // ET VOILA, on a resolu else FP.SetEntityNumber(-id); // CONFLIT -> faudra resoudre ... } else { // NON RESOLU, si pas pbmap, le dire - FP.SetEntityNumber(-id); - if (pbmap) continue; // pbmap : on se retrouvera + if (pbmap) { + FP.SetEntityNumber(-id); + continue; // pbmap : on se retrouvera + } char failmess[100]; // ... Construire le Check ... sprintf(failmess, diff --git a/src/StepData/StepData_UndefinedEntity.cxx b/src/StepData/StepData_UndefinedEntity.cxx index 87765da9f0..48b8670b51 100644 --- a/src/StepData/StepData_UndefinedEntity.cxx +++ b/src/StepData/StepData_UndefinedEntity.cxx @@ -67,13 +67,16 @@ void StepData_UndefinedEntity::ReadRecord(const Handle(StepData_StepReaderData)& Standard_Integer nume = 0; if (partyp == Interface_ParamIdent) { nume = SR->ParamNumber(num,i); + if (nume > 0) { + anent = SR->BoundEntity(nume); + if (anent.IsNull()) { + nume = 0; + } + } if (nume <= 0) { ach->AddFail("A reference to another entity is unresolved"); partyp = Interface_ParamVoid; } - else { - anent = SR->BoundEntity(nume); - } } else if (partyp == Interface_ParamSub) { nume = SR->ParamNumber(num,i);