Skip to content

Commit

Permalink
SERVER-26462 Check if _buffer is allocated in DocumentStorage::clone()
Browse files Browse the repository at this point in the history
  • Loading branch information
m-vojvodic committed Nov 4, 2016
1 parent a7f147a commit c1567ab
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
29 changes: 29 additions & 0 deletions jstests/aggregation/bugs/server26462.js
@@ -0,0 +1,29 @@
// Tests that adding a field that only contains metadata does not cause a segmentation fault when
// grouping on the added field.
(function() {
"use strict";

// Drop the old test collection, if any.
db.server26462.drop();

// Insert some test documents into the collection.
assert.writeOK(db.server26462.insert({"_id": 1, "title": "cakes and ale"}));
assert.writeOK(db.server26462.insert({"_id": 2, "title": "more cakes"}));
assert.writeOK(db.server26462.insert({"_id": 3, "title": "bread"}));
assert.writeOK(db.server26462.insert({"_id": 4, "title": "some cakes"}));

// Create a text index on the documents.
assert.commandWorked(db.server26462.createIndex({title: "text"}));

// Add a metadata only field in the aggregation pipeline and use that field in the $group _id.
let res = db.server26462
.aggregate([
{$match: {$text: {$search: "cake"}}},
{$addFields: {fooScore: {$meta: "textScore"}}},
{$group: {_id: "$fooScore", count: {$sum: 1}}}
])
.itcount();

// Assert that the command worked.
assert.eq(2, res);
})();
6 changes: 4 additions & 2 deletions src/mongo/db/pipeline/document.cpp
Expand Up @@ -186,10 +186,12 @@ intrusive_ptr<DocumentStorage> DocumentStorage::clone() const {

// Make a copy of the buffer.
// It is very important that the positions of each field are the same after cloning.
const size_t bufferBytes = (_bufferEnd + hashTabBytes()) - _buffer;
const size_t bufferBytes = allocatedBytes();
out->_buffer = new char[bufferBytes];
out->_bufferEnd = out->_buffer + (_bufferEnd - _buffer);
memcpy(out->_buffer, _buffer, bufferBytes);
if (bufferBytes > 0) {
memcpy(out->_buffer, _buffer, bufferBytes);
}

// Copy remaining fields
out->_usedBytes = _usedBytes;
Expand Down
8 changes: 8 additions & 0 deletions src/mongo/db/pipeline/document_value_test.cpp
Expand Up @@ -104,6 +104,14 @@ TEST(DocumentConstruction, FromInitializerList) {
ASSERT_EQUALS("q", getNthField(document, 1).second.getString());
}

TEST(DocumentConstruction, FromEmptyDocumentClone) {
Document document;
ASSERT_EQUALS(0U, document.size());
// Prior to SERVER-26462, cloning an empty document would cause a segmentation fault.
Document documentClone = document.clone();
ASSERT_DOCUMENT_EQ(document, documentClone);
}

/** Add Document fields. */
class AddField {
public:
Expand Down

0 comments on commit c1567ab

Please sign in to comment.