Commit 92339463 authored by alexpott's avatar alexpott

Issue #2726747 by DuaelFr: pgsql improperly escape table names leading to a fatal error

parent fbe287dc
......@@ -210,13 +210,8 @@ public function escapeField($field) {
// need to be escaped.
$escaped = $this->escapeTable($table) . '.' . $this->escapeAlias($column);
}
elseif (preg_match('/[A-Z]/', $escaped)) {
// Quote the field name for case-sensitivity.
$escaped = '"' . $escaped . '"';
}
elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
// Quote the field name for PostgreSQL reserved key words.
$escaped = '"' . $escaped . '"';
else {
$escaped = $this->doEscape($escaped);
}
return $escaped;
......@@ -227,16 +222,7 @@ public function escapeField($field) {
*/
public function escapeAlias($field) {
$escaped = preg_replace('/[^A-Za-z0-9_]+/', '', $field);
// Escape the alias in quotes for case-sensitivity.
if (preg_match('/[A-Z]/', $escaped)) {
$escaped = '"' . $escaped . '"';
}
elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
// Quote the alias name for PostgreSQL reserved key words.
$escaped = '"' . $escaped . '"';
}
$escaped = $this->doEscape($escaped);
return $escaped;
}
......@@ -246,16 +232,33 @@ public function escapeAlias($field) {
public function escapeTable($table) {
$escaped = parent::escapeTable($table);
// Ensure that each part (database, schema and table) of the table name is
// properly and independently escaped.
$parts = explode('.', $escaped);
$parts = array_map([$this, 'doEscape'], $parts);
$escaped = implode('.', $parts);
return $escaped;
}
/**
* Escape a string if needed.
*
* @param $string
* The string to escape.
* @return string
* The escaped string.
*/
protected function doEscape($string) {
// Quote identifier to make it case-sensitive.
if (preg_match('/[A-Z]/', $escaped)) {
$escaped = '"' . $escaped . '"';
if (preg_match('/[A-Z]/', $string)) {
$string = '"' . $string . '"';
}
elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
// Quote the table name for PostgreSQL reserved key words.
$escaped = '"' . $escaped . '"';
elseif (in_array(strtolower($string), $this->postgresqlReservedKeyWords)) {
// Quote the string for PostgreSQL reserved key words.
$string = '"' . $string . '"';
}
return $escaped;
return $string;
}
public function driver() {
......
......@@ -40,6 +40,11 @@ public function providerEscapeTables() {
array('"camelCase"', 'camelCase'),
array('"camelCase"', '"camelCase"'),
array('"camelCase"', 'camel/Case'),
// Sometimes, table names are following the pattern database.schema.table.
array('"camelCase".nocase.nocase', 'camelCase.nocase.nocase'),
array('nocase."camelCase".nocase', 'nocase.camelCase.nocase'),
array('nocase.nocase."camelCase"', 'nocase.nocase.camelCase'),
array('"camelCase"."camelCase"."camelCase"', 'camelCase.camelCase.camelCase'),
);
}
......
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