]> OCCT Git - occt.git/commitdiff
0032931: Modeling Algorithms - Crash in ChFi3d_IsInFront when no face was found
authorCharlemagne Lasse <charlemagnelasse@gmail.com>
Wed, 13 Apr 2022 09:54:30 +0000 (11:54 +0200)
committersmoskvin <smoskvin@opencascade.com>
Wed, 20 Jul 2022 09:26:58 +0000 (12:26 +0300)
The ChFi3d_IsInFront code is currently not handling all the combinations
correctly. For example, if `if(fd1->IndexOfS2() == fd2->IndexOfS2())` is
true, it can happen that the `TopoDS::Face(DStr.Shape(fd1->Index(jf1)))`
returns a Face with entity == NULL. The subsequent usage of this NULL face
in `BRep_Tool::Parameters( Vtx, face )` will then cause a segfault.

While the best approach would be to identify the implementation bug in the
algorithm behind PChFi3d_IsInFron, a check + exception is used instead
because the actual algorithm is not known.

Signed-off-by: Charlemagne Lasse <charlemagnelasse@gmail.com>
src/ChFi3d/ChFi3d_Builder_0.cxx
tests/bugs/modalg_8/bug32931 [new file with mode: 0644]

index 27ea6dd75b4101a483fc56fddb880542744dd7a3..520f613f49545543484ed58149f1de80afe694a9 100644 (file)
@@ -819,10 +819,13 @@ Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
   if(fd1->IndexOfS1() == fd2->IndexOfS1()) { 
     jf1 = 1; jf2 = 1; 
     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
+    if (face.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL face");
     OrSave1 = cd1->Orientation(jf1);
     Or = OrFace1 = face.Orientation();
     OrSave2 = cd2->Orientation(jf2);
-    OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
+    const TopoDS_Shape& shape2 = DStr.Shape(fd2->Index(jf2));
+    if (shape2.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL shape");
+    OrFace2 = shape2.Orientation();
     visavis = Standard_True;
     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
     // The parameters of the other side are not used for orientation. This would raise problems
@@ -840,10 +843,13 @@ Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
   if(fd1->IndexOfS2() == fd2->IndexOfS1()) { 
     jf1 = 2; jf2 = 1; 
     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
+    if (face.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL face");
     OrSave1 = cd1->Orientation(jf1);
     Or = OrFace1 = face.Orientation();
     OrSave2 = cd2->Orientation(jf2);
-    OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
+    const TopoDS_Shape& shape2 = DStr.Shape(fd2->Index(jf2));
+    if (shape2.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL shape");
+    OrFace2 = shape2.Orientation();
     visavis = Standard_True;
     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
     // The parameters of the other side are not used for orientation. This would raise problems
@@ -873,10 +879,13 @@ Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
   if(fd1->IndexOfS1() == fd2->IndexOfS2()) { 
     jf1 = 1; jf2 = 2; 
     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
+    if (face.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL face");
     OrSave1 = cd1->Orientation(jf1);
     Or = OrFace1 = face.Orientation();
     OrSave2 = cd2->Orientation(jf2);
-    OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
+    const TopoDS_Shape& shape2 = DStr.Shape(fd2->Index(jf2));
+    if (shape2.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL shape");
+    OrFace2 = shape2.Orientation();
     visavis = Standard_True;
     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
     // The parameters of the other side are not used for orientation.
@@ -906,10 +915,13 @@ Standard_Boolean ChFi3d_IsInFront(TopOpeBRepDS_DataStructure& DStr,
   if(fd1->IndexOfS2() == fd2->IndexOfS2()) { 
     jf1 = 2; jf2 = 2; 
     face = TopoDS::Face(DStr.Shape(fd1->Index(jf1)));
+    if (face.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL face");
     OrSave1 = cd1->Orientation(jf1);
     Or = OrFace1 = face.Orientation();
     OrSave2 = cd2->Orientation(jf2);
-    OrFace2 = DStr.Shape(fd2->Index(jf2)).Orientation();
+    const TopoDS_Shape& shape2 = DStr.Shape(fd2->Index(jf2));
+    if (shape2.IsNull()) throw Standard_NullObject("ChFi3d_IsInFront : Trying to check orientation of NULL shape");
+    OrFace2 = shape2.Orientation();
     visavis = Standard_True;
     sameside = ChFi3d::SameSide(Or,OrSave1,OrSave2,OrFace1,OrFace2);
     // The parameters of the other side are not used for orientation.
diff --git a/tests/bugs/modalg_8/bug32931 b/tests/bugs/modalg_8/bug32931
new file mode 100644 (file)
index 0000000..344b5b0
--- /dev/null
@@ -0,0 +1,26 @@
+puts "TODO OCC32931 ALL: Tcl Exception"
+puts "TODO OCC32931 ALL: TEST INCOMPLETE"
+
+puts "============"
+puts "OCC32931: Modeling Algorithms - Crash in ChFi3d_IsInFront when no face was found"
+puts "============"
+puts ""
+
+# Load & prepare data.
+restore [locate_data_file bug32931.brep] b
+explode b E
+
+# Make screenshot before filleting.
+smallview
+donly b b_10 1 b_18 1 b_19 1 b_20 1 b_21 1 b_17
+fit
+xwd $imagedir/${test_image}_1.png
+
+# Make fillet.
+blend result b 1 b_10 1 b_18 1 b_19 1 b_20 1 b_21 1 b_17
+
+# Make screenshot after filleting.
+donly result
+fit
+xwd $imagedir/${test_image}_2.png
+