Skip to content

Commit b6b247a

Browse files
committed
Merge branch 'fix/#2442-DBAL-2436-escape-identifiers-in-metadata-sql'
Close #2442 Close #2436
2 parents 5f4d92a + 1222e94 commit b6b247a

15 files changed

+498
-35
lines changed

lib/Doctrine/DBAL/Platforms/DB2Platform.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ public function getTruncateTableSQL($tableName, $cascade = false)
250250
*/
251251
public function getListTableColumnsSQL($table, $database = null)
252252
{
253+
$table = $this->quoteStringLiteral($table);
254+
253255
// We do the funky subquery and join syscat.columns.default this crazy way because
254256
// as of db2 v10, the column is CLOB(64k) and the distinct operator won't allow a CLOB,
255257
// it wants shorter stuff like a varchar.
@@ -282,7 +284,7 @@ public function getListTableColumnsSQL($table, $database = null)
282284
ON (c.tabschema = k.tabschema
283285
AND c.tabname = k.tabname
284286
AND c.colname = k.colname)
285-
WHERE UPPER(c.tabname) = UPPER('" . $table . "')
287+
WHERE UPPER(c.tabname) = UPPER(" . $table . ")
286288
ORDER BY c.colno
287289
) subq
288290
JOIN syscat.columns cols
@@ -314,6 +316,8 @@ public function getListViewsSQL($database)
314316
*/
315317
public function getListTableIndexesSQL($table, $currentDatabase = null)
316318
{
319+
$table = $this->quoteStringLiteral($table);
320+
317321
return "SELECT idx.INDNAME AS key_name,
318322
idxcol.COLNAME AS column_name,
319323
CASE
@@ -327,7 +331,7 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
327331
FROM SYSCAT.INDEXES AS idx
328332
JOIN SYSCAT.INDEXCOLUSE AS idxcol
329333
ON idx.INDSCHEMA = idxcol.INDSCHEMA AND idx.INDNAME = idxcol.INDNAME
330-
WHERE idx.TABNAME = UPPER('" . $table . "')
334+
WHERE idx.TABNAME = UPPER(" . $table . ")
331335
ORDER BY idxcol.COLSEQ ASC";
332336
}
333337

@@ -336,6 +340,8 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
336340
*/
337341
public function getListTableForeignKeysSQL($table)
338342
{
343+
$table = $this->quoteStringLiteral($table);
344+
339345
return "SELECT fkcol.COLNAME AS local_column,
340346
fk.REFTABNAME AS foreign_table,
341347
pkcol.COLNAME AS foreign_column,
@@ -359,7 +365,7 @@ public function getListTableForeignKeysSQL($table)
359365
ON fk.REFKEYNAME = pkcol.CONSTNAME
360366
AND fk.REFTABSCHEMA = pkcol.TABSCHEMA
361367
AND fk.REFTABNAME = pkcol.TABNAME
362-
WHERE fk.TABNAME = UPPER('" . $table . "')
368+
WHERE fk.TABNAME = UPPER(" . $table . ")
363369
ORDER BY fkcol.COLSEQ ASC";
364370
}
365371

