From dadd253a209189a074cdb0948907aa137e00a3ed Mon Sep 17 00:00:00 2001 From: Guillaume Smaha Date: Fri, 15 Jan 2016 13:36:05 +0100 Subject: [PATCH] Fix #3476: Database sessions with Postgres did not work properly close #4004 --- CHANGELOG | 1 + framework/db/CDbConnection.php | 19 +++++++++++++++++++ framework/web/CDbHttpSession.php | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index a0e0f4226..f66ae0e36 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ Version 1.1.18 under development - Enh #2819: backported masking of CSRF tokens from Yii 2.0 (samdark) - Enh #4049: Added '//' as a proper beginning of absolute URL in createAbsoluteUrl() method (ksowa) - Enh #4075: Added CClientScript::hasPackage() (samdark) +- Bug #4004: Better fix for PostgreSQL Session storage (GuillaumeSmaha) - Bug #4015: Fixed bug with missing "disabled" attribute in internally rendered hidden fields (rob006) - Bug #4020: Fixed PHP 7 related bug in CCacheHttpSession when destroying not cached sessions (dirx) - Bug #4034: Fixed `CHttpSession::getIsStarted()` PHP 7 compatibility (tomotomo) diff --git a/framework/db/CDbConnection.php b/framework/db/CDbConnection.php index 3fd88d833..05e44e244 100644 --- a/framework/db/CDbConnection.php +++ b/framework/db/CDbConnection.php @@ -582,6 +582,25 @@ class CDbConnection extends CApplicationComponent return "'" . addcslashes(str_replace("'", "''", $str), "\000\n\r\\\032") . "'"; } + /** + * Quotes a value for use in a query using a given type. + * @param mixed $value the value to be quoted. + * @param integer $type The type to be used for quoting. + * This should be one of the `PDO::PARAM_*` constants described in + * {@link http://www.php.net/manual/en/pdo.constants.php PDO documentation}. + * This parameter will be passed to the `PDO::quote()` function. + * @return string the properly quoted string. + * @see http://www.php.net/manual/en/function.PDO-quote.php + */ + public function quoteValueWithType($value, $type) + { + $this->setActive(true); + if(($quoted=$this->_pdo->quote($value, $type))!==false) + return $quoted; + else // the driver doesn't support quote (e.g. oci) + return "'" . addcslashes(str_replace("'", "''", $value), "\000\n\r\\\032") . "'"; + } + /** * Quotes a table name for use in a query. * If the table name contains schema prefix, the prefix will also be properly quoted. diff --git a/framework/web/CDbHttpSession.php b/framework/web/CDbHttpSession.php index 3e5ea0624..0f21f4425 100644 --- a/framework/web/CDbHttpSession.php +++ b/framework/web/CDbHttpSession.php @@ -247,7 +247,7 @@ class CDbHttpSession extends CHttpSession $expire=time()+$this->getTimeout(); $db=$this->getDbConnection(); if($db->getDriverName()=='pgsql') - $data=new CDbExpression("convert_to(".$db->quoteValue($data).", 'UTF8')"); + $data=new CDbExpression($db->quoteValueWithType($data, PDO::PARAM_LOB)."::bytea"); if($db->getDriverName()=='sqlsrv' || $db->getDriverName()=='mssql' || $db->getDriverName()=='dblib') $data=new CDbExpression('CONVERT(VARBINARY(MAX), '.$db->quoteValue($data).')'); if($db->createCommand()->select('id')->from($this->sessionTableName)->where('id=:id',array(':id'=>$id))->queryScalar()===false)