-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Cache] Fix key encoding issue in Memcached adapter #38108
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
[Cache] Fix key encoding issue in Memcached adapter #38108
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR.
I understand that rawurlencode increases the length of keys, but encoding them is nonetheless required since memcached doesn't allow spaces in them, while we do.
This breaks it currently, isn't it?
src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php
Outdated
Show resolved
Hide resolved
Great point, indeed, spaces would now break. So what I did now is adding a custom encoding function that replaces memcached reserved characters with Symfony reserved characters but keep the length of the key. |
LGTM but there are some failures to investigate in Github Actions. |
@nicolas-grekas tests pass now, fixed further encoding issue. I accidentally force-pushed over your changes but restored the variable rename. I've seen that you removed the rawurlencode() for the namespace and I expanded the testcase to demonstrate why I think it’s needed. Can you elaborate on why you think it’s not needed? |
src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php
Outdated
Show resolved
Hide resolved
Thank you @lstrojny. |
Arg, github action just failed with
|
@nicolas-grekas it's a randomly failing test, try this:
From a first glimpse it looks like |
oh, then we might want to make tests resilient to this. If you want to give it a try, PR welcome :) |
@nicolas-grekas correction, it is indeed the patch. It happens when the namespace version contains a slash. This seems to me to be a violation of "internal protocol" in the sense that an adapter should expect to not deal with keys containing PSR-6 reserved characters. WDYT? |
Adapters can deal with non-psr6 chars actually. We might have a conflict with versioning then. Would using |
This would fix it:
Replacing base64 with hex makes sure that there will never be a slash |
I am not sure why previously time() and mt_rand() was used in two different places. |
I won't be able to have a look today, but please submit a PR and I will tomorrow. |
Done, see #38126 |
This PR was squashed before being merged into the 4.4 branch. Discussion ---------- [Cache] Limit cache version character range | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | n.A. | License | MIT | Doc PR | Follow up for #38108 With current HEAD in 4.4, this will fail eventually: `simple-phpunit --repeat 1000 --stop-on-failure --filter "testGetMultiple$" src/Symfony/Component/Cache/Tests/Simple/MemcachedCacheTextModeTest.php` After this PR it will no longer fail @nicolas-grekas Commits ------- 15c21db [Cache] Limit cache version character range
Because the memcached adapter uses
rawurlencode()
to encode each and every key, keys will sometimes be too long and therefore hit the memcached limit of 250 bytes. This happens when the key is small enough to be below 250 when passed toAbstractAdapterTrait::getId()
and is then blown up over the 250 bytes limit in memcached adapter without validating the length again.Looking through the code, it seems that the double encoding is wholly unnecessary assuming if one makes sure the namespace is properly encoded. This PR therefore removes the double encoding and instead uses rawurlencode on the namespace (which is in turn properly accounted for when calculating whether or not we are over the ID limit).