From ce48798c4f73fb1c8c7319c08b1176ded0faef34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Fri, 15 May 2026 01:26:56 -0600 Subject: [PATCH] fix: replace broken pointer arithmetic in DEFGV macro with safe fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV macro contained `arg = arg + AvMAX(arg)` — SV* pointer arithmetic that does not correctly access array elements. This was introduced in fc9195e (2018) as a workaround for an AV appearing on the Perl argument stack. The pointer arithmetic is undefined behavior: it advances by AvMAX * sizeof(SV) bytes, landing in unrelated memory. The subsequent SvTYPE(arg) read would access garbage. Replace with an immediate CALL_REAL_OP() fallback when the stack top is an AV. Since we cannot meaningfully extract a GV from an AV to compare against PL_defgv, delegating to the real Perl OP is the only safe action. Co-Authored-By: Claude Opus 4.6 --- FileCheck.xs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FileCheck.xs b/FileCheck.xs index 8d893fc..13628e5 100644 --- a/FileCheck.xs +++ b/FileCheck.xs @@ -52,7 +52,10 @@ START_MY_CXT #define RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV() STMT_START { \ if (gl_overload_ft->op[OP_STAT].is_mocked) { \ SV *arg = *PL_stack_sp; GV *gv; \ - if ( SvTYPE(arg) == SVt_PVAV ) arg = arg + AvMAX( arg ); \ + /* An AV on the argument stack is an internal Perl edge case \ + * (observed on some optree layouts). We cannot meaningfully \ + * extract a GV from it, so fall back to the real OP. */ \ + if ( SvTYPE(arg) == SVt_PVAV ) { return CALL_REAL_OP(); } \ if ( PL_op->op_flags & OPf_REF ) \ gv = cGVOP_gv; \ else { \