Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[HttpFoundation] Use the correct syntax for session gc based on Pdo driver #25922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

tanasecosminromeo
Copy link
Contributor

Q A
Branch? master
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #25665 #24456
License MIT
Doc PR

The initial fix for #24456 was wrong, since it only accounted for Postgres. @WhiteEagle88 correctly identified #25665 - but having time as SIGNED is ... off, since time shouldn't be negative. Using CAST to solve this issue surely has a performance penalty, so I believe the best approach is to have a switch based on the driver.

…n Pdo driver

The initial fix for symfony#24456 was wrong, since it only accounted for Postgres. @WhiteEagle88 correctly identified symfony#25665 - but having time as SIGNED is ... off, since time shouldn't be negative. Using CAST to solve this issue surely has a performance penalty, so I believe the best approach is to have a switch based on the driver.
@nicolas-grekas
Copy link
Member

Thanks for the PR. Why do we need to have a switch? Can't we just use the version with the + all the time? Any downside doing so ?

@tanasecosminromeo
Copy link
Contributor Author

@nicolas-grekas According to #24456 the version with a + breaks Postgres. I haven't tested myself but it seems likely. Unfortunately the fix for #24456 breaks MySQL. I have noticed the issue myself in production using Percona and it was confirmed in #25665 - We could use an if or a short if, but I think this way it's more clear.

Would be worthwhile to test sqlite driver as well.

@nicolas-grekas
Copy link
Member

OK thanks. I think an if/else would be better in fact :) also note that we use four-spaces indentation.
Can you add a comment meanwhile to hint why mysql needs special care (but no link to github, we don't add these).
Thanks

@nicolas-grekas nicolas-grekas changed the title Fix bug #25665 - Use the correct syntax for session gc based on Pdo driver [HttpFoundation] Use the correct syntax for session gc based on Pdo driver Jan 25, 2018
@nicolas-grekas nicolas-grekas added this to the 2.7 milestone Jan 25, 2018
@tanasecosminromeo
Copy link
Contributor Author

Issue

Because MySQL cast the result of this expression to unsigned types when doing sess_lifetime < time() - sess_time an out of range exception is thrown by MySQL when the PDOSessionHandler is closing a session and does garbage collection.

MySQL Exception Example from Production (percona:5.6)

request.CRITICAL: Uncaught PHP Exception PDOException: "SQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(1516801382 - ***.sessions.sess_time)'" at /code/vendor/symfony/symfony/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php line 382

How to replicate

Using an MySQL Server (replicated with mysql:latest, percona:latest and percona:5.6) create a custom PdoSessionHandler - force garbage collection when session is closed and set time time to 1 day ago and simply make a request. This is a valid replication as in a production environment I had the above error without a custom Handler and these changes just force the circumstances creating the bug to appear, you just have to match the garbage collection with having a session that needs collecting

PdoSessionHandler.php:374
if ($this->gcCalled || true) {

PdoSessionHandler.php:381
$stmt->bindValue(':time', strtotime('-1 day'), \PDO::PARAM_INT);

Why was the initial fix working for Postgres:latest**

If you used lifetime sessions you could end up with the issue below.

[SQL]INSERT INTO sessions VALUES ('test-id1', 'data', 2147483647, 1440);
DELETE FROM sessions WHERE sess_lifetime + sess_time < 1509428343;

[Err] ERROR: integer out of range

Conclusion

I personally wouldn't add session time as MAXINT, but it does make sense if you want to have an unlimited session and the fix works fine in this case, but breaks normal functionality in MySQL/Percona.

Thank you Nicolas, will use an if and change indentation. Sorry for this and for the long message 😄

… driver with if && change to four space indentation
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(for 2.7)

@fabpot
Copy link
Member

fabpot commented Jan 29, 2018

Thank you @tanasecosminromeo.

@fabpot fabpot closed this Jan 29, 2018
fabpot added a commit that referenced this pull request Jan 29, 2018
…ed on Pdo driver (tanasecosminromeo)

This PR was submitted for the master branch but it was squashed and merged into the 2.7 branch instead (closes #25922).

Discussion
----------

[HttpFoundation] Use the correct syntax for session gc based on Pdo driver

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #25665 #24456
| License       | MIT
| Doc PR        |

The initial fix for #24456 was wrong, since it only accounted for Postgres. @WhiteEagle88 correctly identified #25665 - but having time as SIGNED is ... off, since time shouldn't be negative. Using CAST to solve this issue surely has a performance penalty, so I believe the best approach is to have a switch based on the driver.

Commits
-------

826dfbd [HttpFoundation] Use the correct syntax for session gc based on Pdo driver
@fabpot fabpot mentioned this pull request Jan 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants