Commit 29b7fb37 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Fixes #9268: Bug - SELECT with outer brackets not recognized as SELECT

parent e4a42173
Pipeline #6290 passed with stages
in 4 minutes and 40 seconds
......@@ -2935,8 +2935,8 @@ The *tablesorter* options:
* 'Views' can be saved as:
* public: every user will see the `view` and can modify it.
* private: only the user who created the `view` will see/modify it.
* group: every user will see the `view` and can modify it.
* personal: only the user who created the `view` will see/modify it.
* readonly: manually mark a `view` as readonly (no FE User can change it) by setting column `readonly='true'` in table
`Setting` of the corresponding view (identified by `name`).
......
......@@ -257,7 +257,8 @@ abstract class AbstractBuildForm {
$this->store->setStore($row, STORE_PARENT_RECORD, true);
$this->store->setVar(F_MULTI_COL_ID, $row[$idName], STORE_PARENT_RECORD); // In case '_id' is used, both '_id' and 'id' should be accessible.
$record = $this->dbArray[$this->dbIndexData]->sql('SELECT * FROM `' . $this->formSpec[F_TABLE_NAME] . '` WHERE `id`= ?', ROW_EXPECT_1, [$row[$idName]]);
$record = $this->dbArray[$this->dbIndexData]->sql('SELECT * FROM `' . $this->formSpec[F_TABLE_NAME] . '` WHERE `id`= ?',
ROW_EXPECT_1, [$row[$idName]], 'If you get 0 records: check that the primary table is the one used in multi SQL');
$this->store->setStore($record, STORE_RECORD, true);
$jsonTmp = array();
......
......@@ -14,6 +14,7 @@ use IMATHUZH\Qfq\Core\Helper\HelperFile;
use IMATHUZH\Qfq\Core\Helper\HelperFormElement;
use IMATHUZH\Qfq\Core\Helper\Logger;
use IMATHUZH\Qfq\Core\Helper\OnArray;
use IMATHUZH\Qfq\Core\Helper\OnString;
use IMATHUZH\Qfq\Core\Helper\Path;
use IMATHUZH\Qfq\Core\Helper\SqlQuery;
use IMATHUZH\Qfq\Core\Store\Store;
......@@ -433,6 +434,7 @@ class Database {
$command = 'FAILED';
}
$command = OnString::removeLeadingBrace($command);
switch ($command) {
case 'SELECT':
case 'SHOW':
......
......@@ -17,7 +17,6 @@ use IMATHUZH\Qfq\Core\Report\Link;
use IMATHUZH\Qfq\Core\Report\Tablesorter;
use IMATHUZH\Qfq\Core\Store\Sip;
use IMATHUZH\Qfq\Core\Store\Store;
use IMATHUZH\Qfq\Core\Typo3\T3Handler;
const EVALUATE_DB_INDEX_DEFAULT = 0;
......@@ -340,14 +339,19 @@ class Evaluate {
return '';
}
// Get SQL column / row separated
if ($token[0] === '!') {
$token = trim(substr($token, 1));
$sqlMode = ROW_REGULAR;
}
// In case there is a statement starting with '(' (multiple): remove them just to detect if the following is a SQL statement.
// E.g. original: "{{[1] ! ( SELECT name FROM person ORDER BY name UNION SELECT 'new'}}"
$tokenClean = OnString::removeLeadingBrace($token);
// Extract token: check if this is a 'variable', 'SQL Statement', 'link', 'data-dnd-api'
$arrToken = explode(' ', $token);
$arrToken = explode(' ', $tokenClean);
// Variable Type 'SQL Statement'
if (in_array(strtoupper($arrToken[VAR_INDEX_VALUE] . ' '), $this->sqlKeywords)) {
......@@ -356,7 +360,6 @@ class Evaluate {
return $this->dbArray[$dbIndex]->sql($token, $sqlMode);
}
// Variable Type '... AS _link', '... as data-dnd-api', '... AS _tablesorter-view-saver'
$countToken = count($arrToken);
if ($countToken > 2 && strtolower($arrToken[$countToken - 2]) == 'as') {
......
......@@ -645,5 +645,29 @@ class OnString {
return $new;
}
/**
* Checks for any leading braces in $data. Spaces will be ignored.
*
* 'SELE..': returns $data unchanged
* ' ( SELECT...': returns 'SELECT...'
* ' ( (SELECT...': returns 'SELECT...'
*
* @param $data
* @return string
*/
public static function removeLeadingBrace($data) {
$trimmed = false;
$value = trim($data);
while ($value != '' && $value[0] == '(') {
$trimmed = true;
$value = trim(substr($value, 1));
}
if ($trimmed) {
$data = $value;
}
return $value;
}
}
......@@ -534,6 +534,18 @@ class DatabaseTest extends AbstractDatabaseTest {
}
public function testLeadingBrace() {
$allRows = $this->dbArray[DB_INDEX_DEFAULT]->sql('(SELECT * FROM Person WHERE id=0)');
$this->assertEquals(array(), $allRows);
$allRows = $this->dbArray[DB_INDEX_DEFAULT]->sql('(SELECT * FROM Person LIMIT 1)');
$this->assertEquals(1, count($allRows));
$allRows = $this->dbArray[DB_INDEX_DEFAULT]->sql('(SELECT * FROM Person LIMIT 1) UNION ALL (SELECT * FROM Person LIMIT 1)');
$this->assertEquals(2, count($allRows));
}
/**
* @throws \CodeException
* @throws \DbException
......
......@@ -284,4 +284,15 @@ class OnStringTest extends TestCase {
$expected = "<img src=\"pig.gif\" title=\"Pig &quot;blue&quot;\"><img src=\"sun.gif\" title=\"Sun &quot;bright&quot;\">";
$this->assertEquals($expected, OnString::escapeSingleTickInHtml("<img src='pig.gif' title='Pig \"blue\"'><img src='sun.gif' title='Sun \"bright\"'>"));
}
public function testRemoveLeadingBrace() {
$this->assertEquals('', OnString::removeLeadingBrace(""));
$this->assertEquals('SELECT', OnString::removeLeadingBrace("SELECT"));
$this->assertEquals('SELECT', OnString::removeLeadingBrace(" SELECT"));
$this->assertEquals('SELECT', OnString::removeLeadingBrace("( SELECT"));
$this->assertEquals('SELECT', OnString::removeLeadingBrace(" (SELECT"));
$this->assertEquals('SELECT', OnString::removeLeadingBrace("((SELECT"));
$this->assertEquals('SELECT', OnString::removeLeadingBrace(" ( ( SELECT"));
}
}
\ No newline at end of file
......@@ -159,8 +159,8 @@ var QfqNS = QfqNS || {};
'<i class="fa fa-pencil-alt"></i>' +
'</button>' +
'<ul class="dropdown-menu pull-right" role="menu">' +
'<li><a href="#" data-save-private-view>Save Private View</a></li>' +
'<li><a href="#" data-save-public-view>Save Public View</a></li>' +
'<li><a href="#" data-save-private-view>Save Personal View</a></li>' +
'<li><a href="#" data-save-public-view>Save Group View</a></li>' +
'<li><a href="#" data-delete-view>Delete View</a></li>' +
'</ul>' +
'</div>';
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment