Skip to content

Commit

Permalink
Quote reserved words in database queries (see #1262)
Browse files Browse the repository at this point in the history
Description
-----------

This is the port of contao/core#8813.

Also see #1106 and contao/installation-bundle#70

Commits
-------

84c4746 Quote reserved words in database queries
7bf64b1 Use static instead of \Database as self-reference.
  • Loading branch information
ausi authored and leofeyer committed Dec 27, 2017
1 parent 873eeeb commit 44a0ba1
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 32 deletions.
30 changes: 15 additions & 15 deletions src/Resources/contao/drivers/DC_Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ public function show()

foreach ((array) $value as $v)
{
$objKey = $this->Database->prepare("SELECT " . $chunks[1] . " AS value FROM " . $chunks[0] . " WHERE id=?")
$objKey = $this->Database->prepare("SELECT " . \Database::quoteColumnName($chunks[1]) . " AS value FROM " . $chunks[0] . " WHERE id=?")
->limit(1)
->execute($v);

Expand Down Expand Up @@ -3138,12 +3138,12 @@ protected function save($varValue)
{
if ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4)
{
$this->Database->prepare("UPDATE " . $this->strTable . " SET " . $this->strField . "='' WHERE pid=?")
$this->Database->prepare("UPDATE " . $this->strTable . " SET " . \Database::quoteColumnName($this->strField) . "='' WHERE pid=?")
->execute($this->activeRecord->pid);
}
else
{
$this->Database->execute("UPDATE " . $this->strTable . " SET " . $this->strField . "=''");
$this->Database->execute("UPDATE " . $this->strTable . " SET " . \Database::quoteColumnName($this->strField) . "=''");
}
}

Expand All @@ -3156,7 +3156,7 @@ protected function save($varValue)
$arrValues = $this->values;
array_unshift($arrValues, $varValue);

$objUpdateStmt = $this->Database->prepare("UPDATE " . $this->strTable . " SET " . $this->strField . "=? WHERE " . implode(' AND ', $this->procedure))
$objUpdateStmt = $this->Database->prepare("UPDATE " . $this->strTable . " SET " . \Database::quoteColumnName($this->strField) . "=? WHERE " . implode(' AND ', $this->procedure))
->execute($arrValues);

if ($objUpdateStmt->affectedRows)
Expand Down Expand Up @@ -3877,7 +3877,7 @@ protected function generateTree($table, $id, $arrPrevNext, $blnHasSorting, $intM
list($strKey, $strTable) = explode(':', $v);
list($strTable, $strField) = explode('.', $strTable);

$objRef = $this->Database->prepare("SELECT " . $strField . " FROM " . $strTable . " WHERE id=?")
$objRef = $this->Database->prepare("SELECT " . \Database::quoteColumnName($strField) . " FROM " . $strTable . " WHERE id=?")
->limit(1)
->execute($objRow->$strKey);

Expand Down Expand Up @@ -4187,7 +4187,7 @@ protected function parentView()
{
$arrForeignKey = explode('.', $GLOBALS['TL_DCA'][$this->ptable]['fields'][$v]['foreignKey'], 2);

$objLabel = $this->Database->prepare("SELECT " . $arrForeignKey[1] . " AS value FROM " . $arrForeignKey[0] . " WHERE id=?")
$objLabel = $this->Database->prepare("SELECT " . \Database::quoteColumnName($arrForeignKey[1]) . " AS value FROM " . $arrForeignKey[0] . " WHERE id=?")
->limit(1)
->execute($_v);

Expand Down Expand Up @@ -4293,7 +4293,7 @@ protected function parentView()
if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['foreignKey']))
{
$key = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$firstOrderBy]['foreignKey'], 2);
$query = "SELECT *, (SELECT ". $key[1] ." FROM ". $key[0] ." WHERE ". $this->strTable .".". $firstOrderBy ."=". $key[0] .".id) AS foreignKey FROM " . $this->strTable;
$query = "SELECT *, (SELECT ". \Database::quoteColumnName($key[1]) ." FROM ". $key[0] ." WHERE ". $this->strTable .".". \Database::quoteColumnName($firstOrderBy) ."=". $key[0] .".id) AS foreignKey FROM " . $this->strTable;
$orderBy[0] = 'foreignKey';
}
}
Expand Down Expand Up @@ -4668,7 +4668,7 @@ protected function listView()
$firstOrderBy = 'pid';
$showFields = $GLOBALS['TL_DCA'][$table]['list']['label']['fields'];

