summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2014-04-04 10:17:44 -0400
committerMatt Kangas <matt.kangas@mongodb.com>2014-04-09 18:54:21 -0400
commitac55e3f5a963f8ed2b0516703f8305e8091595f0 (patch)
treea4c5126fef827ab25c7bf9bfe75537bb32790655
parentd2030ec6797f4d4238e03690eef8334c1f582ce2 (diff)
downloadmongo-ac55e3f5a963f8ed2b0516703f8305e8091595f0.tar.gz
SERVER-13486 check obj size when building return of geonear cmd
(cherry picked from commit b4a2cc96b18cacdfece81215d9d8c7a3a84ba20a)
-rw-r--r--src/mongo/db/commands/geonear.cpp31
1 files changed, 20 insertions, 11 deletions
diff --git a/src/mongo/db/commands/geonear.cpp b/src/mongo/db/commands/geonear.cpp
index 56d062fbdbe..a1166ddd1dd 100644
--- a/src/mongo/db/commands/geonear.cpp
+++ b/src/mongo/db/commands/geonear.cpp
@@ -190,21 +190,14 @@ namespace mongo {
BSONObj currObj;
int results = 0;
while ((results < numWanted) && Runner::RUNNER_ADVANCED == runner->getNext(&currObj, NULL)) {
- // cout << "result is " << currObj.toString() << endl;
+ // Come up with the correct distance.
double dist = currObj["$dis"].number() * distanceMultiplier;
- // cout << std::setprecision(10) << "HK GEON mul'd dist is " << dist << " raw dist is " << currObj["$dis"].number() << endl;
totalDistance += dist;
if (dist > farthestDist) { farthestDist = dist; }
- BSONObjBuilder oneResultBuilder(
- resultBuilder.subobjStart(BSONObjBuilder::numStr(results)));
- oneResultBuilder.append("dis", dist);
- if (includeLocs) {
- oneResultBuilder.appendAs(currObj["$pt"], "loc");
- }
-
- // strip out '$dis' and '$pt' and the rest gets added as 'obj'.
+ // Strip out '$dis' and '$pt' from the result obj. The rest gets added as 'obj'
+ // in the command result.
BSONObjIterator resIt(currObj);
BSONObjBuilder resBob;
while (resIt.more()) {
@@ -214,7 +207,23 @@ namespace mongo {
resBob.append(elt);
}
}
- oneResultBuilder.append("obj", resBob.obj());
+ BSONObj resObj = resBob.obj();
+
+ // Don't make a too-big result object.
+ if (resultBuilder.len() + resObj.objsize()> BSONObjMaxUserSize) {
+ warning() << "Too many geoNear results for query " << rewritten.toString()
+ << ", truncating output.";
+ break;
+ }
+
+ // Add the next result to the result builder.
+ BSONObjBuilder oneResultBuilder(
+ resultBuilder.subobjStart(BSONObjBuilder::numStr(results)));
+ oneResultBuilder.append("dis", dist);
+ if (includeLocs) {
+ oneResultBuilder.appendAs(currObj["$pt"], "loc");
+ }
+ oneResultBuilder.append("obj", resObj);
oneResultBuilder.done();
++results;
}