-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
FIX 17.0 - collisions in cache for dol_getIdFromCode #32621
FIX 17.0 - collisions in cache for dol_getIdFromCode #32621
Conversation
Note: I do have the pre-commit hook enabled, so I don't understand why it fails here (especially as it fails on the very whitespace changes that my local pre-commit hook forced me to make). I'll check that my pre-commit hook is up to date. |
@atm-florianm just replace the word "Overide" by "Override" |
@atm-florianm otherwise you will get scolded by @mdeweerd 😄 |
@hregis Thanks! The typo was already there, though. But I guess my old pre-commit changed whitespace on the lines where it appeared. |
htdocs/core/lib/functions.lib.php
Outdated
{ | ||
global $cache_codes; | ||
static $cache_codes = array(); |
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.
Why using static instead of global ?
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.
It avoids overcrowding the global namespace and ensures the variable stays private (can't be read or written from the outside, which can be good or bad depending on the situation). I saw that in v21, this variable is replaced with $conf->cache
, which I assume is used by other functions, so in this regard, a global variable makes more sense.
Feel free to revert this line.
'scolded' is a big word, codespell does the job ! I explain why, and @hregis you are clearly progressing. @atm-florianm The php-lint issues you are having depend as far as I remember on the local php version you have installed. php -l htdocs/includes/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDO.php Lists several notices and one fatal error for me with PHP 8.2.12 . FYI, this is my local.sh script called by pre-commit (I still use cygwin, but you can get ideas from it). #!/bin/bash
#exit 0
MYDIR=$(dirname "$0")
if [ -r "$MYDIR/dev/tools/updatelicense.php" ] ; then
git diff --name-only HEAD ':!*/includes/*' ':!htdocs/modulebuilder/template/*' | sort -u | xargs -r "$MYDIR/dev/tools/updatelicense.php"
elif [ -r "$MYDIR/dev/tools/fixcopyrightheader.php" ] ; then
git diff --name-only HEAD ':!*/includes/*' ':!htdocs/modulebuilder/template/*' | sort -u | xargs -r "$MYDIR/dev/tools/fixcopyrightheader.php"
fi
paths=()
for f in "$MYDIR/flow/"* "$MYDIR/flow/".* ; do
if [ "$(basename "$f")" = ".pre-commit-config.yaml" ] ; then continue ; fi
if [ "$(basename "$f")" = ".codespellrc" ] ; then continue ; fi
if [ ! -r "${MYDIR}/$(basename "$f")" ] ; then
echo cp "$f" "${MYDIR}/$(basename "$f")"
cp "$f" "${MYDIR}/$(basename "$f")"
fi
done
for f in $(git diff --name-only HEAD ':*.php' ':!*/includes/*' | sort -u) ; do
echo "Fix '$f'"
paths+=( "$(cygpath -w "$f")" )
phpcbf "$(cygpath -w "$f")"
php-cs-fixer fix "$(cygpath -w "$f")"
done
for f in $(git diff --name-only HEAD ':*.sql' ':!*/includes/*') ; do
sqlfluff fix --rules CP01 --exclude-rules CP02 "$f"
done
#git diff --name-only HEAD ':*.php' ':!*/includes/*' | xargs -r
if [ "${#paths}" != 0 ] ; then
phpcbf "${paths[@]}"
fi |
Using the develop version for the violating file will fix pre-commit, if acceptable for 17.0:
|
I've opened a separate PR: #32651 to avoid mixing changes that addresses the initial issue with code changes that only address checks from the GitHub workflow. |
FIX cache collisions
The cache mechanism of this function is sometimes broken because it doesn't store all query parameters, resulting in collisions. In practice, this can mean that the wrong value will be returned.
In practice, there are not many cases where this bug will manifest itself, but it will occur in scripts that process similar data across multiple entities.
Minimal case for reproducing:
Here is the output I get:
Analysis
This occurs because the functions enables the user to use 6 querying parameters, but only 3 are part of the cache key, meaning that if you change any of the 3 remaining parameters, you will get results from the cache even though they don't match all your criteria.
My proposed solution is to use all 6 parameters as keys. I am aware that this could be wasteful in some cases (because the same result will be stored twice if, for instance, you use two totally equivalent but different filters in
$filter
. However, this will at least return the expected result.In addition, an optional parameter allows the programmers to skip the cache entirely. This parameter is new, but it won't break backward compatibility since it has a default value and up to the current
develop
branch, there are no other new parameters.