$query .= " ORDER BY (SELECT " . $showFields[0] . " FROM " . $this->ptable . " WHERE " . $this->ptable . ".id=" . $this->strTable . ".pid), " . implode(', ', $orderBy);
$query .= " ORDER BY (SELECT " . \Database::quoteColumnName($showFields[0]) . " FROM " . $this->ptable . " WHERE " . $this->ptable . ".id=" . $this->strTable . ".pid), " . implode(', ', $orderBy);

// Set the foreignKey so that the label is translated
if ($GLOBALS['TL_DCA'][$table]['fields']['pid']['foreignKey'] == '')
Expand Down Expand Up @@ -4805,7 +4805,7 @@ protected function listView()
list($strKey, $strTable) = explode(':', $v);
list($strTable, $strField) = explode('.', $strTable);

$objRef = $this->Database->prepare("SELECT " . $strField . " FROM " . $strTable . " WHERE id=?")
$objRef = $this->Database->prepare("SELECT " . \Database::quoteColumnName($strField) . " FROM " . $strTable . " WHERE id=?")
->limit(1)
->execute($row[$strKey]);

Expand Down Expand Up @@ -5079,7 +5079,7 @@ protected function searchMenu()
{
try
{
$this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . $strField . " REGEXP ?")
$this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . \Database::quoteColumnName($strField) . " REGEXP ?")
->limit(1)
->execute($strKeyword);
}
Expand Down Expand Up @@ -5110,12 +5110,12 @@ protected function searchMenu()
if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$fld]['foreignKey']))
{
list($t, $f) = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$fld]['foreignKey']);
$this->procedure[] = "(" . sprintf($strPattern, $fld) . " OR " . sprintf($strPattern, "(SELECT $f FROM $t WHERE $t.id={$this->strTable}.$fld)") . ")";
$this->procedure[] = "(" . sprintf($strPattern, \Database::quoteColumnName($fld)) . " OR " . sprintf($strPattern, "(SELECT ".\Database::quoteColumnName($f)." FROM $t WHERE $t.id={$this->strTable}.".\Database::quoteColumnName($fld).")") . ")";
$this->values[] = $session['search'][$this->strTable]['value'];
}
else
{
$this->procedure[] = sprintf($strPattern, $fld);
$this->procedure[] = sprintf($strPattern, \Database::quoteColumnName($fld));
}

$this->values[] = $session['search'][$this->strTable]['value'];
Expand Down Expand Up @@ -5718,7 +5718,7 @@ protected function filterMenu($intFilterPanel)
{
$key = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['foreignKey'], 2);

$objParent = $this->Database->prepare("SELECT " . $key[1] . " AS value FROM " . $key[0] . " WHERE id=?")
$objParent = $this->Database->prepare("SELECT " . \Database::quoteColumnName($key[1]) . " AS value FROM " . $key[0] . " WHERE id=?")
->limit(1)
->execute($vv);

Expand All @@ -5745,7 +5745,7 @@ protected function filterMenu($intFilterPanel)
$showFields[0] = 'id';
}

$objShowFields = $this->Database->prepare("SELECT " . $showFields[0] . " FROM ". $this->ptable . " WHERE id=?")
$objShowFields = $this->Database->prepare("SELECT " . \Database::quoteColumnName($showFields[0]) . " FROM ". $this->ptable . " WHERE id=?")
->limit(1)
->execute($vv);

Expand Down Expand Up @@ -5871,7 +5871,7 @@ protected function formatCurrentValue($field, $value, $mode)
{
$key = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$field]['foreignKey'], 2);

$objParent = $this->Database->prepare("SELECT " . $key[1] . " AS value FROM " . $key[0] . " WHERE id=?")
$objParent = $this->Database->prepare("SELECT " . \Database::quoteColumnName($key[1]) . " AS value FROM " . $key[0] . " WHERE id=?")
->limit(1)
->execute($value);

Expand Down
30 changes: 28 additions & 2 deletions src/Resources/contao/library/Contao/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public function findInSet($strKey, $varSet, $blnIsField=false)
$varSet = $this->resConnection->quote($varSet);
}

