Skip to content

Commit

Permalink
escape identifiers in metadata SQL properly when used as string literal
Browse files Browse the repository at this point in the history
 Closes #2436
  • Loading branch information
deeky666 committed Jul 7, 2016
1 parent 69b5785 commit a89d283
Show file tree
Hide file tree
Showing 15 changed files with 498 additions and 35 deletions.
12 changes: 9 additions & 3 deletions lib/Doctrine/DBAL/Platforms/DB2Platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ public function getTruncateTableSQL($tableName, $cascade = false)
*/
public function getListTableColumnsSQL($table, $database = null)
{
$table = $this->quoteStringLiteral($table);

// We do the funky subquery and join syscat.columns.default this crazy way because
// as of db2 v10, the column is CLOB(64k) and the distinct operator won't allow a CLOB,
// it wants shorter stuff like a varchar.
Expand Down Expand Up @@ -282,7 +284,7 @@ public function getListTableColumnsSQL($table, $database = null)
ON (c.tabschema = k.tabschema
AND c.tabname = k.tabname
AND c.colname = k.colname)
WHERE UPPER(c.tabname) = UPPER('" . $table . "')
WHERE UPPER(c.tabname) = UPPER(" . $table . ")
ORDER BY c.colno
) subq
JOIN syscat.columns cols
Expand Down Expand Up @@ -314,6 +316,8 @@ public function getListViewsSQL($database)
*/
public function getListTableIndexesSQL($table, $currentDatabase = null)
{
$table = $this->quoteStringLiteral($table);

return "SELECT idx.INDNAME AS key_name,
idxcol.COLNAME AS column_name,
CASE
Expand All @@ -327,7 +331,7 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
FROM SYSCAT.INDEXES AS idx
JOIN SYSCAT.INDEXCOLUSE AS idxcol
ON idx.INDSCHEMA = idxcol.INDSCHEMA AND idx.INDNAME = idxcol.INDNAME
WHERE idx.TABNAME = UPPER('" . $table . "')
WHERE idx.TABNAME = UPPER(" . $table . ")
ORDER BY idxcol.COLSEQ ASC";
}

Expand All @@ -336,6 +340,8 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
*/
public function getListTableForeignKeysSQL($table)
{
$table = $this->quoteStringLiteral($table);

return "SELECT fkcol.COLNAME AS local_column,
fk.REFTABNAME AS foreign_table,
pkcol.COLNAME AS foreign_column,
Expand All @@ -359,7 +365,7 @@ public function getListTableForeignKeysSQL($table)
ON fk.REFKEYNAME = pkcol.CONSTNAME
AND fk.REFTABSCHEMA = pkcol.TABSCHEMA
AND fk.REFTABNAME = pkcol.TABNAME
WHERE fk.TABNAME = UPPER('" . $table . "')
WHERE fk.TABNAME = UPPER(" . $table . ")
ORDER BY fkcol.COLSEQ ASC";
}

