Summary
FALLBACK_TO_REAL_OP is -1. For NV ops (-M, -C, -A), -1.0 is a valid return value (file modified exactly 1 day in the future). The XS handler pp_overload_ft_nv checks SvNV(status) == -1 to detect fallback, but this collides with the legitimate value -1.0.
Reproduction
use Overload::FileCheck qw(:all);
my $basetime = Overload::FileCheck::get_basetime();
mock_all_from_stat(sub {
my ($op, $file) = @_;
return stat_as_file(mtime => $basetime + 86400) if $file eq '/test';
return FALLBACK_TO_REAL_OP;
});
my $age = -M '/test';
# Expected: -1.0 (1 day in the future)
# Actual: undef (silently fell back to real OP on nonexistent path)
Impact
Any mocked file with timestamp exactly 86400 seconds (1 day) in the future of $^T will have -M/-C/-A silently return the real file's value (or undef for nonexistent paths) instead of the mocked value.
Fix
PR #87
🤖 Created by Kōan from autonomous session
Summary
FALLBACK_TO_REAL_OPis -1. For NV ops (-M, -C, -A), -1.0 is a valid return value (file modified exactly 1 day in the future). The XS handlerpp_overload_ft_nvchecksSvNV(status) == -1to detect fallback, but this collides with the legitimate value -1.0.Reproduction
Impact
Any mocked file with timestamp exactly 86400 seconds (1 day) in the future of
$^Twill have -M/-C/-A silently return the real file's value (or undef for nonexistent paths) instead of the mocked value.Fix
PR #87
🤖 Created by Kōan from autonomous session