From 6ebf1fbed08ab5df5ddbaffd96828e118416137b Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Fri, 14 Sep 2018 11:38:48 -0400 Subject: [PATCH 1/7] Fix mangrove crash Crash observed when document length is 257 byte, for example. It represents as '0x01 01 00 00'. In this case '_bytes_read == _len' equal to 1 and callback is called with partial buffer (only 1 byte actually). This cause later crash in 'to_dotted_notation_document' Signed-off-by: Abylay Ospan --- src/boson/bson_streambuf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boson/bson_streambuf.cpp b/src/boson/bson_streambuf.cpp index ce18da7..afad1da 100644 --- a/src/boson/bson_streambuf.cpp +++ b/src/boson/bson_streambuf.cpp @@ -67,7 +67,7 @@ int bson_output_streambuf::insert(int ch) { } // This creates the document from the given bytes, and calls the user-provided callback. - if (_bytes_read == _len) { + if (_bytes_read == _len && _len > 4) { _cb({std::move(_data), _len}); _bytes_read = 0; _len = 0; From 4f0c9e9d60e24e9774d21fb9e2cb5df92835d09e Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Thu, 13 Dec 2018 10:14:21 -0500 Subject: [PATCH 2/7] Fix embedded doc exception with new mongo-cxx With mongo-cxx-3.2+ we have exception: terminate called after throwing an instance of 'bsoncxx::v_noabi::exception' what(): can't convert builder to a valid view: unmatched key while using embedded documents. For example: { "name" : "Jenny", "contact_info" : { "type" : "home" } } we have called twice: 1. for "contact_info" key 2. for "contact_info.type" key in mongo-cxx-3.2+ we can't call key_view/key_owned twice. Otherwise we receive exception as described above. Signed-off-by: Abylay Ospan --- src/boson/bson_archiver.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/boson/bson_archiver.hpp b/src/boson/bson_archiver.hpp index e590cb4..294f149 100644 --- a/src/boson/bson_archiver.hpp +++ b/src/boson/bson_archiver.hpp @@ -383,9 +383,15 @@ class BSONOutputArchive : public cereal::OutputArchive { if (topType == OutputNodeType::InArray) return; } - if (!_nextName && _nodeTypeStack.empty() && isNewNode) { - // This is a document at the root node with no name. - // Do nothing since no name is expected for non root-element documents in root. + if ((!_nextName && _nodeTypeStack.empty() && isNewNode) || + (_nextName && isNewNode)) { + // This is a document: + // * at the root node with no name. + // Do nothing since no name is expected for non root-element documents in root. + // * embedded document + // Do nothing since no value expected for this key. + // Example: + // embedded document "user.profile" but key with value is "user.profile.email" return; } else if (!_nextName) { // Enforce the existence of a name-value pair if this is not a node in root, From 82354ec9afae02ab6d1dea8ab191e56d53eaeffa Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Thu, 13 Dec 2018 20:38:25 -0500 Subject: [PATCH 3/7] Revert "Fix embedded doc exception with new mongo-cxx" Incorrect fix revert. This reverts commit 4f0c9e9d60e24e9774d21fb9e2cb5df92835d09e. --- src/boson/bson_archiver.hpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/boson/bson_archiver.hpp b/src/boson/bson_archiver.hpp index 294f149..e590cb4 100644 --- a/src/boson/bson_archiver.hpp +++ b/src/boson/bson_archiver.hpp @@ -383,15 +383,9 @@ class BSONOutputArchive : public cereal::OutputArchive { if (topType == OutputNodeType::InArray) return; } - if ((!_nextName && _nodeTypeStack.empty() && isNewNode) || - (_nextName && isNewNode)) { - // This is a document: - // * at the root node with no name. - // Do nothing since no name is expected for non root-element documents in root. - // * embedded document - // Do nothing since no value expected for this key. - // Example: - // embedded document "user.profile" but key with value is "user.profile.email" + if (!_nextName && _nodeTypeStack.empty() && isNewNode) { + // This is a document at the root node with no name. + // Do nothing since no name is expected for non root-element documents in root. return; } else if (!_nextName) { // Enforce the existence of a name-value pair if this is not a node in root, From 789d68322c162f1f01940fcc55b57d7d575328db Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Thu, 13 Dec 2018 20:26:53 -0500 Subject: [PATCH 4/7] Fix embedded doc exception with new mongo-cxx With modern mongo-cxx (tested on 3.3.1) we have exception while using embedded documents: terminate called after throwing an instance of 'bsoncxx::v_noabi::exception' what(): can't convert builder to a valid view: unmatched key For example: { "name" : "Jenny", "contact_info" : { "type" : "home" } } we have called twice: 1. for "contact_info" key 2. for "contact_info.type" key we can't call key_view/key_owned twice. Otherwise we receive exception as described above. Signed-off-by: Abylay Ospan --- src/boson/bson_archiver.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/boson/bson_archiver.hpp b/src/boson/bson_archiver.hpp index e590cb4..b1f1486 100644 --- a/src/boson/bson_archiver.hpp +++ b/src/boson/bson_archiver.hpp @@ -387,6 +387,13 @@ class BSONOutputArchive : public cereal::OutputArchive { // This is a document at the root node with no name. // Do nothing since no name is expected for non root-element documents in root. return; + } else if (_nextName && isNewNode) { + // Do nothing since no value expected for this key. + // Save key name in _embeddedNameStack for next rounds + // Example: + // embedded document "user.profile" but key with value is "user.profile.email" + _embeddedNameStack.push_back(_nextName); + return; } else if (!_nextName) { // Enforce the existence of a name-value pair if this is not a node in root, // or this in an element in root. From a93b58528a3b6567a789a736506855731190472f Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Fri, 14 Dec 2018 14:41:37 -0500 Subject: [PATCH 5/7] Revert "Fix embedded doc exception with new mongo-cxx" This reverts commit 789d68322c162f1f01940fcc55b57d7d575328db. --- src/boson/bson_archiver.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/boson/bson_archiver.hpp b/src/boson/bson_archiver.hpp index b1f1486..e590cb4 100644 --- a/src/boson/bson_archiver.hpp +++ b/src/boson/bson_archiver.hpp @@ -387,13 +387,6 @@ class BSONOutputArchive : public cereal::OutputArchive { // This is a document at the root node with no name. // Do nothing since no name is expected for non root-element documents in root. return; - } else if (_nextName && isNewNode) { - // Do nothing since no value expected for this key. - // Save key name in _embeddedNameStack for next rounds - // Example: - // embedded document "user.profile" but key with value is "user.profile.email" - _embeddedNameStack.push_back(_nextName); - return; } else if (!_nextName) { // Enforce the existence of a name-value pair if this is not a node in root, // or this in an element in root. From ed32cbfc79eca8823887c7d13baf994b4856cea3 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Fri, 14 Dec 2018 14:42:31 -0500 Subject: [PATCH 6/7] Fix embedded doc exception with new mongo-cxx With modern mongo-cxx (tested on 3.3.1) we have exception while using embedded documents: terminate called after throwing an instance of 'bsoncxx::v_noabi::exception' what(): can't convert builder to a valid view: unmatched key For example: { "name" : "Jenny", "contact_info" : { "type" : "home" } } we have called twice: 1. for "contact_info" key 2. for "contact_info.type" key we can't call key_view/key_owned twice. Otherwise we receive exception as described above. Signed-off-by: Abylay Ospan --- src/boson/bson_archiver.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/boson/bson_archiver.hpp b/src/boson/bson_archiver.hpp index e590cb4..e036eea 100644 --- a/src/boson/bson_archiver.hpp +++ b/src/boson/bson_archiver.hpp @@ -394,7 +394,8 @@ class BSONOutputArchive : public cereal::OutputArchive { } else { // Set the key of this element to the name stored by the archiver. if (!_dotNotationMode || _embeddedNameStack.empty() || _arrayNestingLevel > 0) { - _bsonBuilder.key_view(_nextName); + if (!isNewNode) + _bsonBuilder.key_view(_nextName); } else { // If we are in dot notation mode and we're not nested in array, build the name of // this key. From 6522306681b8542978bfa702bc493eb450adfe13 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Wed, 19 Dec 2018 13:14:36 -0500 Subject: [PATCH 7/7] fix exception while 'insert_many' Save 'key' if we do not in dot notation mode Signed-off-by: Abylay Ospan --- src/boson/bson_archiver.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boson/bson_archiver.hpp b/src/boson/bson_archiver.hpp index e036eea..8f50a0d 100644 --- a/src/boson/bson_archiver.hpp +++ b/src/boson/bson_archiver.hpp @@ -394,7 +394,7 @@ class BSONOutputArchive : public cereal::OutputArchive { } else { // Set the key of this element to the name stored by the archiver. if (!_dotNotationMode || _embeddedNameStack.empty() || _arrayNestingLevel > 0) { - if (!isNewNode) + if (!isNewNode || !_dotNotationMode) _bsonBuilder.key_view(_nextName); } else { // If we are in dot notation mode and we're not nested in array, build the name of