From: Thomas Lamprecht <t.lamprecht@proxmox.com>
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 [thread overview]
Message-ID: <20260310204737.2475584-1-t.lamprecht@proxmox.com> (raw)
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 <h.laimer@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
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
reply other threads:[~2026-03-10 20:48 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260310204737.2475584-1-t.lamprecht@proxmox.com \
--to=t.lamprecht@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.