Expand Down
38 changes: 32 additions & 6 deletions lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,14 @@ public function getListTableConstraintsSQL($table)
public function getListTableIndexesSQL($table, $currentDatabase = null)
{
if ($currentDatabase) {
$currentDatabase = $this->quoteStringLiteral($currentDatabase);
$table = $this->quoteStringLiteral($table);

return "SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ".
"SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ".
"CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, " .
"NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment " .
"FROM information_schema.STATISTICS WHERE TABLE_NAME = '" . $table . "' AND TABLE_SCHEMA = '" . $currentDatabase . "'";
"FROM information_schema.STATISTICS WHERE TABLE_NAME = " . $table . " AND TABLE_SCHEMA = " . $currentDatabase;
}

return 'SHOW INDEX FROM ' . $table;
Expand All @@ -174,22 +177,33 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
*/
public function getListViewsSQL($database)
{
return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '".$database."'";
$database = $this->quoteStringLiteral($database);

return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = " . $database;
}

/**
* {@inheritDoc}
*/
public function getListTableForeignKeysSQL($table, $database = null)
{
$table = $this->quoteStringLiteral($table);

if (null !== $database) {
$database = $this->quoteStringLiteral($database);
}

$sql = "SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ".
"k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ".
"FROM information_schema.key_column_usage k /*!50116 ".
"INNER JOIN information_schema.referential_constraints c ON ".
" c.constraint_name = k.constraint_name AND ".
" c.table_name = '$table' */ WHERE k.table_name = '$table'";
" c.table_name = $table */ WHERE k.table_name = $table";

$databaseNameSql = null === $database ? "'$database'" : 'DATABASE()';
// @TODO: This needs fixing. The condition has to be inverted.
// When fixed, AbstractMySQLPlatformTestCase::testQuotesDatabaseNameInListTableForeignKeysSQL test
// has to be completed.
$databaseNameSql = null === $database ? $database : 'DATABASE()';

$sql .= " AND k.table_schema = $databaseNameSql /*!50116 AND c.constraint_schema = $databaseNameSql */";
$sql .= " AND k.`REFERENCED_COLUMN_NAME` is not NULL";
Expand Down Expand Up @@ -364,16 +378,18 @@ public function getListTablesSQL()
*/
public function getListTableColumnsSQL($table, $database = null)
{
$table = $this->quoteStringLiteral($table);

if ($database) {
$database = "'" . $database . "'";
$database = $this->quoteStringLiteral($database);
} else {
$database = 'DATABASE()';
}

return "SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ".
"COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, " .
"CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS Collation ".
"FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = " . $database . " AND TABLE_NAME = '" . $table . "'";
"FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = " . $database . " AND TABLE_NAME = " . $table;
}

/**
Expand Down Expand Up @@ -1080,4 +1096,14 @@ public function getBlobTypeDeclarationSQL(array $field)

return 'LONGBLOB';
}

/**
* {@inheritdoc}
*/
public function quoteStringLiteral($str)
{
$str = str_replace('\\', '\\\\', $str); // MySQL requires backslashes to be escaped aswell.

return parent::quoteStringLiteral($str);
}
}
30 changes: 23 additions & 7 deletions lib/Doctrine/DBAL/Platforms/OraclePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,10 @@ public function getListDatabasesSQL()
public function getListSequencesSQL($database)
{
$database = $this->normalizeIdentifier($database);
$database = $this->quoteStringLiteral($database->getName());

return "SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ".
"WHERE SEQUENCE_OWNER = '" . $database->getName() . "'";
"WHERE SEQUENCE_OWNER = " . $database;
}

/**
Expand Down Expand Up @@ -418,6 +419,7 @@ protected function _getCreateTableSQL($table, array $columns, array $options = a
public function getListTableIndexesSQL($table, $currentDatabase = null)
{
$table = $this->normalizeIdentifier($table);
$table = $this->quoteStringLiteral($table->getName());

return "SELECT uind_col.index_name AS name,
(
Expand All @@ -444,7 +446,7 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
WHERE ucon.constraint_name = uind_col.index_name
) AS is_primary
FROM user_ind_columns uind_col
WHERE uind_col.table_name = '" . $table->getName() . "'
WHERE uind_col.table_name = " . $table . "
ORDER BY uind_col.column_position ASC";
}

Expand Down Expand Up @@ -608,7 +610,8 @@ private function getAutoincrementIdentifierName(Identifier $table)
*/
public function getListTableForeignKeysSQL($table)
{
$table = $table = $this->normalizeIdentifier($table);
$table = $this->normalizeIdentifier($table);
$table = $this->quoteStringLiteral($table->getName());

return "SELECT alc.constraint_name,
alc.DELETE_RULE,
Expand All @@ -630,7 +633,7 @@ public function getListTableForeignKeysSQL($table)
JOIN user_constraints alc
ON alc.constraint_name = cols.constraint_name
AND alc.constraint_type = 'R'
AND alc.table_name = '" . $table->getName() . "'
AND alc.table_name = " . $table . "
ORDER BY cols.constraint_name ASC, cols.position ASC";
}

Expand All @@ -640,8 +643,9 @@ public function getListTableForeignKeysSQL($table)
public function getListTableConstraintsSQL($table)
{
$table = $this->normalizeIdentifier($table);
$table = $this->quoteStringLiteral($table->getName());

return "SELECT * FROM user_constraints WHERE table_name = '" . $table->getName() . "'";
return "SELECT * FROM user_constraints WHERE table_name = " . $table;
}

/**
Expand All @@ -650,16 +654,18 @@ public function getListTableConstraintsSQL($table)
public function getListTableColumnsSQL($table, $database = null)
{
$table = $this->normalizeIdentifier($table);
$table = $this->quoteStringLiteral($table->getName());

$tabColumnsTableName = "user_tab_columns";
$colCommentsTableName = "user_col_comments";
$ownerCondition = '';

if (null !== $database) {
$database = $this->normalizeIdentifier($database);
$database = $this->quoteStringLiteral($database->getName());
$tabColumnsTableName = "all_tab_columns";
$colCommentsTableName = "all_col_comments";
$ownerCondition = "AND c.owner = '" . $database->getName() . "'";
$ownerCondition = "AND c.owner = " . $database;
}

return "SELECT c.*,
Expand All @@ -670,7 +676,7 @@ public function getListTableColumnsSQL($table, $database = null)
AND d.COLUMN_NAME = c.COLUMN_NAME
) AS comments
FROM $tabColumnsTableName c
WHERE c.table_name = '" . $table->getName() . "' $ownerCondition
WHERE c.table_name = " . $table . " $ownerCondition
ORDER BY c.column_name";
}

Expand Down Expand Up @@ -1153,4 +1159,14 @@ public function getBlobTypeDeclarationSQL(array $field)
{
return 'BLOB';
}

/**
* {@inheritdoc}
*/
public function quoteStringLiteral($str)
{
$str = str_replace('\\', '\\\\', $str); // Oracle requires backslashes to be escaped aswell.

return parent::quoteStringLiteral($str);
}
}
4 changes: 3 additions & 1 deletion lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ protected function initializeDoctrineTypeMappings()
*/
public function getCloseActiveDatabaseConnectionsSQL($database)
{
return "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$database'";
$database = $this->quoteStringLiteral($database);

return "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $database";
}
}
23 changes: 18 additions & 5 deletions lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ public function getDropViewSQL($name)
public function getListTableConstraintsSQL($table)
{
$table = new Identifier($table);
$table = $table->getName();
$table = $this->quoteStringLiteral($table->getName());

return "SELECT
quote_ident(relname) as relname
Expand All @@ -327,7 +327,7 @@ public function getListTableConstraintsSQL($table)
WHERE oid IN (
SELECT indexrelid
FROM pg_index, pg_class
WHERE pg_class.relname = '$table'
WHERE pg_class.relname = $table
AND pg_class.oid = pg_index.indrelid
AND (indisunique = 't' OR indisprimary = 't')
)";
Expand Down Expand Up @@ -364,13 +364,14 @@ private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias
$whereClause = $namespaceAlias.".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ";
if (strpos($table, ".") !== false) {
list($schema, $table) = explode(".", $table);
$schema = "'" . $schema . "'";
$schema = $this->quoteStringLiteral($schema);
} else {
$schema = "ANY(string_to_array((select replace(replace(setting,'\"\$user\"',user),' ','') from pg_catalog.pg_settings where name = 'search_path'),','))";
}

$table = new Identifier($table);
$whereClause .= "$classAlias.relname = '" . $table->getName() . "' AND $namespaceAlias.nspname = $schema";
$table = $this->quoteStringLiteral($table->getName());
$whereClause .= "$classAlias.relname = " . $table . " AND $namespaceAlias.nspname = $schema";

return $whereClause;
}
Expand Down Expand Up @@ -445,7 +446,9 @@ public function getDisallowDatabaseConnectionsSQL($database)
*/
public function getCloseActiveDatabaseConnectionsSQL($database)
{
return "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = '$database'";
$database = $this->quoteStringLiteral($database);

return "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = $database";
}

