diff options
author | Siyuan Zhou <visualzhou@gmail.com> | 2015-03-09 20:31:11 -0400 |
---|---|---|
committer | Ramon Fernandez <ramon.fernandez@mongodb.com> | 2015-03-13 11:57:25 -0400 |
commit | 4d4986d841968661f876a188d1fcca0b6134dda7 (patch) | |
tree | 6d861102d40c154fcf75880a91577a96d82865e6 | |
parent | 51155cf3524b8faa5736cb16a29e54ac19bf045c (diff) | |
download | mongo-4d4986d841968661f876a188d1fcca0b6134dda7.tar.gz |
SERVER-17486 Crash when parsing invalid polygon coordinates
(cherry picked from commit 7083b5d3abeb7717c9c3c28a006b8f5544922c44)
-rw-r--r-- | jstests/core/geo_validate.js | 6 | ||||
-rw-r--r-- | src/mongo/db/geo/geoparser.cpp | 24 |
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)) { |