lib/Doctrine/DBAL/Platforms/MySqlPlatform.php

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,14 @@ public function getListTableConstraintsSQL($table)
159159
public function getListTableIndexesSQL($table, $currentDatabase = null)
160160
{
161161
if ($currentDatabase) {
162+
$currentDatabase = $this->quoteStringLiteral($currentDatabase);
163+
$table = $this->quoteStringLiteral($table);
164+
162165
return "SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ".
163166
"SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ".
164167
"CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, " .
165168
"NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment " .
166-
"FROM information_schema.STATISTICS WHERE TABLE_NAME = '" . $table . "' AND TABLE_SCHEMA = '" . $currentDatabase . "'";
169+
"FROM information_schema.STATISTICS WHERE TABLE_NAME = " . $table . " AND TABLE_SCHEMA = " . $currentDatabase;
167170
}
168171

169172
return 'SHOW INDEX FROM ' . $table;
@@ -174,22 +177,33 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
174177
*/
175178
public function getListViewsSQL($database)
176179
{
177-
return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '".$database."'";
180+
$database = $this->quoteStringLiteral($database);
181+
182+
return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = " . $database;
178183
}
179184

180185
/**
181186
* {@inheritDoc}
182187
*/
183188
public function getListTableForeignKeysSQL($table, $database = null)
184189
{
190+
$table = $this->quoteStringLiteral($table);
191+
192+
if (null !== $database) {
193+
$database = $this->quoteStringLiteral($database);
194+
}
195+
185196
$sql = "SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ".
186197
"k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ".
187198
"FROM information_schema.key_column_usage k /*!50116 ".
188199
"INNER JOIN information_schema.referential_constraints c ON ".
189200
" c.constraint_name = k.constraint_name AND ".
190-
" c.table_name = '$table' */ WHERE k.table_name = '$table'";
201+
" c.table_name = $table */ WHERE k.table_name = $table";
191202

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

194208
$sql .= " AND k.table_schema = $databaseNameSql /*!50116 AND c.constraint_schema = $databaseNameSql */";
195209
$sql .= " AND k.`REFERENCED_COLUMN_NAME` is not NULL";
@@ -364,16 +378,18 @@ public function getListTablesSQL()
364378
*/
365379
public function getListTableColumnsSQL($table, $database = null)
366380
{
381+
$table = $this->quoteStringLiteral($table);
382+
367383
if ($database) {
368-
$database = "'" . $database . "'";
384+
$database = $this->quoteStringLiteral($database);
369385
} else {
370386
$database = 'DATABASE()';
371387
}
372388

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

379395
/**
@@ -1080,4 +1096,14 @@ public function getBlobTypeDeclarationSQL(array $field)
10801096

10811097
return 'LONGBLOB';
10821098
}
1099+
1100+
/**
1101+
* {@inheritdoc}
1102+
*/
1103+
public function quoteStringLiteral($str)
1104+
{
1105+
$str = str_replace('\\', '\\\\', $str); // MySQL requires backslashes to be escaped aswell.
1106+
1107+
return parent::quoteStringLiteral($str);
1108+
}
10831109
}

lib/Doctrine/DBAL/Platforms/OraclePlatform.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,10 @@ public function getListDatabasesSQL()
375375
public function getListSequencesSQL($database)
376376
{
377377
$database = $this->normalizeIdentifier($database);
378+
$database = $this->quoteStringLiteral($database->getName());
378379

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

383384
/**
@@ -418,6 +419,7 @@ protected function _getCreateTableSQL($table, array $columns, array $options = a
418419
public function getListTableIndexesSQL($table, $currentDatabase = null)
419420
{
420421
$table = $this->normalizeIdentifier($table);
422+
$table = $this->quoteStringLiteral($table->getName());
421423

422424
return "SELECT uind_col.index_name AS name,
423425
(
@@ -444,7 +446,7 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
444446
WHERE ucon.constraint_name = uind_col.index_name
445447
) AS is_primary
446448
FROM user_ind_columns uind_col
447-
WHERE uind_col.table_name = '" . $table->getName() . "'
449+
WHERE uind_col.table_name = " . $table . "
448450
ORDER BY uind_col.column_position ASC";
449451
}
450452

@@ -608,7 +610,8 @@ private function getAutoincrementIdentifierName(Identifier $table)
608610
*/
609611
public function getListTableForeignKeysSQL($table)
610612
{
611-
$table = $table = $this->normalizeIdentifier($table);
613+
$table = $this->normalizeIdentifier($table);
614+
$table = $this->quoteStringLiteral($table->getName());
612615

613616
return "SELECT alc.constraint_name,
614617
alc.DELETE_RULE,
@@ -630,7 +633,7 @@ public function getListTableForeignKeysSQL($table)
630633
JOIN user_constraints alc
631634
ON alc.constraint_name = cols.constraint_name
632635
AND alc.constraint_type = 'R'
633-
AND alc.table_name = '" . $table->getName() . "'
636+
AND alc.table_name = " . $table . "
634637
ORDER BY cols.constraint_name ASC, cols.position ASC";
635638
}
636639

@@ -640,8 +643,9 @@ public function getListTableForeignKeysSQL($table)
640643
public function getListTableConstraintsSQL($table)
641644
{
642645
$table = $this->normalizeIdentifier($table);
646+
$table = $this->quoteStringLiteral($table->getName());
643647

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

647651
/**
@@ -650,16 +654,18 @@ public function getListTableConstraintsSQL($table)
650654
public function getListTableColumnsSQL($table, $database = null)
651655
{
652656
$table = $this->normalizeIdentifier($table);
657+
$table = $this->quoteStringLiteral($table->getName());
653658

654659
$tabColumnsTableName = "user_tab_columns";
655660
$colCommentsTableName = "user_col_comments";
656661
$ownerCondition = '';
657662

658663
if (null !== $database) {
659664
$database = $this->normalizeIdentifier($database);
665+
$database = $this->quoteStringLiteral($database->getName());
660666
$tabColumnsTableName = "all_tab_columns";
661667
$colCommentsTableName = "all_col_comments";
662-
$ownerCondition = "AND c.owner = '" . $database->getName() . "'";
668+
$ownerCondition = "AND c.owner = " . $database;
663669
}
664670

665671
return "SELECT c.*,
@@ -670,7 +676,7 @@ public function getListTableColumnsSQL($table, $database = null)
670676
AND d.COLUMN_NAME = c.COLUMN_NAME
671677
) AS comments
672678
FROM $tabColumnsTableName c
673-
WHERE c.table_name = '" . $table->getName() . "' $ownerCondition
679+
WHERE c.table_name = " . $table . " $ownerCondition
674680
ORDER BY c.column_name";
675681
}
676682

@@ -1153,4 +1159,14 @@ public function getBlobTypeDeclarationSQL(array $field)
11531159
{
11541160
return 'BLOB';
11551161
}
1162+
1163+
/**
1164+
* {@inheritdoc}
1165+
*/
1166+
public function quoteStringLiteral($str)
1167+
{
1168+
$str = str_replace('\\', '\\\\', $str); // Oracle requires backslashes to be escaped aswell.
1169+
1170+
return parent::quoteStringLiteral($str);
1171+
}
11561172
}

lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ protected function initializeDoctrineTypeMappings()
7878
*/
7979
public function getCloseActiveDatabaseConnectionsSQL($database)
8080
{
81-
return "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$database'";
81+
$database = $this->quoteStringLiteral($database);
82+
83+
return "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $database";
8284
}
8385
}

lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public function getDropViewSQL($name)
318318
public function getListTableConstraintsSQL($table)
319319
{
320320
$table = new Identifier($table);
321-
$table = $table->getName();
321+
$table = $this->quoteStringLiteral($table->getName());
322322

323323
return "SELECT
324324
quote_ident(relname) as relname
@@ -327,7 +327,7 @@ public function getListTableConstraintsSQL($table)
327327
WHERE oid IN (
328328
SELECT indexrelid
329329
FROM pg_index, pg_class
330-
WHERE pg_class.relname = '$table'
330+
WHERE pg_class.relname = $table
331331
AND pg_class.oid = pg_index.indrelid
332332
AND (indisunique = 't' OR indisprimary = 't')
333333
)";
@@ -364,13 +364,14 @@ private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias
364364
$whereClause = $namespaceAlias.".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ";
365365
if (strpos($table, ".") !== false) {
366366
list($schema, $table) = explode(".", $table);
367-
$schema = "'" . $schema . "'";
367+
$schema = $this->quoteStringLiteral($schema);
368368
} else {
369369
$schema = "ANY(string_to_array((select replace(replace(setting,'\"\$user\"',user),' ','') from pg_catalog.pg_settings where name = 'search_path'),','))";
370370
}
371371

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

375376
return $whereClause;
376377
}
@@ -445,7 +446,9 @@ public function getDisallowDatabaseConnectionsSQL($database)
445446
*/
446447
public function getCloseActiveDatabaseConnectionsSQL($database)
447448
{
448-
return "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = '$database'";
449+
$database = $this->quoteStringLiteral($database);
450+
451+
return "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = $database";
449452
}
450453

451454
/**
@@ -1173,4 +1176,14 @@ public function getBlobTypeDeclarationSQL(array $field)
11731176
{
11741177
return 'BYTEA';
11751178
}
1179+
1180+
/**
1181+
* {@inheritdoc}
1182+
*/
1183+
public function quoteStringLiteral($str)
1184+
{
1185+
$str = str_replace('\\', '\\\\', $str); // PostgreSQL requires backslashes to be escaped aswell.
1186+
1187+
return parent::quoteStringLiteral($str);
1188+
}
11761189
}

lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ public function getListTableColumnsSQL($table, $database = null)
724724

725725
if (strpos($table, '.') !== false) {
726726
list($user, $table) = explode('.', $table);
727-
$user = "'" . $user . "'";
727+
$user = $this->quoteStringLiteral($user);
728728
}
729729

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

757757
if (strpos($table, '.') !== false) {
758758
list($user, $table) = explode('.', $table);
759-
$user = "'" . $user . "'";
759+
$user = $this->quoteStringLiteral($user);
760+
$table = $this->quoteStringLiteral($table);
761+
} else {
762+
$table = $this->quoteStringLiteral($table);
760763
}
761764

762765
return "SELECT con.*
763766
FROM SYS.SYSCONSTRAINT AS con
764767
JOIN SYS.SYSTAB AS tab ON con.table_object_id = tab.object_id
765-
WHERE tab.table_name = '$table'
768+
WHERE tab.table_name = $table
766769
AND tab.creator = USER_ID($user)";
767770
}
768771

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

