[SERVER-13440] ensureIndex should validate its arguments more carefully. Created: 01/Apr/14  Updated: 10/May/22

Status: Backlog
Project: Core Server
Component/s: Shell
Affects Version/s: 2.4.9, 2.6.0-rc2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: rohit.nijhawan@10gen.com Assignee: DO NOT USE - Backlog - Platform Team
Resolution: Unresolved Votes: 1
Labels: move-sa, neweng
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
Operating System: ALL
Steps To Reproduce:

db.test.insert({lname:'David', age:80})
db.test.insert({lname:'David', age:80})
db.test.insert({lname:'David', age:80})
 
db.test.ensureIndex({lname:1,age:1},[unique=true,sparse=true])
 
db.test.count()

Participants:
Case:

 Description   

Basically, there is parsing of the options in the ensureIndex commands but some edge cases need to be ironed out.

dropDups get invoked if ensureIndex options are in array syntax [x=true,y=true]

For example if one inserts

db.test.insert({lname:'David', age:80})
db.test.insert({lname:'David', age:80})
db.test.insert({lname:'David', age:80})

and then issues the command

db.test.ensureIndex({lname:1,age:1},[unique=true,sparse=true])

This will drop all of their duplicate data as entered above.

Further, given the parsing of the options as "object" it doesn't matter what 'key' is passed.

db.test.ensureIndex({lname:1,age:1},[x=true,y=true])

will yield the same results

However

db.test.ensureIndex({lname:1,age:1},[x=false,y=true]) 

shall yield a more peculiar result - the dropDups will be stored system.indexes but unique won't be enforced.

There may be other ways to pass in these options that can be dangerous in similar ways.



 Comments   
Comment by Steven Vannelli [ 10/May/22 ]

Moving this ticket to the Backlog and removing the "Backlog" fixVersion as per our latest policy for using fixVersions.

Comment by Asya Kamsky [ 25/Aug/20 ]

Note that in SERVER-50442 the query team approved removing ensureIndex method from the shell as it was deprecated in version 3.0.0.

 

Comment by Max Hirschhorn [ 05/Feb/16 ]

It's worth noting that in JavaScript, [unique = true, sparse = true] defines global variables unique and sparse and evaluates to the array [true, true]. When var isn't used to declare a variable, the AssignmentExpression returns the value on the RHS. Doing so is potentially useful to chain assignments, e.g. x = y = 1.

Further, given the parsing of the options as "object" it doesn't matter what 'key' is passed.

The "keys" (really variable identifiers) used within the array have nothing to do with the definition of the DBCollection.prototype.ensureIndex() function and everything to do with how JavaScript works.

Moreover, this isn't really a bug in the sense that the mongo shell intentionally accepts options to DBCollection.prototype.ensureIndex() as an array. When options is specified as an array (of up to 3 elements), the first boolean value in the array is used as the unique option for the index, and the second boolean value in the array is used as the dropDups option for the index.

Accepting an array value has been the behavior of DBCollection.prototype.ensureIndex() for a really long time. However, given that the object form {unique: true, dropDups: true} is also supported and self-describing about the meaning of the options, we should consider breaking the mongo shell's API and throwing an error if an options array is passed to DBCollection.prototype._indexSpec().

Generated at Thu Feb 08 03:31:44 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.