Filter @INC hook refs from yath startup and process_includes#449
Open
yuu-no wants to merge 1 commit into
Open
Conversation
768f46f to
b98450c
Compare
Author
|
Force-pushed after rebasing onto the new |
…ludes Tools like Carmel inject blessed @inc hooks via PERL5OPT=-MCarmel::Setup. yath snapshots @inc into two places that all assume plain strings: * App::Yath::Script::V1::call (settings->harness->orig_inc) — JSON encoded by write_settings_to and stringified into child -I flags. * Test2::Harness::Util::process_includes(include_current => 1) — runs through clean_path (realpath/rel2abs) which stringifies refs to bogus "HASH(0x...)" / "CODE(0x...)" / "ARRAY(0x...)" paths, then those leak into child -I flags. Filter refs at both snapshot points. Hook refs cannot survive an exec boundary as -I args anyway; the child reruns whatever PERL5OPT injection the parent had. Tests cover all three @inc hook forms documented in perlvar "@inc" (blessed object, coderef, arrayref) end-to-end through `yath test`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
b98450c to
17790f0
Compare
Author
|
[MEMO] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
yathcrashes (or silently corrupts child-Iflags) when@INCcontains a hook entry — a coderef, an arrayref, or a blessed object — as documented inperlvar "@INC". The most common trigger in the wild is Carmel, which injects a blessed@INChook viaPERL5OPT=-MCarmel::Setup, but anything that follows the hook protocol breaks the same way.This PR filters hook refs out of the two places
yathsnapshots@INC:lib/App/Yath/Script/V1.pm— the early@ORIG_INCsnapshot inApp::Yath::Script::V1::callthat flows intosettings->harness->orig_inc.lib/Test2/Harness/Util.pm—process_includes()when called withinclude_current => 1(used fromRunner.pm,runner.pm, andJob.pm).Reproduction
Without Carmel, any module that does
unshift @INC, sub { ... }orunshift @INC, [\&handler, @state]exhibits the same problem: the JSON encode inwrite_settings_tofails on blessed hooks, andclean_path()(which usesrealpath/rel2abs) stringifies coderef and arrayref hooks into bogus paths likeCODE(0x55a...)/ARRAY(0x55b...), which then leak into child-Iflags viaprocess_includes.Root cause
There are two independent code paths that snapshot
@INCinto something that must be a list of plain path strings:App::Yath::Script::V1::callcaptures@INCearly into@ORIG_INCand stores it onsettings->harness->orig_inc. That setting is later JSON-encoded bywrite_settings_to, which throws on blessed objects, and stringified into-Iarguments for child processes.Test2::Harness::Util::process_includes, called withinclude_current => 1from the runner, re-introduces the live@INCof the parent — including any hooks inherited fromPERL5OPT— into the include list that is passed throughclean_pathand ultimately to child workers.Filtering only the first site is not sufficient: the runner re-pulls hook refs from its own
@INCand the same garbage paths reappear downstream.Fix
In both sites, drop entries that are references:
Hook refs cannot cross the
execboundary as-Iarguments anyway (the child gets a string path from the kernel), so filtering them at the snapshot point loses no functionality — the child's own startup will redo whateverPERL5OPTinjection the parent did.Tests
t/integration/inc_hook.trunsyath testunder three fixture modules that inject each of the hook forms documented inperlvar "@INC":FakeHook.pmCoderefHook.pmArrayrefHook.pm[\&handler, ...]Each case asserts:
encountered objectJSON encode error in the outputHASH(0x...)/CODE(0x...)/ARRAY(0x...)) leaked into a pathThis is broader than the unit-level coverage proposed in #308 — it exercises both sites of the fix end-to-end through an actual child invocation.
Related issues / PRs
2.0branch where the affected files have been moved underreference/legacy/. On the1.0line — which this PR targets — the bug is still present and reproducible.process_includes) but was a bot-generated PR with merge conflicts and no integration test, and was closed without engagement. This PR uses the same filter shape (functionally equivalent:ref $_ eq ''↔!ref($_)) and adds end-to-end coverage for all three hook forms.Branch target
1.0. The corresponding files do not exist in this form on2.0(they have moved toreference/legacy/), so no port to2.0is needed.Notes for review
@INCentries (the normal case) are untouched, so existing behavior is preserved.use strict; use warnings;.t/integration/inc_hook.tis marked# HARNESS-DURATION-MEDIUMbecause it spawns three fullyath testruns.AI assistance disclosure (per
AI_AND_LLM_POLICY.txt)Drafting and code generation in this PR were assisted by Claude (Anthropic), noted via
Co-Authored-By:trailer on the commit. The diagnosis (two-site snapshot, JSON encode crash, ref stringification throughclean_path), the choice of filter shape, the test design covering all three hook forms, and the issue/PR archaeology against1.0vs2.0were vetted by a human reviewer. I can answer questions about every line of the change.