Repository navigation
[3.0][Testing] Case insensitive comparisons (part 2 of 2) — guard the convention in the unit suite - #9597
Merged
jdarwood007 merged 5 commits intoOct 4, 2026
Conversation
This was referenced Aug 31, 2026
albertlast
force-pushed
the
3.0/tests-ci-token-guard
branch
from
September 2, 2026 06:07
27b4337 to
0df2a14
Compare
albertlast
force-pushed
the
3.0/tests-ci-token-guard
branch
from
September 3, 2026 14:06
0df2a14 to
bd84584
Compare
This was referenced Sep 29, 2026
Member
|
Can this get a rebase? |
A LIKE against text a person typed has to say whether it folds case, because
the engines disagree about it. Written as a bare column it says nothing, and
the query then matches on MySQL and not on PostgreSQL. That failure returns
fewer rows instead of erroring, so it reaches neither the error log nor CI.
This counts, per file, the comparisons on the columns holding names, email
addresses and hostnames that do not fold case in the query text, and holds the
count against a baseline. A new one fails the suite and names the file; fixing
an old one means lowering its number in the same commit.
The scan covers LIKE only. `member_name = {string:name}` and
`$member_name = $string` are the same line to a scanner, and the SET clause of
an UPDATE looks like both, so equality is left out rather than guessed at.
The two comparisons in Security.php are folded by the 'ban_like' identifier at
the point the query runs rather than in the query text, so they stay in the
list with a note saying why.
Reading every file under Sources costs about 60ms on a normal filesystem.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
Folding one side is worse than folding neither. A folded column can never equal
an unfolded value, so rather than matching too much on PostgreSQL the comparison
matches nothing at all, including the row it was looking for. It is also the
harder one to see, because the query says {ci:} and reads as handled.
The first scan cannot find these, by construction: it treats {ci:} as proof that
a decision was made. So a second scan lists the comparisons that fold a column
while comparing it against a value the query leaves alone. Those are correct
only when the caller folded the value in PHP, which is a claim about code
elsewhere, so the list names which callers do and which do not.
This one reads equality as well as LIKE. A line carrying {ci:} is SQL, so an =
on it is a comparison rather than a PHP assignment, which is what put equality
out of reach of the first scan.
Five of the eleven entries are known faults: Register2.php and Profile.php are
SimpleMachines#9594, and PersonalMessage/Search.php is the same fault in the search for a
personal message by its author.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
{ci_string} became {string_ci} and gained {array_string_ci}, so the scan that
decides whether a comparison declares its case handling has to recognise both.
User.php leaves the second list as a result. It hands its names to
{array_string_ci:}, which folds every value in the list, so the comparison no
longer folds one side only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
{ci:} became {column_ci:}, so the scan that decides whether a comparison
declares its case handling has to look for the new spelling. Getting this wrong
fails loudly rather than quietly: every converted call site would stop looking
folded at once, and the baseline would grow by all of them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
SimpleMachines#9633 moved the email comparisons in Bans.php, Register2.php and Profile.php onto the casefolded email_address_ci column, which closed SimpleMachines#9592 and SimpleMachines#9594. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
albertlast
force-pushed
the
3.0/tests-ci-token-guard
branch
from
October 4, 2026 14:59
bd84584 to
2143b6c
Compare
Collaborator
Author
|
Rebased onto There is one new commit on top. The guard test failed after the rebase, and in the direction it is meant to: #9633 moved the email comparisons in The unit suite passes and php-cs-fixer is clean on the file. I've updated the description to match. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
Part 1 (#9596) gives a comparison a way to say whether it folds case. This is what notices when
one does not say. What makes it worth a test rather than a review habit is the failure
mode: a case sensitive comparison returns fewer rows instead of erroring, so nothing
reaches
smf_log_errors, nothing fails in CI, and the first person to notice is a memberwhose search came back empty. #9592 and #9593 both sat in the tree for years.
There are two ways to get this wrong, so there are two scans.
1. Folding neither side. The comparison relies on the collation, which folds on MySQL
and does not on PostgreSQL. Counted per file against a baseline:
Three are #9593. The two in
Security.phpare folded by theban_likeidentifier when thequery runs rather than in the query text, and the one in
Bans.phpcomparesemail_address_ciagainst a ban's email pattern, which is stored casefolded. Those threestay listed with a note saying why.
This scan reads
LIKEonly.member_name = {string:name}and$member_name = $stringare the same line to a scanner, and an
UPDATE ... SETclause looks like both; guessingwould produce a baseline of about fifty entries that are mostly PHP assignments, which is
a test people learn to ignore.
2. Folding only the column. This is the worse one, and it is why the second scan
exists. A folded column can never equal an unfolded value, so instead of matching too much
the comparison matches nothing at all on PostgreSQL — including the row it was looking
for. It also hides, because the query says
{column_ci:}and reads as handled. The first scancannot find these by construction: it treats
{column_ci:}as proof a decision was made.These are correct only when the caller folds the value in PHP first, which is a claim
about code elsewhere, so the list names which callers do and which do not. Five do.
Two do not, and are a fault:
PersonalMessage/Search.php, in the search for a personalmessage by its author, which is #9598.
This scan reads equality as well as
LIKE, which the first cannot. A line carrying{column_ci:}is SQL, so an=on it is a comparison rather than an assignment — which is how#9594 came into range before #9633 fixed it.
Sources/User.phpleft this list when #9596 gained{array_string_ci:}, which folds everyvalue in an
INlist, so that comparison folds both sides now.Confirmed to fail when it should. Adding
'WHERE real_name LIKE {string:x}'toSources/Actions/Groups.php:It also fails when a count goes down, which is what happened on the rebase: #9633 moved the
email comparisons in
Bans.php,Register2.phpandProfile.phpontoemail_address_ci,and the test asked for its baselines to be lowered to match. That is the last commit here.
A third test asserts both scans find something, so that emptying either one does not leave
the tests above passing against an empty baseline.
Neither scan asserts anything about behaviour, so this is not a substitute for the fixes.
It stops the lists growing while they are worked through, and lowering a number is the
point of them rather than a chore attached to them.
Reading every file under
Sources/costs about 60ms on a normal filesystem.It is slower over a Docker bind mount on Windows, which is a local artifact.
Issues References (Fixes|Related|Closes)
{column_ci:}type this guards the use of🤖 Generated with Claude Code