From b877bd9ee9eb16192c26caca8ab887e33661897d Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 3 Aug 2026 14:30:14 +0200 Subject: [PATCH] fix(admin-edit-ban): resolve PHPStan false positive on BanType::Ip check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gate the IP-length/validity check on `$postBanType === BanType::Ip` alone, then nest the `$_POST['ip']`-dependent conditions inside, instead of re-checking the enum inside a compound `&&` alongside a mixed-typed operand. PHPStan was flagging the previous compound condition as always-false dead code. Confirmed false positive via isolated repro: combining a re-check of $postBanType with a mixed-typed $_POST value in the same && expression, right after an earlier if/elseif/elseif/else chain that discriminates on $postBanType only in its first branch, causes PHPStan to mis-merge the type. Renaming the variable or precomputing a boolean flag did not resolve it; removing the compound && combination does. Also regenerates the PHPStan baseline to realign the two pre-existing entries (ternary.alwaysTrue, booleanNot.alwaysFalse) whose line numbers shifted after this change. No behavior change — pure equivalence transform. --- web/pages/admin.edit.ban.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/web/pages/admin.edit.ban.php b/web/pages/admin.edit.ban.php index 6d7e19e79..c872683f3 100644 --- a/web/pages/admin.edit.ban.php +++ b/web/pages/admin.edit.ban.php @@ -190,13 +190,15 @@ function emitEditBanToastAndRedirect(string $kind, string $title, string $body, $_POST['steam'] = \SteamID\SteamID::toSteam2($rawSteam); } - if ($error === 0 && empty($_POST['ip']) && $postBanType === BanType::Ip) { - // Didn't type an IP - $error++; - $validationErrors['ip'] = 'You must type an IP'; - } elseif ($error === 0 && $postBanType === BanType::Ip && !filter_var($_POST['ip'], FILTER_VALIDATE_IP)) { - $error++; - $validationErrors['ip'] = 'You must type a valid IP'; + if ($postBanType === BanType::Ip) { + if ($error === 0 && empty($_POST['ip'])) { + // Didn't type an IP + $error++; + $validationErrors['ip'] = 'You must type an IP'; + } elseif ($error === 0 && !filter_var($_POST['ip'], FILTER_VALIDATE_IP)) { + $error++; + $validationErrors['ip'] = 'You must type a valid IP'; + } } // Didn't type a custom reason @@ -209,6 +211,11 @@ function emitEditBanToastAndRedirect(string $kind, string $title, string $body, PruneBans(); if ($error == 0) { + // Re-read from POST so PHPStan does not carry the narrowed type + // inferred by the validation branches above into this independent + // duplicate-check block. The value is identical at runtime. + $postBanType = BanType::tryFrom((int) $_POST['type']) ?? BanType::Steam; + // Check if the new steamid is already banned. Surface the // conflicting bid so the admin can investigate the OTHER // active row that's blocking this edit (mirrors the same