From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 886F41FF144 for ; Tue, 10 Mar 2026 21:48:36 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 649D5909C; Tue, 10 Mar 2026 21:48:29 +0100 (CET) From: Thomas Lamprecht To: pve-devel@lists.proxmox.com Subject: [RFC perlmod] ffi glue: type detection: check actual SV flags instead of structural body type Date: Tue, 10 Mar 2026 21:45:43 +0100 Message-ID: <20260310204737.2475584-1-t.lamprecht@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1773175637908 X-SPAM-LEVEL: Spam detection results: 0 AWL -1.078 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.408 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.819 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.903 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: TPAMQIF2NXHFP46A5X4J6Y2LBJRR5XD3 X-Message-ID-Hash: TPAMQIF2NXHFP46A5X4J6Y2LBJRR5XD3 X-MailFrom: t.lamprecht@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: RSPL_type_flags and the RSPL_has_* helpers used a lookup table indexed by SvTYPE, which reflects the structural body layout (what slots are allocated) rather than which slots hold valid data. Since SV body types only upgrade and never downgrade, this caused misclassification [0]. For example, a string "65004" coerced to integer via int() still reported STRING|INTEGER|DOUBLE because SvTYPE remained SVt_PVNV. The deserializer then treated it as a string, and the SvPVutf8 call to read it set SVf_POK as a side effect, making the contamination permanent. Replace the table with actual per-slot validity checks using SvIOKp/SvNOKp/SvPOKp. The private "p" variants are needed because SvOK (used in RSPL_is_defined) also considers private flags -- using only the public variants can leave defined values with no type flags. [0] https://perldoc.perl.org/perlguts#What's-Really-Stored-in-an-SV Reported-by: Hannes Laimer Signed-off-by: Thomas Lamprecht --- NOTE: really not that deep into perl guts so definitively warrants an in-depth review (@Wolfgang O:)). perlmod/src/glue.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/perlmod/src/glue.c b/perlmod/src/glue.c index 2baffe8..c5c9e0b 100644 --- a/perlmod/src/glue.c +++ b/perlmod/src/glue.c @@ -174,16 +174,6 @@ extern bool RSPL_SvTRUE(SV *sv) { #define TYPE_FLAG_DOUBLE 2 #define TYPE_FLAG_STRING 4 -static const uint32_t type_flags[16] = { - [SVt_NULL] = 0, - [SVt_IV] = TYPE_FLAG_INT, - [SVt_NV] = TYPE_FLAG_INT | TYPE_FLAG_DOUBLE, - [SVt_PV] = TYPE_FLAG_STRING, - [SVt_PVIV] = TYPE_FLAG_STRING | TYPE_FLAG_INT, - [SVt_PVNV] = TYPE_FLAG_STRING | TYPE_FLAG_INT | TYPE_FLAG_DOUBLE, - [SVt_PVMG] = ~0, -}; - extern bool RSPL_is_defined(SV *sv) { // see OP_DEFINED in pp_hot.c in perl code if (!sv || !SvANY(sv)) @@ -213,19 +203,23 @@ extern uint32_t RSPL_svtype(SV *sv) { } extern uint32_t RSPL_type_flags(SV *sv) { - return type_flags[SvTYPE(sv)]; + uint32_t flags = 0; + if (SvIOKp(sv)) flags |= TYPE_FLAG_INT; + if (SvNOKp(sv)) flags |= TYPE_FLAG_DOUBLE; + if (SvPOKp(sv)) flags |= TYPE_FLAG_STRING; + return flags; } extern bool RSPL_has_integer(SV *sv) { - return 0 != (type_flags[SvTYPE(sv)] & TYPE_FLAG_INT); + return SvIOKp(sv); } extern bool RSPL_has_double(SV *sv) { - return 0 != (type_flags[SvTYPE(sv)] & TYPE_FLAG_DOUBLE); + return SvNOKp(sv); } extern bool RSPL_has_string(SV *sv) { - return 0 != (type_flags[SvTYPE(sv)] & TYPE_FLAG_STRING); + return SvPOKp(sv); } extern SV* RSPL_SvRV(SV *sv) { -- 2.47.3