Skip to content

Keep the --deep source cache in a per-user directory and refuse unsafe cache paths - #69

Merged
thebenignhacker merged 1 commit into
mainfrom
integrate/2026-10-18-r8
Oct 18, 2026
Merged

thebenignhacker merged 1 commit into
mainfrom
integrate/2026-10-18-r8

Conversation

@thebenignhacker

Copy link
Copy Markdown
Member

This pull request lands 1 commit in cmd/cryptodeps and internal/analyzer.

Included

  • Keep the --deep source cache in a per-user directory and refuse unsafe cache paths

Verified on this exact tree

  • go build ./...: exit 0
  • go vet ./...: exit 0
  • make lint (golangci-lint v1.64.8): exit 0, no finding lines in its output
  • Changelog check: the repository has none (no script and no step in .github/workflows/ci.yml)
  • go test -race -p 4 -parallel 4 -v ./...: exit 0; 13 packages ok, 3 packages with no test files; 544 top-level tests passed, 0 failed, 1 skipped (TestIntegration_FetchPyPIPackage, pip not available); 1659 PASS, 0 FAIL and 1 SKIP lines counting subtests
  • git ls-files | grep -c '_test.go$': 86

Not included

None

Closes

None

How to merge

Rebase and merge, so that each change stays its own commit on main.

…e cache paths

--deep kept the source it fetches in one fixed directory, cryptodeps-cache,
in the system temporary directory. It created that directory 0755, and
nothing removed it. The cache now lives in the per-user cache directory
that os.UserCacheDir names: ~/Library/Caches/cryptodeps on macOS,
$XDG_CACHE_HOME/cryptodeps or ~/.cache/cryptodeps on Linux and other Unix
systems, and %LocalAppData%\cryptodeps on Windows. The root and the
ecosystem, package and version directories below it are created 0700.
Where there is no per-user cache directory, or it cannot be created, as
under a home directory the account cannot write to, the run gets a
directory of its own from os.MkdirTemp. source.Fetcher.Close removes it,
and the analyze command calls that, through analyzer.Analyzer.Close,
before it exits. The old directory in the temporary directory is neither
read nor removed.

Before anything in the cache is read or written, the root and the
ecosystem, package and version directories of the entry are checked with
Lstat. One that is a symbolic link or not a directory is refused, and on
Unix so is one that belongs to another user or that its group or everyone
can write to. The error names the directory and the reason, and the
package is reported as not examined; a refused per-user directory is not
replaced with another one. A fetch downloads and extracts in a directory
of its own inside the cache root and renames it into place as the entry,
so an entry appears only once its extraction has finished, and a failed
extraction leaves no entry.

The tests in internal/analyzer/source/cache_root_test.go and
cache_root_unix_test.go cover the location, each refusal at the root and
at the ecosystem, package and version directories, the 0700 modes, the
staging directory, the run's own directory and Close. Against the tree
before this change each of them fails: the cache was in the temporary
directory, its directories were created 0755, the planted links, files
and modes were used rather than refused, and extraction ran in the entry
itself; the Close tests did not compile.
TestDeepSourceCacheOfItsOwnIsRemovedAtExit runs the command with no home
directory and a stub npm, and failed with cryptodeps-cache left in the
temporary directory. deepScanFixture and mavenDeepFixture now put their
entries in the per-user cache of a home inside the test's directory, and
the eight deep-scan tests that use them, which failed against the old
location, pass. The npm and Maven integration tests, which run npm pack,
tar, curl and unzip against the registries, pass through the staging
directory.

Refs #39
@thebenignhacker
thebenignhacker merged commit c330276 into main Oct 18, 2026
3 checks passed
@thebenignhacker
thebenignhacker deleted the integrate/2026-10-18-r8 branch October 18, 2026 22:22
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