From 5101b1361d147315ca8a6cc32ccb3b75ac0b7506 Mon Sep 17 00:00:00 2001 From: reverse Date: Wed, 19 Aug 2026 01:58:01 +0000 Subject: [PATCH] =?UTF-8?q?whois:=20build=20the=20target=20snapshot=20as?= =?UTF-8?q?=20a=20named=20WhoisInfo=20struct=20instead=20of=20a=2017-field?= =?UTF-8?q?=20positional=20tuple=20=E2=80=94=20field-named=20construction?= =?UTF-8?q?=20can't=20silently=20transpose=20two=20same-typed=20fields;=20?= =?UTF-8?q?destructured=20into=20the=20same=20locals=20so=20the=20reply=20?= =?UTF-8?q?code=20is=20unchanged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/coremods/core_info.rs | 64 ++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/src/coremods/core_info.rs b/src/coremods/core_info.rs index 07937b3..59f2119 100644 --- a/src/coremods/core_info.rs +++ b/src/coremods/core_info.rs @@ -180,7 +180,28 @@ impl Command for Whois { // hidewhois: hide sensitive lines from ordinary users (opers/self exempt per config) let hide = crate::modules::hidewhois::hide(s, uid, tuid, asker_oper); let keys: Vec = s.users[&tuid].channels.iter().cloned().collect(); - let ( + // A named snapshot of the target for the WHOIS reply — a struct rather than a + // 17-field positional tuple, so construction can't silently transpose fields. + struct WhoisInfo { + nick: String, + ident: String, + disp: String, + realname: String, + realhost: String, + realip: String, + secure: bool, + oper: bool, + bot: bool, + hideoper: bool, + hidechans: bool, + account: Option, + last_active: u64, + signon: u64, + certfp: Option, + swhois: Option, + showwhois: bool, + } + let WhoisInfo { nick, ident, disp, @@ -198,29 +219,30 @@ impl Command for Whois { certfp, swhois, showwhois, - ) = { + } = { let u = &s.users[&tuid]; - ( - u.nick.clone(), - u.ident.clone(), - u.host_display().to_string(), - u.realname.clone(), - u.host.clone(), - u.addr.ip().to_string(), - u.secure, - u.flags.oper, - u.flags.bot, - u.flags.hideoper, - u.flags.hidechans, - u.account.clone(), - u.last_active, - u.signon, - u.certfp.clone(), - u.ext + WhoisInfo { + nick: u.nick.clone(), + ident: u.ident.clone(), + disp: u.host_display().to_string(), + realname: u.realname.clone(), + realhost: u.host.clone(), + realip: u.addr.ip().to_string(), + secure: u.secure, + oper: u.flags.oper, + bot: u.flags.bot, + hideoper: u.flags.hideoper, + hidechans: u.flags.hidechans, + account: u.account.clone(), + last_active: u.last_active, + signon: u.signon, + certfp: u.certfp.clone(), + swhois: u + .ext .get::() .map(|w| w.0.clone()), - u.flags.showwhois, - ) + showwhois: u.flags.showwhois, + } }; let chans: Vec = keys .iter()