Details
-
Bug
-
Resolution: Fixed
-
Minor
-
17.5.0
-
None
-
Unit
-
Unknown
-
N/A
-
N/A
-
Description
The REST keyword-search endpoints accept a repeatable "scope" query parameter that
selects what to search in (content, name, title, spaces, objects):
GET /rest/wikis/{wikiName}/search?q=hello&scope=content&scope=title
GET /rest/wikis/{wikiName}/spaces/{spaceName}/search?q=hello&scope=content
When a client repeats the same scope value (e.g. scope=content&scope=content, or
sends the same scope twice by mistake), the duplicate is meant to be dropped:
BaseSearchResult.parseSearchScopeStrings() has a guard whose whole purpose is to
skip a scope that was already added. That guard never fires.
Root cause: the guard compares the wrong types. searchScopes is a
List<KeywordSearchScope> but the value tested is the raw String scope name, so
"searchScopes.contains(searchScopeString)" is always false and no scope is ever
recognised as a duplicate.
What a user hits:
When duplicate scopes are passed, they are carried through unchanged instead of
being collapsed. Downstream, DatabaseKeywordSearchSource builds the HQL WHERE
clause by OR-ing one predicate per scope in the list, so a duplicated page scope
produces a redundant, repeated predicate, e.g.:
where ( upper(doc.content) like :keywords or upper(doc.content) like :keywords )
The database therefore executes a needlessly larger query for the same result set.
Result rows themselves are not duplicated in practice (the page query uses
"select distinct", and the spaces/objects scopes are guarded with contains()), so
this is a query-efficiency / broken-contract bug rather than a wrong-results bug.
Steps to reproduce:
1. On any XWiki instance, call:
GET /xwiki/rest/wikis/xwiki/search?q=test&scope=content&scope=content
2. Inspect the generated HQL (query logging, or DatabaseKeywordSearchSource).
Expected: the two identical "content" scopes are collapsed to a single predicate.
Actual: the content predicate appears twice, OR-ed together.