@@ -60,10 +60,13 @@ namespace mongo {
6060 , _s(this )
6161 , _tracker(0 )
6262 , _doneCalled(false ) {
63- // Reserve space for a holder object at the beginning of the buffer, followed by
63+ // Skip over space for a holder object at the beginning of the buffer, followed by
6464 // space for the object length. The length is filled in by _done.
6565 _b.skip (sizeof (BSONObj::Holder));
6666 _b.skip (sizeof (int ));
67+
68+ // Reserve space for the EOO byte. This means _done() can't fail.
69+ _b.reserveBytes (1 );
6770 }
6871
6972 /* * @param baseBuilder construct a BSONObjBuilder using an existing BufBuilder
@@ -76,9 +79,13 @@ namespace mongo {
7679 , _s(this )
7780 , _tracker(0 )
7881 , _doneCalled(false ) {
79- // Reserve space for the object length, which is filled in by _done. We don't need a holder
80- // since we are a sub-builder, and some parent builder has already made the reservation.
82+ // Skip over space for the object length, which is filled in by _done. We don't need a
83+ // holder since we are a sub-builder, and some parent builder has already made the
84+ // reservation.
8185 _b.skip (sizeof (int ));
86+
87+ // Reserve space for the EOO byte. This means _done() can't fail.
88+ _b.reserveBytes (1 );
8289 }
8390
8491 BSONObjBuilder ( const BSONSizeTracker & tracker )
@@ -91,6 +98,9 @@ namespace mongo {
9198 // See the comments in the first constructor for details.
9299 _b.skip (sizeof (BSONObj::Holder));
93100 _b.skip (sizeof (int ));
101+
102+ // Reserve space for the EOO byte. This means _done() can't fail.
103+ _b.reserveBytes (1 );
94104 }
95105
96106 ~BSONObjBuilder () {
@@ -626,6 +636,7 @@ namespace mongo {
626636 BSONObj asTempObj () {
627637 BSONObj temp (_done ());
628638 _b.setlen (_b.len ()-1 ); // next append should overwrite the EOO
639+ _b.reserveBytes (1 ); // Rereserve room for the real EOO
629640 _doneCalled = false ;
630641 return temp;
631642 }
@@ -707,8 +718,14 @@ namespace mongo {
707718 return _b.buf () + _offset;
708719
709720 _doneCalled = true ;
721+
722+ // TODO remove this or find some way to prevent it from failing. Since this is intended
723+ // for use with BSON() literal queries, it is less likely to result in oversized BSON.
710724 _s.endField ();
725+
726+ _b.claimReservedBytes (1 ); // Prevents adding EOO from failing.
711727 _b.appendNum ((char ) EOO);
728+
712729 char *data = _b.buf () + _offset;
713730 int size = _b.len () - _offset;
714731 DataView (data).writeLE (size);
0 commit comments