Skip to content

Commit c39c2ab

Browse files
committed
Raise error on insert into system collection.
Only if the collection is not system.users or system.indexes. [ RUBY-492 ]
1 parent ef88563 commit c39c2ab

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

lib/mongo/collection.rb

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ class Collection
2020
#
2121
# @param [String, Symbol] name the name of the collection.
2222
# @param [DB] db a MongoDB database instance.
23-
#
23+
#
2424
# @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
2525
# should be acknowledged
2626
# @option opts [Boolean] :j (false) Set journal acknowledgement
2727
# @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
2828
# @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
29-
#
29+
#
3030
# Notes about write concern:
31-
# These write concern options will be used for insert, update, and remove methods called on this
32-
# Collection instance. If no value is provided, the default values set on this instance's DB will be used.
31+
# These write concern options will be used for insert, update, and remove methods called on this
32+
# Collection instance. If no value is provided, the default values set on this instance's DB will be used.
3333
# These option values can be overridden for any invocation of insert, update, or remove.
3434
#
3535
# @option opts [:create_pk] :pk (BSON::ObjectId) A primary key factory to use
36-
# other than the default BSON::ObjectId.
36+
# other than the default BSON::ObjectId.
3737
# @option opts [:primary, :secondary] :read The default read preference for queries
3838
# initiates from this connection object. If +:secondary+ is chosen, reads will be sent
3939
# to one of the closest available secondary nodes. If a secondary node cannot be located, the
@@ -315,10 +315,10 @@ def find_one(spec_or_object_id=nil, opts={})
315315
# @return [ObjectId] the _id of the saved document.
316316
#
317317
# @option opts [Hash] :w, :j, :wtimeout, :fsync Set the write concern for this operation.
318-
# :w > 0 will run a +getlasterror+ command on the database to report any assertion.
318+
# :w > 0 will run a +getlasterror+ command on the database to report any assertion.
319319
# :j will confirm a write has been committed to the journal,
320320
# :wtimeout specifies how long to wait for write confirmation,
321-
# :fsync will confirm that a write has been fsynced.
321+
# :fsync will confirm that a write has been fsynced.
322322
# Options provided here will override any write concern options set on this collection,
323323
# its database object, or the current connection. See the options
324324
# for DB#get_last_error.
@@ -351,26 +351,29 @@ def save(doc, opts={})
351351
# @option opts [Boolean] :j (false) Set journal acknowledgement
352352
# @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
353353
# @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
354-
#
354+
#
355355
# Notes on write concern:
356356
# Options provided here will override any write concern options set on this collection,
357-
# its database object, or the current connection. See the options for +DB#get_last_error+.
357+
# its database object, or the current connection. See the options for +DB#get_last_error+.
358358
#
359359
# @option opts [Boolean] :continue_on_error (+false+) If true, then
360360
# continue a bulk insert even if one of the documents inserted
361361
# triggers a database assertion (as in a duplicate insert, for instance).
362362
# If not acknowledging writes, the list of ids returned will
363363
# include the object ids of all documents attempted on insert, even
364-
# if some are rejected on error. When acknowledging writes, any error will raise an
364+
# if some are rejected on error. When acknowledging writes, any error will raise an
365365
# OperationFailure exception.
366366
# MongoDB v2.0+.
367367
# @option opts [Boolean] :collect_on_error (+false+) if true, then
368368
# collects invalid documents as an array. Note that this option changes the result format.
369369
#
370-
# @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
370+
# @raise [Mongo::OperationFailure] will be raised iff :w > 0 and the operation fails.
371371
#
372372
# @core insert insert-instance_method
373373
def insert(doc_or_docs, opts={})
374+
if name.start_with?("system.") && name !~ /(\Asystem\.users)|(\Asystem\.indexes)/
375+
raise Mongo::InvalidNSName, "cannot insert into system collections."
376+
end
374377
doc_or_docs = [doc_or_docs] unless doc_or_docs.is_a?(Array)
375378
doc_or_docs.collect! { |doc| @pk_factory.create_pk(doc) }
376379
write_concern = get_write_concern(opts, self)
@@ -392,7 +395,7 @@ def insert(doc_or_docs, opts={})
392395
#
393396
# Notes on write concern:
394397
# Options provided here will override any write concern options set on this collection,
395-
# its database object, or the current connection. See the options for +DB#get_last_error+.
398+
# its database object, or the current connection. See the options for +DB#get_last_error+.
396399
#
397400
# @example remove all documents from the 'users' collection:
398401
# users.remove
@@ -446,7 +449,7 @@ def remove(selector={}, opts={})
446449
#
447450
# Notes on write concern:
448451
# Options provided here will override any write concern options set on this collection,
449-
# its database object, or the current connection. See the options for DB#get_last_error.
452+
# its database object, or the current connection. See the options for DB#get_last_error.
450453
#
451454
# @return [Hash, true] Returns a Hash containing the last error object if acknowledging writes.
452455
# Otherwise, returns true.
@@ -631,7 +634,7 @@ def find_and_modify(opts={})
631634
#
632635
# @param [Array] pipeline Should be a single array of pipeline operator hashes.
633636
#
634-
# '$project' Reshapes a document stream by including fields, excluding fields, inserting computed fields,
637+
# '$project' Reshapes a document stream by including fields, excluding fields, inserting computed fields,
635638
# renaming fields,or creating/populating fields that hold sub-documents.
636639
#
637640
# '$match' Query-like interface for filtering documents out of the aggregation pipeline.

test/functional/collection_test.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,19 @@ def test_ensure_index_timeout
10751075
coll.ensure_index([['a', 1]])
10761076
end
10771077

1078+
def test_insert_raises_exception_on_system_collection
1079+
collection = @@db["system.foo"]
1080+
assert_raise Mongo::InvalidNSName do
1081+
collection.insert({ :a => 1 })
1082+
end
1083+
end
1084+
1085+
def test_save_raises_exception_on_system_collection
1086+
collection = @@db["system.foo"]
1087+
assert_raise Mongo::InvalidNSName do
1088+
collection.save({ :a => 1 })
1089+
end
1090+
end
10781091

10791092
if @@version > '2.0.0'
10801093
def test_show_disk_loc

0 commit comments

Comments
 (0)