summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2014-01-14 01:49:55 (GMT)
committerMarius Kintel <marius@kintel.net>2014-01-14 01:49:55 (GMT)
commit23b04c3a9f1aba164d7429fee4669de18a32d9a8 (patch)
tree9256565d394e35850a8b01ba11c8820546e3c960
parente6bfee021b3cb4843a78cf7b526986f51966de32 (diff)
bugfix: division by zero can cause malformed primitives
-rw-r--r--src/mathc99.h2
-rw-r--r--src/primitives.cc30
-rw-r--r--testdata/scad/features/primitive-inf-tests.scad9
-rw-r--r--tests/regression/cgalpngtest/primitive-inf-tests-expected.pngbin0 -> 4408 bytes
-rw-r--r--tests/regression/dumptest/primitive-inf-tests-expected.csg10
-rw-r--r--tests/regression/opencsgtest/primitive-inf-tests-expected.pngbin0 -> 4408 bytes
-rw-r--r--tests/regression/throwntogethertest/primitive-inf-tests-expected.pngbin0 -> 4408 bytes
7 files changed, 41 insertions, 10 deletions
diff --git a/src/mathc99.h b/src/mathc99.h
index ae31a22..d1dc504 100644
--- a/src/mathc99.h
+++ b/src/mathc99.h
@@ -13,6 +13,8 @@ float fmax(float a, float b);
#else
#include <math.h>
+#include <cmath>
+using std::isinf;
#endif
diff --git a/src/primitives.cc b/src/primitives.cc
index 53b2e19..c7ebb82 100644
--- a/src/primitives.cc
+++ b/src/primitives.cc
@@ -35,6 +35,7 @@
#include "visitor.h"
#include "context.h"
#include "calc.h"
+#include "mathc99.h"
#include <sstream>
#include <assert.h>
#include <boost/assign/std/vector.hpp>
@@ -293,8 +294,9 @@ PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const
{
PolySet *p = new PolySet();
- if (this->type == CUBE && this->x > 0 && this->y > 0 && this->z > 0)
- {
+ if (this->type == CUBE &&
+ this->x > 0 && this->y > 0 && this->z > 0 &&
+ !isinf(this->x) > 0 && !isinf(this->y) > 0 && !isinf(this->z) > 0) {
double x1, x2, y1, y2, z1, z2;
if (this->center) {
x1 = -this->x/2;
@@ -347,7 +349,7 @@ PolySet *PrimitiveNode::evaluate_polyset(class PolySetEvaluator *) const
p->append_vertex(x1, y2, z2);
}
- if (this->type == SPHERE && this->r1 > 0)
+ if (this->type == SPHERE && this->r1 > 0 && !isinf(this->r1))
{
struct ring_s {
point2d *points;
@@ -415,8 +417,9 @@ sphere_next_r2:
}
if (this->type == CYLINDER &&
- this->h > 0 && this->r1 >=0 && this->r2 >= 0 && (this->r1 > 0 || this->r2 > 0))
- {
+ this->h > 0 && !isinf(this->h) &&
+ this->r1 >=0 && this->r2 >= 0 && (this->r1 + this->r2) > 0 &&
+ !isinf(this->r1) && !isinf(this->r2)) {
int fragments = Calc::get_fragments_from_r(fmax(this->r1, this->r2), this->fn, this->fs, this->fa);
double z1, z2;
@@ -480,12 +483,18 @@ sphere_next_r2:
for (size_t i=0; i<this->faces.toVector().size(); i++)
{
p->append_poly();
- for (size_t j=0; j<this->faces.toVector()[i].toVector().size(); j++) {
- size_t pt = this->faces.toVector()[i].toVector()[j].toDouble();
+ const Value::VectorType &vec = this->faces.toVector()[i].toVector();
+ for (size_t j=0; j<vec.size(); j++) {
+ size_t pt = vec[j].toDouble();
if (pt < this->points.toVector().size()) {
double px, py, pz;
- if (this->points.toVector()[pt].getVec3(px, py, pz))
- p->insert_vertex(px, py, pz);
+ if (!this->points.toVector()[pt].getVec3(px, py, pz) ||
+ isinf(px) || isinf(py) || isinf(pz)) {
+ PRINTB("ERROR: Unable to convert point at index %d to a vec3 of numbers", j);
+ delete p;
+ return NULL;
+ }
+ p->insert_vertex(px, py, pz);
}
}
}
@@ -532,7 +541,8 @@ sphere_next_r2:
for (size_t i=0; i<this->points.toVector().size(); i++) {
double x,y;
- if (!this->points.toVector()[i].getVec2(x, y)) {
+ if (!this->points.toVector()[i].getVec2(x, y) ||
+ isinf(x) || isinf(y)) {
PRINTB("ERROR: Unable to convert point at index %d to a vec2 of numbers", i);
delete p;
return NULL;
diff --git a/testdata/scad/features/primitive-inf-tests.scad b/testdata/scad/features/primitive-inf-tests.scad
new file mode 100644
index 0000000..a0bca32
--- /dev/null
+++ b/testdata/scad/features/primitive-inf-tests.scad
@@ -0,0 +1,9 @@
+cube(1/0);
+cube([0,0,1/0]);
+cylinder(h=10, r=1/0);
+cylinder(h=10, r1=1, r2=1/0);
+cylinder(h=1/0);
+sphere(1/0);
+polygon([[0,0,0],[1,0,0],[1,1/0,0]]);
+polyhedron(points = [[1/0,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]],
+ triangles = [[0,4,2],[0,2,5],[0,3,4],[0,5,3],[1,2,4],[1,5,2],[1,4,3], [1,3,5]]);
diff --git a/tests/regression/cgalpngtest/primitive-inf-tests-expected.png b/tests/regression/cgalpngtest/primitive-inf-tests-expected.png
new file mode 100644
index 0000000..50d838c
--- /dev/null
+++ b/tests/regression/cgalpngtest/primitive-inf-tests-expected.png
Binary files differ
diff --git a/tests/regression/dumptest/primitive-inf-tests-expected.csg b/tests/regression/dumptest/primitive-inf-tests-expected.csg
new file mode 100644
index 0000000..1827d7e
--- /dev/null
+++ b/tests/regression/dumptest/primitive-inf-tests-expected.csg
@@ -0,0 +1,10 @@
+group() {
+ cube(size = [inf, inf, inf], center = false);
+ cube(size = [0, 0, inf], center = false);
+ cylinder($fn = 0, $fa = 12, $fs = 2, h = 10, r1 = inf, r2 = inf, center = false);
+ cylinder($fn = 0, $fa = 12, $fs = 2, h = 10, r1 = 1, r2 = inf, center = false);
+ cylinder($fn = 0, $fa = 12, $fs = 2, h = inf, r1 = 1, r2 = 1, center = false);
+ sphere($fn = 0, $fa = 12, $fs = 2, r = inf);
+ polygon(points = [[0, 0, 0], [1, 0, 0], [1, inf, 0]], paths = undef, convexity = 1);
+ polyhedron(points = [[inf, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]], faces = [[0, 4, 2], [0, 2, 5], [0, 3, 4], [0, 5, 3], [1, 2, 4], [1, 5, 2], [1, 4, 3], [1, 3, 5]], convexity = 1);
+}
diff --git a/tests/regression/opencsgtest/primitive-inf-tests-expected.png b/tests/regression/opencsgtest/primitive-inf-tests-expected.png
new file mode 100644
index 0000000..50d838c
--- /dev/null
+++ b/tests/regression/opencsgtest/primitive-inf-tests-expected.png
Binary files differ
diff --git a/tests/regression/throwntogethertest/primitive-inf-tests-expected.png b/tests/regression/throwntogethertest/primitive-inf-tests-expected.png
new file mode 100644
index 0000000..50d838c
--- /dev/null
+++ b/tests/regression/throwntogethertest/primitive-inf-tests-expected.png
Binary files differ
contact: Jan Huwald // Impressum