PdoSessionHandler: fix advisory lock for pgsql when session.sid_bits_per_character > 4
This commit is contained in:
parent
e4d9bfd245
commit
0f0a6e85e3
|
@ -580,11 +580,11 @@ class PdoSessionHandler implements \SessionHandlerInterface
|
|||
return $releaseStmt;
|
||||
case 'pgsql':
|
||||
// Obtaining an exclusive session level advisory lock requires an integer key.
|
||||
// So we convert the HEX representation of the session id to an integer.
|
||||
// Since integers are signed, we have to skip one hex char to fit in the range.
|
||||
if (4 === PHP_INT_SIZE) {
|
||||
$sessionInt1 = hexdec(substr($sessionId, 0, 7));
|
||||
$sessionInt2 = hexdec(substr($sessionId, 7, 7));
|
||||
// When session.sid_bits_per_character > 4, the session id can contain non-hex-characters.
|
||||
// So we cannot just use hexdec().
|
||||
if (4 === \PHP_INT_SIZE) {
|
||||
$sessionInt1 = $this->convertStringToInt($sessionId);
|
||||
$sessionInt2 = $this->convertStringToInt(substr($sessionId, 4, 4));
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key1, :key2)');
|
||||
$stmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
|
||||
|
@ -595,7 +595,7 @@ class PdoSessionHandler implements \SessionHandlerInterface
|
|||
$releaseStmt->bindValue(':key1', $sessionInt1, \PDO::PARAM_INT);
|
||||
$releaseStmt->bindValue(':key2', $sessionInt2, \PDO::PARAM_INT);
|
||||
} else {
|
||||
$sessionBigInt = hexdec(substr($sessionId, 0, 15));
|
||||
$sessionBigInt = $this->convertStringToInt($sessionId);
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT pg_advisory_lock(:key)');
|
||||
$stmt->bindValue(':key', $sessionBigInt, \PDO::PARAM_INT);
|
||||
|
@ -613,6 +613,27 @@ class PdoSessionHandler implements \SessionHandlerInterface
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the first 4 (when PHP_INT_SIZE == 4) or 8 characters of the string as an integer.
|
||||
*
|
||||
* Keep in mind, PHP integers are signed.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function convertStringToInt($string)
|
||||
{
|
||||
if (4 === \PHP_INT_SIZE) {
|
||||
return (ord($string[3]) << 24) + (ord($string[2]) << 16) + (ord($string[1]) << 8) + ord($string[0]);
|
||||
}
|
||||
|
||||
$int1 = (ord($string[7]) << 24) + (ord($string[6]) << 16) + (ord($string[5]) << 8) + ord($string[4]);
|
||||
$int2 = (ord($string[3]) << 24) + (ord($string[2]) << 16) + (ord($string[1]) << 8) + ord($string[0]);
|
||||
|
||||
return $int2 + ($int1 << 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a locking or nonlocking SQL query to read session information.
|
||||
*
|
||||
|
|
Reference in New Issue