Replace the duplicated withinDir path-containment helpers in internal... - #149
Merged
colonelpanik merged 1 commit intoAug 9, 2026
Conversation
colonelpanik
marked this pull request as ready for review
August 9, 2026 19:07
colonelpanik
force-pushed
the
overseer/replace-the-duplicated-withindir-path-containment-helpers-in
branch
from
August 9, 2026 19:07
19f5afd to
d87bb91
Compare
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.
Goal
Replace the duplicated withinDir path-containment helpers in internal/grpcapi/vmimport.go:818-824 and internal/libvirt/vtpmstate.go:373 with the existing internal/safename.Contains, removing both local copies.
Plan
Fold the duplicated
withinDirhelpers intosafename.Contains— Implementation PlanGoal: Delete the two local
withinDirpath-containment helpers (internal/grpcapi/vmimport.go:818-824,internal/libvirt/vtpmstate.go:373-379) and route every call site through the existinginternal/safename.Contains.Architecture: Pure consolidation, no new abstraction.
safename.Containsalready exists, is already the implementationSafeJoinbuilds on, and its doc comment already names these copies as the duplication it generalizes. Both local copies are byte-for-byte equivalent to it (proof in Reviewer notes below), so every call site is a mechanical substitution.internal/safenameis a stdlib-only leaf package, so neither import can create a cycle.Tech Stack: Go 1.26, standard
go test. No new dependencies.Global Constraints
ContainsandwithinDircompute the identicalfilepath.Rel-based check. If any test needs a new assertion to stay green, stop — that means the equivalence claim is wrong.internal/grpcapi.TestWithinDir) calls the removed helper directly and therefore moves; moving it is not adding coverage.grep -rn "withinDir" --include=*.go .returns zero hits at the end.internal/vmimport/ova.go:24(safeJoin),internal/storage/btrfs.go:116,internal/safename/tar.go:211. See Reviewer notes.File Structure
internal/libvirt/vtpmstate.gosafename.Contains; delete localwithinDir(:373-379).safenameis already imported (:11).internal/grpcapi/vmimport.gosafenameimport; call sites at :462, :787, :808 →safename.Contains; delete localwithinDir(:818-824).internal/grpcapi/migrate.gosafename.Contains.safenameis already imported (:28).internal/grpcapi/vmimport_test.goTestWithinDir(:86-102) — it tests a helper this change removes.internal/safename/safename_test.goTestContains_Table, next to the existingTestContains.internal/safename/path.goSafeJoindoc comment (:9-12), which names the copies being removed.No files created. No files deleted.
Task 1:
internal/libvirt— drop the vtpmstate copyStart here: this package already imports
safename, so it is the smallest self-contained slice and proves the leaf-package claim before the larger edit.Files:
internal/libvirt/vtpmstate.go:166,internal/libvirt/vtpmstate.go:373-379internal/libvirt/vtpmstate_test.go(existing, unmodified)Interfaces:
Consumes:
safename.Contains(dir, path string) bool— already ininternal/safename/path.go:28.Produces: nothing new.
internal/libvirt.withinDirceases to exist.Step 1: Confirm
internal/safenameis a leaf package (no import cycle)Run:
go list -f '{{.ImportPath}}: {{join .Imports " "}}' ./internal/safenameExpected — stdlib only, no
github.com/litevirt/litevirt/...entry:If any
litevirtimport appears, stop and report — the cycle premise is broken.Run:
go test ./internal/libvirt/Expected:
ok github.com/litevirt/litevirt/internal/libvirtinternal/libvirt/vtpmstate.go:166— replace:with:
Remove these seven lines in full (
internal/libvirt/vtpmstate.go:373-379), including the blank line that separated them fromfsyncPath:fsyncPath(:364-371) becomes the last function in the file.Do not touch the import block.
stringsis still used at :131, :144, :161, :293;osandfilepathare used throughout. The build will tell you if that is wrong.Run:
Expected: no
gofmtoutput, no build output,ok github.com/litevirt/litevirt/internal/libvirt.If you instead get
"strings" imported and not used, you deleted more than the seven lines above — revert the import block and re-check.Run:
Expected: four
--- PASSlines.Note for whoever reads the diff: the check you just rewired at :166 is defense-in-depth and not reachable through
ReadFirmwareBundle's inputs — the earlier guard at :127-133 rejects absolute and..-escaping member names, andrelis derived from an already-cleaned, already-non-escapingname, sodstcannot leaveswtpmStage.TestReadFirmwareBundle_RejectsSlip's"escaping swtpm path"case (swtpm/../../etc/evil) cleans to../etc/eviland dies at :131. That is why Task 2, not this task, carries the mutation check.git add internal/libvirt/vtpmstate.go git commit -m "refactor(libvirt): use safename.Contains for swtpm stage containment"Task 2:
internal/grpcapi— drop the vmimport copy and relocate its testFiles:
internal/grpcapi/vmimport.go(import block, :462, :787, :808, :818-824)internal/grpcapi/migrate.go:60,internal/grpcapi/migrate.go:73internal/grpcapi/vmimport_test.go:86-102(deleteTestWithinDir)internal/safename/safename_test.go(addTestContains_Tableafter the existingTestContains)Interfaces:
Consumes:
safename.Contains(dir, path string) bool.Produces: nothing new.
internal/grpcapi.withinDirceases to exist;internal/grpcapi.(*Server).withinDiskArtifactRootkeeps its exact signature and semantics.Step 1: Baseline the package
Run:
go test ./internal/grpcapi/Expected:
ok github.com/litevirt/litevirt/internal/grpcapi— takes roughly two minutes, that is normal for this package.vmimport.gointernal/grpcapi/vmimport.go— in the third import group, insertsafenamebetweenqcow2andtenancy(gofmt sorts by path, so aliaslvdoes not affect ordering):The stray
"log/slog"at the end of the group is pre-existing — leave it exactly where it is.vmimport.gocall sites:462, insideresolveStagedPath— replace:with:
:787, inside the VMDK descriptor scan — replace:with:
:808, inside theqemu-img infobacking-file check — replace:with:
internal/grpcapi/vmimport.go:818-824— remove these seven lines, leaving the// ── small helpers ──banner at :816 in place (it still headsfileExists,readHead, andfindByExt):fileExistsbecomes the first helper under the banner. Do not touch the import block again:osis still used byfileExists/readHead/findByExt,stringsby :474 and :787,filepaththroughout.migrate.gocall sitesinternal/grpcapi/migrate.go:59-77,withinDiskArtifactRoot. Replace :60:with:
and :73:
with:
migrate.goalready importssafenameat :28 — no import edit here.internal/safenameDelete
internal/grpcapi/vmimport_test.go:86-102in full:Then add this to
internal/safename/safename_test.go, immediately after the existingTestContains(which ends at :144) and before the// --- tar extraction ---section marker at :146 — it belongs with the path tests, not the tar tests:Two deliberate differences from the original, both no-ops for these inputs:
Containsinstead ofwithinDir(same package now, so no qualifier);filepath.Clean(c.path)is dropped, becauseContainscleans internally./srv/imports/x/../y/disk.qcow2still yieldsrel == "../y/disk.qcow2"→false, identical to before.After deleting
TestWithinDir, check whetherfilepathis still used elsewhere invmimport_test.go— it is (:67,:78,:80,:107), so its import stays. The build is the authority.Run:
Expected: no
gofmtoutput, no build or vet output, thenEverything above is a substitution, so the risk is not "wrong logic", it is "call site silently no longer consulted". Break
Containsand confirm red.Temporarily insert
return trueas the first statement ofContainsininternal/safename/path.go— keep the rest of the body:Insert it, do not replace the final
return— line 34 is the only use ofstringsinpath.go, and replacing it fails the build with"strings" imported and not usedinstead of failing the test, which proves nothing.Run:
Expected: both FAIL.
TestContains/TestContains_Table/TestSafeJoinfail on the sibling/parent/escape cases;TestAssertNoExternalDiskRefs_RejectsExternalBackingfails withexpected rejection of external backing file, got nil, which is the :808 call site you just rewired reporting that it is genuinely reached. (go vetwill now also warnunreachable code— expected, it is the mutation.)That grpcapi test needs a real
qemu-imgonPATH. Confirm withwhich qemu-imgfirst; if it is missing the test passes vacuously and this step is worthless — install it or say so in the handoff rather than recording a pass.Now revert the mutation and re-run both commands. Expected: both
ok.git add internal/grpcapi/vmimport.go internal/grpcapi/migrate.go internal/grpcapi/vmimport_test.go internal/safename/safename_test.go git commit -m "refactor(grpcapi): use safename.Contains for path containment"Task 3: Retire the stale
SafeJoindoc comment and gate the whole thingFiles:
internal/safename/path.go:9-12Interfaces: none — comment text and repo-wide verification only.
internal/safename/path.go:9-12names the copies this change just deleted, so it is now wrong. Replace:with:
The last sentence is load-bearing for the next person:
internal/vmimport/ova.go:24is a different helper (returns(string, error)for tar members, rejectsrel == ".") and was left alone on purpose. Do not silently drop that note.Run:
Expected: no matching lines and
exit=1. Any hit means a call site or definition was missed.Run each, in order, and read the output:
Expected: no build/vet output; every
go testlineokorno test files;make ci-guardscompletes with all sub-checks passing. None of the guards should be affected by this change — no SQL builders, no schema version, no new operator-facing flags or config keys — so anyci-guardsfailure is either pre-existing onmainor a real surprise. If one fails, re-run it on a cleanmaincheckout before assuming this change caused it, and report either way.git add internal/safename/path.go git commit -m "docs(safename): point SafeJoin's comment at the finished consolidation"Reviewer notes
1. The equivalence is exact, not approximate. Both removed copies were:
safename.Containsdiffers in exactly two cosmetic ways, and neither changes any result:filepath.Cleanon both arguments first.filepath.Relalready does this internally — Go 1.26src/path/filepath/path.goopensRelwithbase := Clean(basePath); targ := Clean(targPath)— so the extraCleancannot changerel.filepath.Separatorwhere the copies wroteos.PathSeparator.path/filepathdeclaresSeparator = os.PathSeparator, so these are the same constant.Same error handling (
Relerrors →false), same"."acceptance, same..rejection. No call site changes behavior, which is why no call site needed a new assertion.2. The change is wider than the two lines in the goal.
internal/grpcapi.withinDirhad five callers, not three:vmimport.go:462,:787,:808andmigrate.go:60,:73(withinDiskArtifactRoot, which bounds migration's create/remove to the disks dir and file-backed pool dirs so it can never touch{dataDir}/state.db). Removing the helper forcesmigrate.goto move too. Worth checking that the reviewer expected five.3. One existing test had to move, and it is the only test file change.
internal/grpcapi.TestWithinDircalled the removed helper directly, so it could not stay. It is relocated verbatim (bar the two documented no-ops) intointernal/safenameasTestContains_Table. Net coverage is unchanged — no assertion added, none dropped.4. Coverage of the rewired call sites is uneven, and the plan does not pretend otherwise.
Containsbreaks?grpcapi/vmimport.go:808TestAssertNoExternalDiskRefs_RejectsExternalBacking(needs realqemu-img; present here at/usr/bin/qemu-img). This is the mutation target in Task 2 Step 8.grpcapi/vmimport.go:787TestConvertForeignDisk_VMDKRoundTripexercises the descriptor path; thefilepath.IsAbs/strings.Contains(ext, "..")terms short-circuit most escapes beforeContainsis consulted.grpcapi/vmimport.go:462resolveStagedPathgates on RBAC role).grpcapi/migrate.go:60,:73withinDiskArtifactRoot; reached only viaMigrateVM/disk-stub paths.libvirt/vtpmstate.go:1665.
vtpmstate.go:166is unreachable defense-in-depth.ReadFirmwareBundlerejects absolute member names at :127 and..-escaping cleaned names at :131 before the switch. By the time :165 computesdst = filepath.Join(swtpmStage, rel),relderives from an already-cleaned non-escapingname, sodstprovably cannot leaveswtpmStage.TestReadFirmwareBundle_RejectsSlip'sswtpm/../../etc/evilcase cleans to../etc/eviland is caught at :131 — it never reaches the line this plan rewires. So a mutatedContainswill not turn that test red, and the plan does not claim it will. The line is kept (not deleted) because it is a cheap invariant guard, and CLAUDE.md's "mutation-verify anything you assert" is satisfied through the grpcapi site, which is genuinely reachable.6. Import-cycle risk is nil, and Task 1 Step 1 checks it rather than assuming.
internal/safenameimports only stdlib (archive/tar errors fmt io os path/filepath regexp strings syscall time) — a true leaf.internal/libvirt/vtpmstate.go:11already imports it, so Task 1 adds no import at all;internal/grpcapialready imports it from a dozen files, so Task 2 only adds it to one more file in the same package.7. Three near-identical helpers survive, on purpose. The goal names two copies; these are not them:
internal/vmimport/ova.go:24safeJoin— different shape ((string, error), tar-member semantics, treatsrel == "."as an error). Replacing it means usingsafename.SafeJoin, a separate change with its own behavioral review.internal/safename/tar.go:211— insidesafenameitself, tar-specific.internal/storage/btrfs.go:116— usesstrings.HasPrefix(rel, "..")without the separator, so it is subtly over-broad: it would reject a legitimate sibling-free path whose first component starts with..(e.g...data/x). That is a real (if harmless-in-practice) divergence, not an equivalent copy, and swapping it toContainswould be a behavior change — exactly what this plan's constraints forbid. Flagged here so it is a known follow-up rather than an oversight.8. Nothing operator-facing changes, so the docs triangulation guard (
cmd/litevirt/docs_triangulation_test.go) is unaffected: no command, flag, config key, orlitevirt_*identifier is added or removed.grep -rn withinDir docs/is already empty.make ci-guardsis still run in Task 3 because the repo asks for it before every push, not because this change plausibly trips it.9. Baselines measured in this worktree before planning, so the "expected" outputs above are real, not guessed:
go test ./internal/safename/→ok 0.008s;go test ./internal/libvirt/→ok 0.020s;go test ./internal/grpcapi/→ok 120.324s;TestWithinDir,TestAssertNoExternalDiskRefs_RejectsExternalBacking,TestConvertForeignDisk_VMDKRoundTripall currently PASS.Deviations from the plan as executed
The plan's substance held up — every equivalence claim, line number, call-site
count (five, not three), and mutation prediction was correct. Three procedural
deviations:
1. No commits made. Task 1 Step 7, Task 2 Step 9, and Task 3 Step 4 were
skipped: the execution instructions stated committing is handled externally. All
six files are left modified in the working tree as one reviewable change.
2.
gofmt -lis not empty, and that is pre-existing. Task 1 Step 5 and Task2 Step 7 expect no
gofmtoutput. The repo has 13 gofmt-unclean files onde655ea— 4 underinternal/libvirt/, 8 underinternal/grpcapi/, andinternal/safename/safename_test.go(misaligned map literal inTestProjectRBACPath, ~:68). Each was verified unformatted atHEADbefore anyedit. None of the six files this change touches is newly unformatted, and the
added
TestContains_Tableis gofmt-clean. They were left alone deliberately:reformatting unrelated files would bury a 30-line refactor in whitespace noise
for the reviewer. Worth a separate
chore: gofmtpass.3. Task 3 Step 2's
exit=1expectation contradicts Task 3 Step 1. Step 1instructs writing a
SafeJoindoc comment that contains the wordwithinDir("the former per-package withinDir copies…"), so the Step 2 grep cannot return
zero hits. Final state is one hit —
internal/safename/path.go:13, that new comment. Both definitions and allfive call sites are gone, which is what the Global Constraint actually means;
grep -rn 'func withinDir\|withinDir(' --include='*.go' .returns nothing.Verification actually run (not asserted)
go listoninternal/safenamego test ./internal/libvirt/ok 0.020s-v--- PASSgo build ./... && go vet ./...go test ./...okorno test files; zero failuresmake ci-guardsMutation check (Task 2 Step 8) performed as written and it worked.
qemu-imgconfirmed at/usr/bin/qemu-imgbefore running, so the grpcapi testwas not vacuous. With
return trueinserted at the top ofContains:TestContains,TestContains_Table,TestSafeJoin→ FAIL. The relocatedtable failed on both escape cases (
../y/disk.qcow2and/etc/passwd),proving the move preserved its teeth.
TestAssertNoExternalDiskRefs_RejectsExternalBacking→ FAIL withexpected rejection of external backing file, got nil— verbatim the predictedmessage, so the rewired
vmimport.gobacking-file call site is genuinelyreached.
TestConvertForeignDisk_VMDKRoundTrippassed under mutation, consistent withReviewer note 4 rating that site "partly" covered.
Mutation reverted; both commands re-run and
ok.Final Codex review
No blocking findings remained.
Opened by overseer. The plan and the code each converged to zero blocking findings from Codex before this pull request was created.