File tree Expand file tree Collapse file tree 3 files changed +82
-2
lines changed Expand file tree Collapse file tree 3 files changed +82
-2
lines changed Original file line number Diff line number Diff line change @@ -809,8 +809,11 @@ function hasAtomicOperators(doc) {
809809 return doc . reduce ( ( err , u ) => err || hasAtomicOperators ( u ) , null ) ;
810810 }
811811
812- const keys = Object . keys ( doc ) ;
813- return keys . length > 0 && keys [ 0 ] [ 0 ] === '$' ;
812+ return (
813+ Object . keys ( typeof doc . toBSON !== 'function' ? doc : doc . toBSON ( ) )
814+ . map ( k => k [ 0 ] )
815+ . indexOf ( '$' ) >= 0
816+ ) ;
814817}
815818
816819module . exports = {
Original file line number Diff line number Diff line change @@ -1662,4 +1662,67 @@ describe('Bulk', function() {
16621662 ) ;
16631663 } ) ;
16641664 } ) ;
1665+
1666+ it ( 'should enforce no atomic operators' , function ( ) {
1667+ const client = this . configuration . newClient ( ) ;
1668+ return client
1669+ . connect ( )
1670+ . then ( ( ) => {
1671+ const collection = client . db ( ) . collection ( 'noAtomicOp' ) ;
1672+ return collection
1673+ . drop ( )
1674+ . catch ( ignoreNsNotFound )
1675+ . then ( ( ) => collection ) ;
1676+ } )
1677+ . then ( collection => {
1678+ return collection . insertMany ( [ { a : 1 } , { a : 1 } , { a : 1 } ] ) . then ( ( ) => collection ) ;
1679+ } )
1680+ . then ( collection => {
1681+ try {
1682+ return collection . replaceOne ( { a : 1 } , { $atomic : 1 } ) ;
1683+ } catch ( err ) {
1684+ expect ( err ) . to . be . instanceOf (
1685+ TypeError ,
1686+ 'Replacement document must not use atomic operators'
1687+ ) ;
1688+ }
1689+ } )
1690+ . finally ( ( ) => {
1691+ return client . close ( ) ;
1692+ } ) ;
1693+ } ) ;
1694+
1695+ it ( 'should respect toBSON conversion when checking for atomic operators' , function ( ) {
1696+ const client = this . configuration . newClient ( ) ;
1697+ return client
1698+ . connect ( )
1699+ . then ( ( ) => {
1700+ const collection = client . db ( ) . collection ( 'noAtomicOp' ) ;
1701+ return collection
1702+ . drop ( )
1703+ . catch ( ignoreNsNotFound )
1704+ . then ( ( ) => collection ) ;
1705+ } )
1706+ . then ( collection => {
1707+ return collection . insertMany ( [ { a : 1 } , { a : 1 } , { a : 1 } ] ) . then ( ( ) => collection ) ;
1708+ } )
1709+ . then ( collection => {
1710+ try {
1711+ return collection . replaceOne (
1712+ { a : 1 } ,
1713+ {
1714+ $atomic : 1 ,
1715+ toBSON ( ) {
1716+ return { atomic : this . $atomic } ;
1717+ }
1718+ }
1719+ ) ;
1720+ } catch ( err ) {
1721+ expect . fail ( ) ; // shouldn't throw any error
1722+ }
1723+ } )
1724+ . finally ( ( ) => {
1725+ return client . close ( ) ;
1726+ } ) ;
1727+ } ) ;
16651728} ) ;
Original file line number Diff line number Diff line change 22const eachAsync = require ( '../../lib/core/utils' ) . eachAsync ;
33const makeInterruptableAsyncInterval = require ( '../../lib/utils' ) . makeInterruptableAsyncInterval ;
44const now = require ( '../../lib/utils' ) . now ;
5+ const hasAtomicOperators = require ( '../../lib/utils' ) . hasAtomicOperators ;
56const expect = require ( 'chai' ) . expect ;
67const sinon = require ( 'sinon' ) ;
78
@@ -163,4 +164,17 @@ describe('utils', function() {
163164 this . clock . tick ( 250 ) ;
164165 } ) ;
165166 } ) ;
167+
168+ it ( 'should assert hasAtomicOperators and respect toBSON conversion' , function ( ) {
169+ expect ( hasAtomicOperators ( { $key : 2.3 } ) ) . to . be . true ;
170+ expect ( hasAtomicOperators ( { nonAtomic : 1 , $key : 2.3 } ) ) . to . be . true ;
171+ expect (
172+ hasAtomicOperators ( {
173+ $key : 2.3 ,
174+ toBSON ( ) {
175+ return { key : this . $key } ;
176+ }
177+ } )
178+ ) . to . be . false ;
179+ } ) ;
166180} ) ;
You can’t perform that action at this time.
0 commit comments