escape path prefix when doing cache jail search

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2022-11-02 12:44:51 +01:00 committed by backportbot-nextcloud[bot]
parent 151f7195c0
commit 0bd5bcdaeb
3 changed files with 8 additions and 7 deletions

View file

@ -317,7 +317,7 @@ class CacheJail extends CacheWrapper {
new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR,
[
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'path', $this->getGetUnjailedRoot()),
new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', $this->getGetUnjailedRoot() . '/%'),
new SearchComparison(ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE, 'path', SearchComparison::escapeLikeParameter($this->getGetUnjailedRoot()) . '/%'),
],
)
]

View file

@ -23,15 +23,12 @@ declare(strict_types=1);
namespace OC\Files\Search\QueryOptimizer;
use OC\Files\Search\SearchComparison;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
class PathPrefixOptimizer extends QueryOptimizerStep {
public function escapeLikeParameter(string $param): string {
return addcslashes($param, '\\_%');
}
public function processOperator(ISearchOperator &$operator) {
// normally the `path = "$prefix"` search query part of the prefix filter would be generated as an `path_hash = md5($prefix)` sql query
// since the `path_hash` sql column usually provides much faster querying that selecting on the `path` sql column
@ -43,11 +40,11 @@ class PathPrefixOptimizer extends QueryOptimizerStep {
$b = $operator->getArguments()[1];
if ($a instanceof ISearchComparison && $b instanceof ISearchComparison && $a->getField() === 'path' && $b->getField() === 'path') {
if ($a->getType() === ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE && $b->getType() === ISearchComparison::COMPARE_EQUAL
&& $a->getValue() === $this->escapeLikeParameter($b->getValue()) . '/%') {
&& $a->getValue() === SearchComparison::escapeLikeParameter($b->getValue()) . '/%') {
$b->setQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, false);
}
if ($b->getType() === ISearchComparison::COMPARE_LIKE_CASE_SENSITIVE && $a->getType() === ISearchComparison::COMPARE_EQUAL
&& $b->getValue() === $this->escapeLikeParameter($a->getValue()) . '/%') {
&& $b->getValue() === SearchComparison::escapeLikeParameter($a->getValue()) . '/%') {
$a->setQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, false);
}
}

View file

@ -74,4 +74,8 @@ class SearchComparison implements ISearchComparison {
public function setQueryHint(string $name, $value): void {
$this->hints[$name] = $value;
}
public static function escapeLikeParameter(string $param): string {
return addcslashes($param, '\\_%');
}
}