/**
Expand Down Expand Up @@ -1173,4 +1176,14 @@ public function getBlobTypeDeclarationSQL(array $field)
{
return 'BYTEA';
}

/**
* {@inheritdoc}
*/
public function quoteStringLiteral($str)
{
$str = str_replace('\\', '\\\\', $str); // PostgreSQL requires backslashes to be escaped aswell.

return parent::quoteStringLiteral($str);
}
}
23 changes: 16 additions & 7 deletions lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ public function getListTableColumnsSQL($table, $database = null)

if (strpos($table, '.') !== false) {
list($user, $table) = explode('.', $table);
$user = "'" . $user . "'";
$user = $this->quoteStringLiteral($user);
}

return "SELECT col.column_name,
Expand Down Expand Up @@ -756,13 +756,16 @@ public function getListTableConstraintsSQL($table)

if (strpos($table, '.') !== false) {
list($user, $table) = explode('.', $table);
$user = "'" . $user . "'";
$user = $this->quoteStringLiteral($user);
$table = $this->quoteStringLiteral($table);
} else {
$table = $this->quoteStringLiteral($table);
}

return "SELECT con.*
FROM SYS.SYSCONSTRAINT AS con
JOIN SYS.SYSTAB AS tab ON con.table_object_id = tab.object_id
WHERE tab.table_name = '$table'
WHERE tab.table_name = $table
AND tab.creator = USER_ID($user)";
}

Expand All @@ -775,7 +778,10 @@ public function getListTableForeignKeysSQL($table)

if (strpos($table, '.') !== false) {
list($user, $table) = explode('.', $table);
$user = "'" . $user . "'";
$user = $this->quoteStringLiteral($user);
$table = $this->quoteStringLiteral($table);
} else {
$table = $this->quoteStringLiteral($table);
}

return "SELECT fcol.column_name AS local_column,
Expand Down Expand Up @@ -844,7 +850,7 @@ public function getListTableForeignKeysSQL($table)
ON fk.foreign_table_id = dt.foreign_table_id
AND fk.foreign_index_id = dt.foreign_key_id
AND dt.event = 'D'
WHERE ftbl.table_name = '$table'
WHERE ftbl.table_name = $table
AND ftbl.creator = USER_ID($user)
ORDER BY fk.foreign_index_id ASC, idxcol.sequence ASC";
}
Expand All @@ -858,7 +864,10 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)

if (strpos($table, '.') !== false) {
list($user, $table) = explode('.', $table);
$user = "'" . $user . "'";
$user = $this->quoteStringLiteral($user);
$table = $this->quoteStringLiteral($table);
} else {
$table = $this->quoteStringLiteral($table);
}

return "SELECT idx.index_name AS key_name,
Expand Down Expand Up @@ -893,7 +902,7 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
ON idxcol.table_id = col.table_id AND idxcol.column_id = col.column_id
JOIN SYS.SYSTAB AS tbl
ON idx.table_id = tbl.table_id
WHERE tbl.table_name = '$table'
WHERE tbl.table_name = $table
AND tbl.creator = USER_ID($user)
AND idx.index_category != 2 -- exclude indexes implicitly created by foreign key constraints
ORDER BY idx.index_id ASC, idxcol.sequence ASC";
Expand Down
Loading

0 comments on commit a89d283

Please sign in to comment.