summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@apache.org>2019-09-05 14:50:58 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2019-09-05 15:11:36 -0400
commitd6b6155f2c0f016c276d7bb2f051b14bfe97201e (patch)
tree6f60f3ff604d17a3d13aba9258eae6ae688d8109
parent247bbef844445c4aca39662dbfcc19fcc915a015 (diff)
downloadcouchdb-d6b6155f2c0f016c276d7bb2f051b14bfe97201e.tar.gz
Add a max db name length config option
This is done for compatibility with CouchDB < 4.x where this limit was implicitly enforced by the file system's max filename size. The default value enforces the same limit for FDB in case users decide to replicate back and forth between old and new instances with 'create_target = true' option.
-rw-r--r--rel/overlay/etc/default.ini7
-rw-r--r--src/fabric/src/fabric2_db.erl20
-rw-r--r--test/elixir/test/basics_test.exs7
3 files changed, 34 insertions, 0 deletions
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index 9f892b64e..51d450bd7 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -37,6 +37,13 @@ default_security = admin_local
; influenced directly with this setting - increase for faster processing at the
; expense of more memory usage.
changes_doc_ids_optimization_threshold = 100
+;
+; Maximum database name length. The default setting is chosen for CouchDB < 4.x
+; compatibility, where it was determined by the maximum file name size. On most
+; current file systems that is 255, and with timestamp and ".couch" extension
+; subtracted it ends up as 238.
+;max_database_name_length = 238
+;
; Maximum document ID length. Can be set to an integer or 'infinity'.
;max_document_id_length = infinity
;
diff --git a/src/fabric/src/fabric2_db.erl b/src/fabric/src/fabric2_db.erl
index b2945b68c..f3036e4c3 100644
--- a/src/fabric/src/fabric2_db.erl
+++ b/src/fabric/src/fabric2_db.erl
@@ -131,6 +131,10 @@
-include("fabric2.hrl").
+% Default max database name length is based on CouchDb < 4.x compatibility. See
+% default.ini entry for additional information.
+-define(DEFAULT_MAX_DATABASE_NAME_LENGTH, 238).
+
-define(DBNAME_REGEX,
"^[a-z][a-z0-9\\_\\$()\\+\\-\\/]*" % use the stock CouchDB regex
"(\\.[0-9]{10,})?$" % but allow an optional shard timestamp at the end
@@ -866,6 +870,22 @@ validate_dbname(DbName) when is_binary(DbName) ->
DbName, Normalized, fun validate_dbname_int/2).
validate_dbname_int(DbName, Normalized) when is_binary(DbName) ->
+ case validate_dbname_length(DbName) of
+ ok -> validate_dbname_pat(DbName, Normalized);
+ {error, _} = Error -> Error
+ end.
+
+
+validate_dbname_length(DbName) ->
+ MaxLength = config:get_integer("couchdb", "max_database_name_length",
+ ?DEFAULT_MAX_DATABASE_NAME_LENGTH),
+ case byte_size(DbName) =< MaxLength of
+ true -> ok;
+ false -> {error, {database_name_too_long, DbName}}
+ end.
+
+
+validate_dbname_pat(DbName, Normalized) ->
DbNoExt = couch_util:drop_dot_couch_ext(DbName),
case re:run(DbNoExt, ?DBNAME_REGEX, [{capture,none}, dollar_endonly]) of
match ->
diff --git a/test/elixir/test/basics_test.exs b/test/elixir/test/basics_test.exs
index 736cdbbec..cde11aa5e 100644
--- a/test/elixir/test/basics_test.exs
+++ b/test/elixir/test/basics_test.exs
@@ -45,6 +45,13 @@ defmodule BasicsTest do
{:ok, _} = delete_db(db_name)
end
+ test "Exceeding configured DB name size limit returns an error" do
+ db_name = String.duplicate("x", 239)
+ resp = Couch.put("/#{db_name}")
+ assert resp.status_code == 400
+ assert resp.body["error"] == "database_name_too_long"
+ end
+
@tag :with_db
test "Created database has appropriate db info name", context do
db_name = context[:db_name]