return "FIND_IN_SET(" . $strKey . ", " . $varSet . ")";
return "FIND_IN_SET(" . static::quoteColumnName($strKey) . ", " . $varSet . ")";
}


Expand Down Expand Up @@ -490,7 +490,7 @@ public function getFieldNames($strTable, $blnNoCache=false)
*/
public function isUniqueValue($strTable, $strField, $varValue, $intId=null)
{
$strQuery = "SELECT * FROM $strTable WHERE $strField=?";
$strQuery = "SELECT * FROM $strTable WHERE " . static::quoteColumnName($strField) . "=?";

if ($intId !== null)
{
Expand Down Expand Up @@ -706,6 +706,32 @@ public function getUuid()
}


/**
* Quote the column name if it is a reserved word
*
* @param string $strName
*
* @return string
*/
public static function quoteColumnName($strName)
{
return \System::getContainer()->get('database_connection')->getDatabasePlatform()->quoteSingleIdentifier($strName);
}


/**
* Quote a list of column names
*
* @param string[] $arrNames
*
* @return string[]
*/
public static function quoteColumnNames(array $arrNames)
{
return array_map(array(static::class, 'quoteColumnName'), $arrNames);
}


/**
* Execute a query and do not cache the result
*
Expand Down
4 changes: 2 additions & 2 deletions src/Resources/contao/library/Contao/Database/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public function set($arrParams)
if (strncasecmp($this->strQuery, 'INSERT', 6) === 0)
{
$strQuery = sprintf('(%s) VALUES (%s)',
implode(', ', array_keys($arrParams)),
implode(', ', \Database::quoteColumnNames(array_keys($arrParams))),
str_replace('%', '%%', implode(', ', array_values($arrParams))));
}

Expand All @@ -193,7 +193,7 @@ public function set($arrParams)

foreach ($arrParams as $k=>$v)
{
$arrSet[] = $k . '=' . $v;
$arrSet[] = \Database::quoteColumnName($k) . '=' . $v;
}

$strQuery = 'SET ' . str_replace('%', '%%', implode(', ', $arrSet));
Expand Down
8 changes: 4 additions & 4 deletions src/Resources/contao/library/Contao/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ public function save()
}

// Update the row
$objDatabase->prepare("UPDATE " . static::$strTable . " %s WHERE " . static::$strPk . "=?")
$objDatabase->prepare("UPDATE " . static::$strTable . " %s WHERE " . \Database::quoteColumnName(static::$strPk) . "=?")
->set($arrSet)
->execute($intPk);

Expand Down Expand Up @@ -563,7 +563,7 @@ public function delete()
}

// Delete the row
$intAffected = \Database::getInstance()->prepare("DELETE FROM " . static::$strTable . " WHERE " . static::$strPk . "=?")
$intAffected = \Database::getInstance()->prepare("DELETE FROM " . static::$strTable . " WHERE " . \Database::quoteColumnName(static::$strPk) . "=?")
->execute($intPk)
->affectedRows;

Expand Down Expand Up @@ -624,7 +624,7 @@ public function getRelated($strKey, array $arrOptions=array())
elseif ($arrRelation['type'] == 'hasMany' || $arrRelation['type'] == 'belongsToMany')
{
$arrValues = \StringUtil::deserialize($this->$strKey, true);
$strField = $arrRelation['table'] . '.' . $arrRelation['field'];
$strField = $arrRelation['table'] . '.' . \Database::quoteColumnName($arrRelation['field']);

// Handle UUIDs (see #6525)
if ($strField == 'tl_files.uuid')
Expand Down Expand Up @@ -668,7 +668,7 @@ public function refresh()
}

// Reload the database record
$res = \Database::getInstance()->prepare("SELECT * FROM " . static::$strTable . " WHERE " . static::$strPk . "=?")
$res = \Database::getInstance()->prepare("SELECT * FROM " . static::$strTable . " WHERE " . \Database::quoteColumnName(static::$strPk) . "=?")
->execute($intPk);

$this->setRow($res->row());
Expand Down
8 changes: 4 additions & 4 deletions src/Resources/contao/library/Contao/Model/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ public static function find(array $arrOptions)

foreach (array_keys($objRelated->getFields()) as $strField)
{
$arrFields[] = 'j' . $intCount . '.' . $strField . ' AS ' . $strKey . '__' . $strField;
$arrFields[] = 'j' . $intCount . '.' . \Database::quoteColumnName($strField) . ' AS ' . $strKey . '__' . $strField;
}

$arrJoins[] = " LEFT JOIN " . $arrConfig['table'] . " j$intCount ON " . $arrOptions['table'] . "." . $strKey . "=j$intCount." . $arrConfig['field'];
$arrJoins[] = " LEFT JOIN " . $arrConfig['table'] . " j$intCount ON " . $arrOptions['table'] . "." . \Database::quoteColumnName($strKey) . "=j$intCount." . $arrConfig['field'];
}
}
}
Expand All @@ -68,7 +68,7 @@ public static function find(array $arrOptions)
// Where condition
if ($arrOptions['column'] !== null)
{
$strQuery .= " WHERE " . (\is_array($arrOptions['column']) ? implode(" AND ", $arrOptions['column']) : $arrOptions['table'] . '.' . $arrOptions['column'] . "=?");
$strQuery .= " WHERE " . (\is_array($arrOptions['column']) ? implode(" AND ", $arrOptions['column']) : $arrOptions['table'] . '.' . \Database::quoteColumnName($arrOptions['column']) . "=?");
}

// Group by
Expand Down Expand Up @@ -106,7 +106,7 @@ public static function count(array $arrOptions)

if ($arrOptions['column'] !== null)
{
$strQuery .= " WHERE " . (\is_array($arrOptions['column']) ? implode(" AND ", $arrOptions['column']) : $arrOptions['table'] . '.' . $arrOptions['column'] . "=?");
$strQuery .= " WHERE " . (\is_array($arrOptions['column']) ? implode(" AND ", $arrOptions['column']) : $arrOptions['table'] . '.' . \Database::quoteColumnName($arrOptions['column']) . "=?");
}

return $strQuery;
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/contao/library/Contao/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ protected function checkAccountStatus()
*/
public function findBy($strColumn, $varValue)
{
$objResult = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . $strColumn . "=?")
$objResult = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE " . \Database::quoteColumnName($strColumn) . "=?")
->limit(1)
->execute($varValue);

Expand Down
2 changes: 1 addition & 1 deletion src/Resources/contao/widgets/FileSelector.php
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ public function generateAjax($strFolder, $strField, $level, $mount=false)
break;
}

