diff options
author | Morris Jobke <hey@morrisjobke.de> | 2015-11-20 16:44:25 +0100 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2015-11-20 16:44:25 +0100 |
commit | dc2a6e2210ba7ddf756a35ddebe22a27eb3d922f (patch) | |
tree | bc9436a8e3eeb9f69c4e6e8d4c8eaf6fa52b1402 | |
parent | ded50e8dbe0f519ba9b16016c3be9f15422f33b1 (diff) | |
parent | 08866d54fda7e8ca07286fe565ff12762f726375 (diff) | |
download | nextcloud-server-dc2a6e2210ba7ddf756a35ddebe22a27eb3d922f.tar.gz nextcloud-server-dc2a6e2210ba7ddf756a35ddebe22a27eb3d922f.zip |
Merge pull request #20638 from owncloud/cache-escape-like-8
[8.0] Escape like parameter in cache operations
-rw-r--r-- | lib/private/db/adapteroci8.php | 1 | ||||
-rw-r--r-- | lib/private/db/adaptersqlite.php | 1 | ||||
-rw-r--r-- | lib/private/files/cache/cache.php | 3 | ||||
-rw-r--r-- | tests/lib/files/cache/cache.php | 48 |
4 files changed, 52 insertions, 1 deletions
diff --git a/lib/private/db/adapteroci8.php b/lib/private/db/adapteroci8.php index db7e66e7913..825895441ac 100644 --- a/lib/private/db/adapteroci8.php +++ b/lib/private/db/adapteroci8.php @@ -21,6 +21,7 @@ class AdapterOCI8 extends Adapter { const UNIX_TIMESTAMP_REPLACEMENT = "(cast(sys_extract_utc(systimestamp) as date) - date'1970-01-01') * 86400"; public function fixupStatement($statement) { + $statement = preg_replace('( LIKE \?)', '$0 ESCAPE \'\\\'', $statement); $statement = preg_replace('/`(\w+)` ILIKE \?/', 'REGEXP_LIKE(`$1`, \'^\' || REPLACE(?, \'%\', \'.*\') || \'$\', \'i\')', $statement); $statement = str_replace('`', '"', $statement); $statement = str_ireplace('NOW()', 'CURRENT_TIMESTAMP', $statement); diff --git a/lib/private/db/adaptersqlite.php b/lib/private/db/adaptersqlite.php index a9106967333..cc0e9e89ff8 100644 --- a/lib/private/db/adaptersqlite.php +++ b/lib/private/db/adaptersqlite.php @@ -11,6 +11,7 @@ namespace OC\DB; class AdapterSqlite extends Adapter { public function fixupStatement($statement) { + $statement = preg_replace('( I?LIKE \?)', '$0 ESCAPE \'\\\'', $statement); $statement = preg_replace('/`(\w+)` ILIKE \?/', 'LOWER($1) LIKE LOWER(?)', $statement); $statement = str_replace( '`', '"', $statement ); $statement = str_ireplace( 'NOW()', 'datetime(\'now\')', $statement ); diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 358e654aada..b6062c75408 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -432,7 +432,8 @@ class Cache { if ($sourceData['mimetype'] === 'httpd/unix-directory') { //find all child entries $sql = 'SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?'; - $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $source . '/%')); + $escapedsource = addcslashes($source, '\\_%'); + $result = \OC_DB::executeAudited($sql, array($this->getNumericStorageId(), $escapedsource . '/%')); $childEntries = $result->fetchAll(); $sourceLength = strlen($source); $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ? WHERE `fileid` = ?'); diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 3f869639f25..17bb0ee1e43 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -585,6 +585,54 @@ class Cache extends \Test\TestCase { $this->assertNotEquals($fileId, $fileId2); } + public function escapingProvider() { + return [ + ['foo'], + ['o%'], + ['oth_r'], + ]; + } + + /** + * @param string $name + * @dataProvider escapingProvider + */ + public function testEscaping($name) { + $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain'); + $this->cache->put($name, $data); + $this->assertTrue($this->cache->inCache($name)); + $retrievedData = $this->cache->get($name); + foreach ($data as $key => $value) { + $this->assertEquals($value, $retrievedData[$key]); + } + $this->cache->move($name, $name . 'asd'); + $this->assertFalse($this->cache->inCache($name)); + $this->assertTrue($this->cache->inCache($name . 'asd')); + $this->cache->remove($name . 'asd'); + $this->assertFalse($this->cache->inCache($name . 'asd')); + $folderData = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); + $this->cache->put($name, $folderData); + $this->cache->put('other', $folderData); + $childs = ['asd', 'bar', 'foo', 'sub/folder']; + $this->cache->put($name . '/sub/folder', $folderData); + $this->cache->put('other/sub/folder', $folderData); + foreach ($childs as $child) { + $this->cache->put($name . '/' . $child, $data); + $this->cache->put('other/' . $child, $data); + $this->assertTrue($this->cache->inCache($name . '/' . $child)); + } + $this->cache->move($name, $name . 'asd'); + foreach ($childs as $child) { + $this->assertTrue($this->cache->inCache($name . 'asd/' . $child)); + $this->assertTrue($this->cache->inCache('other/' . $child)); + } + foreach ($childs as $child) { + $this->cache->remove($name . 'asd/' . $child); + $this->assertFalse($this->cache->inCache($name . 'asd/' . $child)); + $this->assertTrue($this->cache->inCache('other/' . $child)); + } + } + protected function tearDown() { if ($this->cache) { $this->cache->clear(); |