diff options
-rw-r--r-- | share/www/script/test/invalid_docids.js | 13 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_db.erl | 15 |
2 files changed, 28 insertions, 0 deletions
diff --git a/share/www/script/test/invalid_docids.js b/share/www/script/test/invalid_docids.js index a3c9a6e1..86c3fd38 100644 --- a/share/www/script/test/invalid_docids.js +++ b/share/www/script/test/invalid_docids.js @@ -20,6 +20,19 @@ couchTests.invalid_docids = function(debug) { T(db.save({"_id": "_local/foo"}).ok); T(db.open("_local/foo")._id == "_local/foo"); + var urls = [ + "/test_suite_db/_local", + "/test_suite_db/_local/", + "/test_suite_db/_local%2F", + "/test_suite_db/_local/foo/bar", + ]; + + urls.forEach(function(u) { + var res = db.request("PUT", u, {"body": "{}"}); + T(res.status == 400); + T(JSON.parse(res.responseText).error == "bad_request"); + }); + //Test non-string try { db.save({"_id": 1}); diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl index 084dd946..55429cef 100644 --- a/src/couchdb/couch_httpd_db.erl +++ b/src/couchdb/couch_httpd_db.erl @@ -506,6 +506,21 @@ db_req(#httpd{path_parts=[_DbName,<<"_design">>,Name|FileNameParts]}=Req, Db) -> db_attachment_req(Req, Db, <<"_design/",Name/binary>>, FileNameParts); +% Special case to allow for accessing local documents without %2F +% encoding the docid. Throws out requests that don't have the second +% path part or that specify an attachment name. +db_req(#httpd{path_parts=[_DbName, <<"_local">>]}, _Db) -> + throw({bad_request, <<"Invalid _local document id.">>}); + +db_req(#httpd{path_parts=[_DbName, <<"_local/">>]}, _Db) -> + throw({bad_request, <<"Invalid _local document id.">>}); + +db_req(#httpd{path_parts=[_DbName, <<"_local">>, Name]}=Req, Db) -> + db_doc_req(Req, Db, <<"_local/", Name/binary>>); + +db_req(#httpd{path_parts=[_DbName, <<"_local">> | _Rest]}, _Db) -> + throw({bad_request, <<"_local documents do not accept attachments.">>}); + db_req(#httpd{path_parts=[_, DocId]}=Req, Db) -> db_doc_req(Req, Db, DocId); |