Unverified Commit 94ba9d74 authored by Marco Pivetta's avatar Marco Pivetta Committed by GitHub

Merge pull request #3317 from morozov/platforms-literal-escaping

Implemented proper escaping of string literals in platforms and schema managers
parents 82fd5d66 423b03d5
......@@ -326,15 +326,15 @@ class DrizzlePlatform extends AbstractPlatform
public function getListTableColumnsSQL($table, $database = null)
{
if ($database) {
$database = "'" . $database . "'";
$databaseSQL = $this->quoteStringLiteral($database);
} else {
$database = 'DATABASE()';
$databaseSQL = 'DATABASE()';
}
return 'SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT, IS_NULLABLE, IS_AUTO_INCREMENT, CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT,' .
' NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME' .
' FROM DATA_DICTIONARY.COLUMNS' .
' WHERE TABLE_SCHEMA=' . $database . " AND TABLE_NAME = '" . $table . "'";
' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME = ' . $this->quoteStringLiteral($table);
}
/**
......@@ -343,14 +343,14 @@ class DrizzlePlatform extends AbstractPlatform
public function getListTableForeignKeysSQL($table, $database = null)
{
if ($database) {
$database = "'" . $database . "'";
$databaseSQL = $this->quoteStringLiteral($database);
} else {
$database = 'DATABASE()';
$databaseSQL = 'DATABASE()';
}
return 'SELECT CONSTRAINT_NAME, CONSTRAINT_COLUMNS, REFERENCED_TABLE_NAME, REFERENCED_TABLE_COLUMNS, UPDATE_RULE, DELETE_RULE' .
' FROM DATA_DICTIONARY.FOREIGN_KEYS' .
' WHERE CONSTRAINT_SCHEMA=' . $database . " AND CONSTRAINT_TABLE='" . $table . "'";
' WHERE CONSTRAINT_SCHEMA=' . $databaseSQL . ' AND CONSTRAINT_TABLE=' . $this->quoteStringLiteral($table);
}
/**
......@@ -359,14 +359,14 @@ class DrizzlePlatform extends AbstractPlatform
public function getListTableIndexesSQL($table, $database = null)
{
if ($database) {
$database = "'" . $database . "'";
$databaseSQL = $this->quoteStringLiteral($database);
} else {
$database = 'DATABASE()';
$databaseSQL = 'DATABASE()';
}
return "SELECT INDEX_NAME AS 'key_name', COLUMN_NAME AS 'column_name', IS_USED_IN_PRIMARY AS 'primary', IS_UNIQUE=0 AS 'non_unique'" .
' FROM DATA_DICTIONARY.INDEX_PARTS' .
' WHERE TABLE_SCHEMA=' . $database . " AND TABLE_NAME='" . $table . "'";
' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME=' . $this->quoteStringLiteral($table);
}
/**
......
......@@ -439,7 +439,7 @@ SQL
*/
public function getDisallowDatabaseConnectionsSQL($database)
{
return "UPDATE pg_database SET datallowconn = 'false' WHERE datname = '" . $database . "'";
return "UPDATE pg_database SET datallowconn = 'false' WHERE datname = " . $this->quoteStringLiteral($database);
}
/**
......
......@@ -27,7 +27,7 @@ class DB2SchemaManager extends AbstractSchemaManager
public function listTableNames()
{
$sql = $this->_platform->getListTablesSQL();
$sql .= " AND CREATOR = UPPER('" . $this->_conn->getUsername() . "')";
$sql .= ' AND CREATOR = UPPER(' . $this->_conn->quote($this->_conn->getUsername()) . ')';
$tables = $this->_conn->fetchAll($sql);
......
......@@ -117,15 +117,9 @@ class SqliteSchemaManager extends AbstractSchemaManager
$tableForeignKeys = $this->_conn->fetchAll($sql);
if (! empty($tableForeignKeys)) {
$createSql = $this->_conn->fetchAll(
sprintf(
"SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type = 'table' AND name = '%s'",
$table
)
);
$createSql = $createSql[0]['sql'] ?? '';
$createSql = $this->getCreateTableSQL($table);
if (preg_match_all(
if ($createSql !== null && preg_match_all(
'#
(?:CONSTRAINT\s+([^\s]+)\s+)?
(?:FOREIGN\s+KEY[^\)]+\)\s*)?
......@@ -174,9 +168,10 @@ class SqliteSchemaManager extends AbstractSchemaManager
$indexBuffer = [];
// fetch primary
$stmt = $this->_conn->executeQuery(
sprintf("PRAGMA TABLE_INFO ('%s')", $tableName)
);
$stmt = $this->_conn->executeQuery(sprintf(
'PRAGMA TABLE_INFO (%s)',
$this->_conn->quote($tableName)
));
$indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE);
usort($indexArray, static function ($a, $b) {
......@@ -212,9 +207,10 @@ class SqliteSchemaManager extends AbstractSchemaManager
$idx['primary'] = false;
$idx['non_unique'] = $tableIndex['unique']?false:true;
$stmt = $this->_conn->executeQuery(
sprintf("PRAGMA INDEX_INFO ('%s')", $keyName)
);
$stmt = $this->_conn->executeQuery(sprintf(
'PRAGMA INDEX_INFO (%s)',
$this->_conn->quote($keyName)
));
$indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE);
foreach ($indexArray as $indexColumnRow) {
......@@ -272,13 +268,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
}
// inspect column collation and comments
$createSql = $this->_conn->fetchAll(
sprintf(
"SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type = 'table' AND name = '%s'",
$table
)
);
$createSql = $createSql[0]['sql'] ?? '';
$createSql = $this->getCreateTableSQL($table) ?? '';
foreach ($list as $columnName => $column) {
$type = $column->getType();
......@@ -488,4 +478,24 @@ class SqliteSchemaManager extends AbstractSchemaManager
return $comment === '' ? null : $comment;
}
private function getCreateTableSQL(string $table) : ?string
{
return $this->_conn->fetchColumn(
<<<'SQL'
SELECT sql
FROM (
SELECT *
FROM sqlite_master
UNION ALL
SELECT *
FROM sqlite_temp_master
)
WHERE type = 'table'
AND name = ?
SQL
,
[$table]
) ?: null;
}
}
......@@ -30,7 +30,7 @@ final class DB2SchemaManagerTest extends TestCase
$platform = $this->createMock(DB2Platform::class);
$this->conn = $this
->getMockBuilder(Connection::class)
->setMethods(['fetchAll'])
->setMethods(['fetchAll', 'quote'])
->setConstructorArgs([['platform' => $platform], $driverMock, new Configuration(), $eventManager])
->getMock();
$this->manager = new DB2SchemaManager($this->conn);
......@@ -102,6 +102,7 @@ final class DB2SchemaManagerTest extends TestCase
$this->conn->getConfiguration()->setSchemaAssetsFilter(static function ($assetName) use ($accepted) {
return in_array($assetName, $accepted);
});
$this->conn->expects($this->any())->method('quote');
$this->conn->expects($this->once())->method('fetchAll')->will($this->returnValue([
['name' => 'FOO'],
['name' => 'T_FOO'],
......@@ -129,6 +130,7 @@ final class DB2SchemaManagerTest extends TestCase
$this->conn->getConfiguration()->setSchemaAssetsFilter(static function ($assetName) use ($accepted) {
return in_array($assetName, $accepted);
});
$this->conn->expects($this->any())->method('quote');
$this->conn->expects($this->atLeastOnce())->method('fetchAll')->will($this->returnValue([
['name' => 'FOO'],
['name' => 'T_FOO'],
......
Markdown is supported
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