fix(create): reject non-semver versions in org-template manifests - #2665
Conversation
🚀 Deploying Preview to Cloudflare 🚀Preview URL: https://fix-org-template-version-validation-viteplus-dev.voidzero-docs.workers.dev (commit 481b6f5)This URL reflects your latest Preview deploymentPreview Deployments by commit
|
Registry bridge build (
|
| Package | Version |
|---|---|
vite-plus |
0.0.0-commit.0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a |
@voidzero-dev/vite-plus-core |
0.0.0-commit.0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a |
Install the Vite+ CLI built from this commit, then migrate a project:
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/voidzero-dev/vite-plus/0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a/packages/cli/install.sh | VP_PR_VERSION=2665 VP_LEGACY_INSTALLER_URL=https://raw.githubusercontent.com/voidzero-dev/vite-plus/0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a/packages/cli/install-legacy.sh bash# Windows (PowerShell)
$env:VP_PR_VERSION="2665"; $env:VP_LEGACY_INSTALLER_URL="https://raw.githubusercontent.com/voidzero-dev/vite-plus/0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a/packages/cli/install-legacy.ps1"; irm https://raw.githubusercontent.com/voidzero-dev/vite-plus/0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a/packages/cli/install.ps1 | iexOr download the standalone Windows installer built from this commit:
| Architecture | Installer |
|---|---|
| x64 | vp-setup-x86_64-pc-windows-msvc.exe |
| Arm64 | vp-setup-aarch64-pc-windows-msvc.exe |
GitHub requires you to sign in and downloads each installer as a ZIP artifact. Extract vp-setup.exe, then run it against this preview build:
.\vp-setup.exe --version "0.0.0-commit.0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a" --registry "https://registry-bridge.viteplus.dev/"After installing, upgrade the current project's vite-plus to this test build with:
vp migrateOr point your package manager at the bridge registry https://registry-bridge.viteplus.dev/:
| Package manager | Registry config |
|---|---|
| npm / pnpm / Bun | .npmrc: registry=https://registry-bridge.viteplus.dev/ |
| Yarn (v2+) | .yarnrc.yml: npmRegistryServer: "https://registry-bridge.viteplus.dev/" |
Then pin the build (vite aliases to vite-plus-core; pnpm can use a catalog, npm an overrides entry):
{
"devDependencies": {
"vite-plus": "0.0.0-commit.0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a",
"vite": "npm:@voidzero-dev/vite-plus-core@0.0.0-commit.0e24d6c2139ea8733ee4a1dd70e4a2a1ba8b4a4a"
}
}
🐳 Docker preview imageBuilt from this PR's registry bridge build:
# remove any stale local copy from a previous run, then pull fresh
docker rmi ghcr.io/voidzero-dev/vite-plus:pr-2665 2>/dev/null; docker pull ghcr.io/voidzero-dev/vite-plus:pr-2665Quick check: docker run --rm ghcr.io/voidzero-dev/vite-plus:pr-2665 vp --versionSee docs/guide/docker.md for usage. |
A registry response can point a dist-tag at a non-semver string, and readOrgManifest() copied that value into OrgManifest.version without validation. The version later becomes a path component in the org-template extraction cache (<cache>/<host>/<scope>/create/<version>), where '..' segments in a malformed value place the extraction directory outside the cache root. Validate the resolved version with semver.valid() at resolution time, covering both the dist-tags.latest branch and the pinned dist-tags[requestedVersion] branch, and keep the same containment invariant at the path construction sink.
fe1a99c to
481b6f5
Compare
Malformed registry versions can place org-template files outside the cache root.
readOrgManifest()now rejects versions that failsemver.valid(), including targets fromdist-tags.latestand tags that match a requested version.resolveExtractionDir()also checks that the extraction path stays within the cache root. Tests cover invalid versions, path traversal, and valid versions with prerelease or build metadata.