Add encoding to file lock names #40330
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description (*)
This pull request was created to address for Magento instances using the
filelock provider. If a lock name contains characters that are forbidden for file names (e.g.,/on Unix-like systems), the operating system will fail to create the lock file, leading to aFileSystemExceptionbeing thrown.There are instances where the system attempts to acquire a lock using a string that can contain these forbidden characters. An example includes:
app/code/Magento/Catalog/Plugin/ProductRepositorySaveOperationSynchronizer.php::aroundSave(). This plugin wraps calls to product saves in aProductMutex, which is implemented using a lock, and the name of that lock is determined by the product SKU. The product SKU attribute has no restriction that makes the/character forbidden.To address this limitation, I have introduced file lock name encoding. I chose
rawurlencode()for a few reasons:It is an injective algorithm, so naming collisions are impossible.
It is human readable, so users that wish to monitor the lock directory have a relatively unchanged experience.
Easy to decode using
rawurldecode().Encodes forbidden characters on Unix-like operating systems, as well as Windows.
/<>:"/\|?*%is valid for both types of systems.Implementation details
rawurlencode()withinMagento\Framework\Lock\Backend\FileLock::getLockPath().lock(),unlock(), andisLocked()methods because they all utilize the updatedgetLockPath()method.cleanupOldLocks()method was also updated to userawurldecode()before checking lock status, preventing issues where double-encoded paths would prevent detection of active locks or deletion of encoded lock files.Manual testing scenarios (*)
productsendpoint. In the request body, ensure that a/is present in theskuattribute:400.200(success).Questions or comments
I acknowledge that
rawurlencode()might not be the optimal encoding mechanism in this scenario. I would argue it is good for this scenario, but I do not claim to be an expert on methods of encoding text. If anyone has a better idea, or concerns with this encoding method, please feel free to let me know!Per the Adobe Commerce documentation, Windows is not supported, but I am not 100% sure if this applies to new versions of Magento Open Source as well. If Windows is not supported, I could potentially devise a more simple encoding scheme that just handles
/. For extra clarification, I did all development & testing on Linux.I am a bit concerned with how backwards compatible this change might be. If the deployment occurs while a long-lasting lock is active, the new code will miss the existing lock if it's encoded name is different from it's current name.
Finally, this is my first contribution to Magento Open Source. I did my best to follow the contribution guidelines, but it's very possible I did something wrong. Please let me know so I can do better next time.
Contribution checklist (*)
Resolved issues: