From 9980a0bfcb36b485c540a0fa372081eb610aa17d Mon Sep 17 00:00:00 2001 From: Charles Galambos Date: Tue, 19 May 2015 11:51:48 +0100 Subject: [PATCH] CXX-603 Fix for dropping parts of blocks appended to a gridfs file with appendChunk and add unit test for gridfs GridFileBuilder to check it handles block boundries correctly Signed-off-by: Andrew Morrow --- src/mongo/client/gridfs.cpp | 9 +++++- .../integration/standalone/gridfs_test.cpp | 32 ++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/mongo/client/gridfs.cpp b/src/mongo/client/gridfs.cpp index fd53fcb209..d57d73cbfa 100644 --- a/src/mongo/client/gridfs.cpp +++ b/src/mongo/client/gridfs.cpp @@ -321,7 +321,14 @@ namespace mongo { invariant( _pendingDataSize <= _chunkSize ); if (_pendingDataSize == _chunkSize) { _appendPendingData(); - _appendChunk( data + size, length - size, false ); + const char* const end = data + length; + data = _appendChunk( data + size, length - size, false ); + if (data != end) { + invariant(data < end); + size_t nsize = static_cast(end - data); + memcpy( _pendingData.get() + _pendingDataSize, data, nsize ); + _pendingDataSize += nsize; + } } } else { diff --git a/src/mongo/integration/standalone/gridfs_test.cpp b/src/mongo/integration/standalone/gridfs_test.cpp index b4f7c3bbdc..15a1b15067 100644 --- a/src/mongo/integration/standalone/gridfs_test.cpp +++ b/src/mongo/integration/standalone/gridfs_test.cpp @@ -226,21 +226,45 @@ namespace { TEST_F(GridFSTest, GridFileBuilder) { GridFileBuilder gfb(_gfs.get()); - for (int i=0; ifindFileByName(DATA_NAME); ASSERT_EQUALS(gf.getNumChunks(), 1); + ASSERT_EQUALS(gf.getContentLength(), totalSize); } TEST_F(GridFSTest, GridFileBuilderMultipleChunks) { _gfs->setChunkSize(1); GridFileBuilder gfb(_gfs.get()); - for (int i=0; ifindFileByName(DATA_NAME); ASSERT_EQUALS(gf.getNumChunks(), DATA_LEN); + ASSERT_EQUALS(gf.getContentLength(), total_size); + } + + TEST_F(GridFSTest, GridFileBuilderAcrossChunkBoundry) { + _gfs->setChunkSize(11); + GridFileBuilder gfb(_gfs.get()); + size_t total_size = 0; + for (int i=0; ifindFileByName(DATA_NAME); + ASSERT_EQUALS(gf.getContentLength(), total_size); } } // namespace