776779
if (strpos($table, '.') !== false) {
777780
list($user, $table) = explode('.', $table);
778-
$user = "'" . $user . "'";
781+
$user = $this->quoteStringLiteral($user);
782+
$table = $this->quoteStringLiteral($table);
783+
} else {
784+
$table = $this->quoteStringLiteral($table);
779785
}
780786

781787
return "SELECT fcol.column_name AS local_column,
@@ -844,7 +850,7 @@ public function getListTableForeignKeysSQL($table)
844850
ON fk.foreign_table_id = dt.foreign_table_id
845851
AND fk.foreign_index_id = dt.foreign_key_id
846852
AND dt.event = 'D'
847-
WHERE ftbl.table_name = '$table'
853+
WHERE ftbl.table_name = $table
848854
AND ftbl.creator = USER_ID($user)
849855
ORDER BY fk.foreign_index_id ASC, idxcol.sequence ASC";
850856
}
@@ -858,7 +864,10 @@ public function getListTableIndexesSQL($table, $currentDatabase = null)
858864

859865
if (strpos($table, '.') !== false) {
860866
list($user, $table) = explode('.', $table);
861-
$user = "'" . $user . "'";
867+
$user = $this->quoteStringLiteral($user);
868+
$table = $this->quoteStringLiteral($table);
869+
} else {
870+
$table = $this->quoteStringLiteral($table);
862871
}
863872

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

0 commit comments

Comments
 (0)