Skip to content

fix: replace broken pointer arithmetic in DEFGV macro#112

Draft
Koan-Bot wants to merge 1 commit into
cpan-authors:mainfrom
Koan-Bot:koan.atoomic/fix-defgv-av-pointer-arithmetic
Draft

fix: replace broken pointer arithmetic in DEFGV macro#112
Koan-Bot wants to merge 1 commit into
cpan-authors:mainfrom
Koan-Bot:koan.atoomic/fix-defgv-av-pointer-arithmetic

Conversation

@Koan-Bot
Copy link
Copy Markdown
Contributor

@Koan-Bot Koan-Bot commented May 15, 2026

What

Replace undefined-behavior pointer arithmetic in the RETURN_CALL_REAL_OP_IF_CALL_WITH_DEFGV XS macro with a safe immediate fallback.

Why

The macro contained arg = arg + AvMAX(arg) — SV-struct-level pointer arithmetic that doesn't correctly access array elements. Introduced in fc9195e (Dec 2018) as a workaround for an AV appearing on the Perl argument stack, the expression advances the pointer by AvMAX * sizeof(SV) bytes into unrelated memory. Any subsequent SvTYPE(arg) read is UB.

The AvMAX >= 0 guard (added in 3005451) prevents the negative-offset case but doesn't fix the fundamental problem: pointer arithmetic on SV* cannot yield an array element.

How

When *PL_stack_sp is an AV, fall back immediately to CALL_REAL_OP(). 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. This is consistent with the existing SVt_NULL fallback path.

Testing

Full test suite passes (62 test files). The AV-on-stack edge case is an internal Perl optree artifact that cannot be reliably triggered from pure Perl — existing stacked-op tests (t/stack-corruption.t, t/mock-all-from-stat_basic.t) cover the DEFGV detection path.


🤖 Generated with Claude Code


Quality Report

Changes: 1 file changed, 4 insertions(+), 1 deletion(-)

Code scan: clean

Tests: passed (0 Tests)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

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 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant