summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiyuan Zhou <visualzhou@gmail.com>2015-03-09 20:31:11 -0400
committerRamon Fernandez <ramon.fernandez@mongodb.com>2015-03-13 11:57:25 -0400
commit4d4986d841968661f876a188d1fcca0b6134dda7 (patch)
tree6d861102d40c154fcf75880a91577a96d82865e6
parent51155cf3524b8faa5736cb16a29e54ac19bf045c (diff)
downloadmongo-4d4986d841968661f876a188d1fcca0b6134dda7.tar.gz
SERVER-17486 Crash when parsing invalid polygon coordinates
(cherry picked from commit 7083b5d3abeb7717c9c3c28a006b8f5544922c44)
-rw-r--r--jstests/core/geo_validate.js6
-rw-r--r--src/mongo/db/geo/geoparser.cpp24
2 files changed, 27 insertions, 3 deletions
diff --git a/jstests/core/geo_validate.js b/jstests/core/geo_validate.js
index 2d3782e233a..5b9957166c3 100644
--- a/jstests/core/geo_validate.js
+++ b/jstests/core/geo_validate.js
@@ -91,3 +91,9 @@ assert.commandWorked(db.runCommand({geoNear: coll.getName(),
//
// SERVER-17241 Polygon has no loop
assert.writeError(coll.insert({ geo : { type: 'Polygon', coordinates: [] } }));
+
+//
+// SERVER-17486 Loop has less then 3 vertices.
+assert.writeError(coll.insert({geo: {type: 'Polygon', coordinates: [[]]}}));
+assert.writeError(coll.insert({geo: {type: 'Polygon', coordinates: [[[0,0]]]}}));
+assert.writeError(coll.insert({geo: {type: 'Polygon', coordinates: [[[0,0], [0,0], [0,0], [0,0]]]}}));
diff --git a/src/mongo/db/geo/geoparser.cpp b/src/mongo/db/geo/geoparser.cpp
index db03fe66c12..8b8c3aebb63 100644
--- a/src/mongo/db/geo/geoparser.cpp
+++ b/src/mongo/db/geo/geoparser.cpp
@@ -144,9 +144,15 @@ namespace mongo {
}
static Status isLoopClosed(const vector<S2Point>& loop, const BSONElement loopElt) {
- if (loop.empty() || loop[0] != loop[loop.size() - 1])
- return BAD_VALUE("Loop is not closed: " << loopElt.toString(false));
- return Status::OK();
+ if (loop.empty()) {
+ return BAD_VALUE("Loop has no vertices: " << loopElt.toString(false));
+ }
+
+ if (loop[0] != loop[loop.size() - 1]) {
+ return BAD_VALUE("Loop is not closed: " << loopElt.toString(false));
+ }
+
+ return Status::OK();
}
static Status parseGeoJSONPolygonCoordinates(const BSONElement& elem, S2Polygon *out) {
@@ -173,6 +179,12 @@ namespace mongo {
// Drop the duplicated last point.
points.resize(points.size() - 1);
+ // At least 3 vertices.
+ if (points.size() < 3) {
+ return BAD_VALUE("Loop must have at least 3 different vertices: " <<
+ coordinateElt.toString(false));
+ }
+
S2Loop* loop = new S2Loop(points);
loops.push_back(loop);
@@ -269,6 +281,12 @@ namespace mongo {
// duplicate points
exteriorVertices.resize(exteriorVertices.size() - 1);
+ // At least 3 vertices.
+ if (exteriorVertices.size() < 3) {
+ return BAD_VALUE("Loop must have at least 3 different vertices: " <<
+ elem.toString(false));
+ }
+
auto_ptr<S2Loop> loop(new S2Loop(exteriorVertices));
// Check whether this loop is valid.
if (!loop->IsValid(&err)) {