Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Escape identifiers in metadata SQL properly when used as string literal #2442

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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