Prevent multiple updates to a single _local doc

If a user uploads a two _local docs with the same docid in a _bulk_docs
request the updater will insert multiple entries into the local docs
btree. This patch avoids that by throwing an error if a user attempts
it.

This is an old bug that I caught and just added a fix for. I split it
out as its own patch to point out that its a bug fix that differs from
the old behvior.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/c6ed2538
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/c6ed2538
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/c6ed2538

Branch: refs/heads/new-security-object
Commit: c6ed2538749697bbbedfbf7ff32afa8a0c940e94
Parents: b96bea4
Author: Paul Joseph Davis <dav...@apache.org>
Authored: Mon Jan 23 17:56:18 2012 -0600
Committer: Paul Joseph Davis <dav...@apache.org>
Committed: Wed Jan 25 01:25:06 2012 -0600

----------------------------------------------------------------------
 src/couchdb/couch_db.erl |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c6ed2538/src/couchdb/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl
index a6903c4..be65f53 100644
--- a/src/couchdb/couch_db.erl
+++ b/src/couchdb/couch_db.erl
@@ -727,6 +727,16 @@ update_docs(Db, Docs, Options, interactive_edit) ->
             end
         end, {[], []}, Docs2),
 
+    % Prevent updating multiple _local docs in a single update
+    % request. This relies on couch_db_updater not collecting
+    % more than one update that contains _local docs but this
+    % is still trigerable with a _bulk_docs request.
+    UniqNRIds = lists:usort([Id || #doc{id=Id} <- NonRepDocs0]),
+    case length(UniqNRIds) == length(NonRepDocs0) of
+        true -> ok;
+        false -> throw({update_error, repeated_local_docs})
+    end,
+
     {NonRepDocs, _} = new_revs(NonRepDocs0, [], []),
 
     DocBuckets = before_docs_update(Db, group_alike_docs(Docs3)),

Reply via email to