From 449edf0de03143dbf41e5235d36726d2ed10c0a9 Mon Sep 17 00:00:00 2001 From: Gabor Pali Date: Thu, 5 Oct 2023 16:54:39 +0200 Subject: [PATCH] mango: fix validation of `use_index` The `binary:split/2` function will split the input only at the first occurrence of the pattern which is not suitable for identifying each part of the index name, therefore validating it. Add the `global` option to fully break the index name into parts and let the related validation logic work as expected. --- src/mango/src/mango_error.erl | 6 ++++++ src/mango/src/mango_opts.erl | 2 +- src/mango/test/05-index-selection-test.py | 10 ++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mango/src/mango_error.erl b/src/mango/src/mango_error.erl index 989e9fa1245..830b36dd1fa 100644 --- a/src/mango/src/mango_error.erl +++ b/src/mango/src/mango_error.erl @@ -253,6 +253,12 @@ info(mango_opts, {invalid_bulk_docs, Val}) -> [Val] ) }; +info(mango_opts, {invalid_index_name, Val}) -> + { + 400, + <<"invalid_index_name">>, + fmt("Invalid index name: ~w", [Val]) + }; info(mango_opts, {invalid_ejson, Val}) -> { 400, diff --git a/src/mango/src/mango_opts.erl b/src/mango/src/mango_opts.erl index 1d3ded1701f..c846bce14b0 100644 --- a/src/mango/src/mango_opts.erl +++ b/src/mango/src/mango_opts.erl @@ -262,7 +262,7 @@ validate_bulk_docs(Else) -> ?MANGO_ERROR({invalid_bulk_docs, Else}). validate_use_index(IndexName) when is_binary(IndexName) -> - case binary:split(IndexName, <<"/">>) of + case binary:split(IndexName, <<"/">>, [global]) of [DesignId] -> {ok, [DesignId]}; [<<"_design">>, DesignId] -> diff --git a/src/mango/test/05-index-selection-test.py b/src/mango/test/05-index-selection-test.py index c4f245bdb27..0cbbd0b8013 100644 --- a/src/mango/test/05-index-selection-test.py +++ b/src/mango/test/05-index-selection-test.py @@ -211,6 +211,16 @@ def test_explain_sort_reverse(self): ) self.assertEqual(resp_explain["index"]["type"], "json") + def test_use_index_with_invalid_name(self): + for index in ["foo/bar/baz", ["foo", "bar", "baz"]]: + with self.subTest(index=index): + try: + self.db.find({"manager": True}, use_index=index) + except Exception as e: + self.assertEqual(e.response.status_code, 400) + else: + raise AssertionError("did not fail on invalid index name") + def test_use_index_without_fallback(self): with self.subTest(use_index="valid"): docs = self.db.find(