$objField = $this->Database->prepare("SELECT " . $this->strField . " FROM " . $this->strTable . " WHERE id=?")
$objField = $this->Database->prepare("SELECT " . \Database::quoteColumnName($this->strField) . " FROM " . $this->strTable . " WHERE id=?")
->limit(1)
->execute($this->strId);

Expand Down
2 changes: 1 addition & 1 deletion src/Resources/contao/widgets/FileTree.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function __construct($arrAttributes=null)
$this->strOrderName = $this->orderField . str_replace($this->strField, '', $this->strName);

// Retrieve the order value
$objRow = $this->Database->prepare("SELECT {$this->orderField} FROM {$this->strTable} WHERE id=?")
$objRow = $this->Database->prepare("SELECT ".\Database::quoteColumnName($this->orderField)." FROM {$this->strTable} WHERE id=?")
->limit(1)
->execute($this->activeRecord->id);

Expand Down
2 changes: 1 addition & 1 deletion src/Resources/contao/widgets/PageSelector.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public function generateAjax($id, $strField, $level)
break;
}

$objField = $this->Database->prepare("SELECT " . $this->strField . " FROM " . $this->strTable . " WHERE id=?")
$objField = $this->Database->prepare("SELECT " . \Database::quoteColumnName($this->strField) . " FROM " . $this->strTable . " WHERE id=?")
->limit(1)
->execute($this->strId);

Expand Down
2 changes: 1 addition & 1 deletion src/Resources/contao/widgets/PageTree.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function __construct($arrAttributes=null)
$this->strOrderName = $this->orderField . str_replace($this->strField, '', $this->strName);

// Retrieve the order value
$objRow = $this->Database->prepare("SELECT {$this->orderField} FROM {$this->strTable} WHERE id=?")
$objRow = $this->Database->prepare("SELECT ".\Database::quoteColumnName($this->orderField)." FROM {$this->strTable} WHERE id=?")
->limit(1)
->execute($this->activeRecord->id);

Expand Down

0 comments on commit 44a0ba1

Please sign in to comment.