Skip to content

fix: use stat (not lstat) for -p/-S/-b/-c in mock_all_from_stat#92

Draft
Koan-Bot wants to merge 1 commit intocpan-authors:mainfrom
Koan-Bot:koan.atoomic/fix-stat-lstat-dispatch-for-special-types
Draft

fix: use stat (not lstat) for -p/-S/-b/-c in mock_all_from_stat#92
Koan-Bot wants to merge 1 commit intocpan-authors:mainfrom
Koan-Bot:koan.atoomic/fix-stat-lstat-dispatch-for-special-types

Conversation

@Koan-Bot
Copy link
Copy Markdown
Contributor

@Koan-Bot Koan-Bot commented Apr 19, 2026

What

Corrects the stat/lstat dispatch for -p, -S, -b, -c in the mock_all_from_stat code path.

Why

In Perl, only -l uses lstat — all other file test ops follow symlinks via stat. The $can_use_stat whitelist regex missed these four ops, so mocking a symlink that points to a socket/pipe/block/char device would incorrectly fail the corresponding check (e.g., -S would see symlink mode bits from lstat instead of socket mode bits from stat).

How

  • Replaced the fragile character-class whitelist ($can_use_stat) with a blacklist: only -l triggers lstat.
  • Updated the dispatch table entries for -p, -S, -b, -c to read from @stat instead of @lstat.
  • Converted two remaining die calls to Carp::croak for consistency with the public API convention.

Testing

New test t/stat-dispatch-special-types.t with 6 subtests:

  • Verifies -p/-S/-b/-c receive 'stat' (not 'lstat') as callback argument
  • Verifies symlink-to-socket, symlink-to-pipe, symlink-to-block, symlink-to-char scenarios return true
  • Confirms -l still uses lstat correctly

Full test suite passes (1440+ subtests).

🤖 Generated with Claude Code


Quality Report

Changes: 2 files changed, 162 insertions(+), 15 deletions(-)

Code scan: clean

Tests: passed (0 Tests)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

In Perl, only -l uses lstat. All other file test operators follow
symlinks via stat. The $can_use_stat whitelist regex missed -p, -S,
-b, and -c, causing mock_all_from_stat to call the user callback
with 'lstat' instead of 'stat' for these ops. This meant mocking a
symlink-to-socket (for example) would incorrectly fail -S because
lstat sees symlink mode bits, not the target's socket mode bits.

Replace the fragile whitelist with a simple blacklist: only -l uses
lstat. Also fix the dispatch table entries to read from @stat
(not @Lstat) for -p/-S/-b/-c, and convert two remaining die calls
to Carp::croak for consistency with the public API convention.

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