diff --git a/README.md b/README.md index fff6be2..913f0ef 100644 --- a/README.md +++ b/README.md @@ -161,8 +161,9 @@ python 3.13 version-file: ".tool-versions" ``` -Only a single Python version is supported. Multiple fallback versions and the asdf `ref:`, `path:`, -and `system` forms are ignored with a warning. +Only a single Python version is supported. Filesystem paths are not supported for uv or Python. +Multiple Python fallback versions and the asdf `ref:`, `path:`, and `system` forms are ignored with +a warning. ```yaml - name: Install the latest version of uv and set the python version to 3.13t diff --git a/__tests__/version/tool-versions-file.test.ts b/__tests__/version/tool-versions-file.test.ts index bf91b0f..8276dca 100644 --- a/__tests__/version/tool-versions-file.test.ts +++ b/__tests__/version/tool-versions-file.test.ts @@ -113,6 +113,20 @@ describe("getUvVersionFromToolVersions", () => { ); }); + it.each(["/my/python/exploit", "my/exploited/uv", "C:\\exploited\\uv"])( + "should warn and return undefined for path %s", + async (version) => { + mockReadFileSync.mockReturnValue(`uv ${version}`); + + const result = await getVersionFromToolVersions(".tool-versions"); + + expect(result).toBeUndefined(); + expect(mockWarning).toHaveBeenCalledWith( + `The uv version ${version} in .tool-versions is not supported. Paths are not allowed.`, + ); + }, + ); + it("should handle file path with .tool-versions extension", async () => { const fileContent = "uv 0.1.0"; mockReadFileSync.mockReturnValue(fileContent); @@ -170,19 +184,23 @@ describe("getPythonVersionFromToolVersions", () => { ); }); - it.each(["ref:main", "path:~/src/python", "system"])( - "should warn and return undefined for %s", - async (version) => { - mockReadFileSync.mockReturnValue(`python ${version}`); + it.each([ + "ref:main", + "path:~/src/python", + "system", + "/my/python/exploit", + "my/exploited/python", + "C:\\exploited\\python", + ])("should warn and return undefined for %s", async (version) => { + mockReadFileSync.mockReturnValue(`python ${version}`); - const result = await getPythonVersionFromToolVersions(".tool-versions"); + const result = await getPythonVersionFromToolVersions(".tool-versions"); - expect(result).toBeUndefined(); - expect(mockWarning).toHaveBeenCalledWith( - `The Python version ${version} in .tool-versions is not supported. The Python entry will be ignored.`, - ); - }, - ); + expect(result).toBeUndefined(); + expect(mockWarning).toHaveBeenCalledWith( + `The Python version ${version} in .tool-versions is not supported. The Python entry will be ignored.`, + ); + }); it("should return undefined for non-.tool-versions files", async () => { const result = await getPythonVersionFromToolVersions(".python-version"); diff --git a/dist/save-cache/index.cjs b/dist/save-cache/index.cjs index a1dbbda..9d78a0f 100644 --- a/dist/save-cache/index.cjs +++ b/dist/save-cache/index.cjs @@ -61862,7 +61862,7 @@ function getPythonVersionFromToolVersions(filePath) { return void 0; } const version3 = stripVersionPrefix(versions[0]); - if (version3 === "system" || version3.startsWith("ref:") || version3.startsWith("path:")) { + if (version3 === "system" || version3.startsWith("ref:") || version3.startsWith("path:") || isPath(version3)) { warning( `The Python version ${versions[0]} in .tool-versions is not supported. The Python entry will be ignored.` ); @@ -61890,6 +61890,9 @@ function getToolVersions(filePath, toolName) { function stripVersionPrefix(version3) { return version3.startsWith("v") ? version3.slice(1) : version3; } +function isPath(version3) { + return version3.includes("/") || version3.includes("\\"); +} // src/utils/config-file.ts var import_node_fs3 = __toESM(require("node:fs"), 1); diff --git a/dist/setup/index.cjs b/dist/setup/index.cjs index f8d33d2..6f021ac 100644 --- a/dist/setup/index.cjs +++ b/dist/setup/index.cjs @@ -99245,6 +99245,12 @@ function getUvVersionFromToolVersions(filePath) { return void 0; } const version3 = stripVersionPrefix(versions[0]); + if (isPath(version3)) { + warning( + `The uv version ${versions[0]} in .tool-versions is not supported. Paths are not allowed.` + ); + return void 0; + } if (version3.startsWith("ref")) { warning( "The ref syntax of .tool-versions is not supported. Please use a released version instead." @@ -99265,7 +99271,7 @@ function getPythonVersionFromToolVersions(filePath) { return void 0; } const version3 = stripVersionPrefix(versions[0]); - if (version3 === "system" || version3.startsWith("ref:") || version3.startsWith("path:")) { + if (version3 === "system" || version3.startsWith("ref:") || version3.startsWith("path:") || isPath(version3)) { warning( `The Python version ${versions[0]} in .tool-versions is not supported. The Python entry will be ignored.` ); @@ -99293,6 +99299,9 @@ function getToolVersions(filePath, toolName) { function stripVersionPrefix(version3) { return version3.startsWith("v") ? version3.slice(1) : version3; } +function isPath(version3) { + return version3.includes("/") || version3.includes("\\"); +} // src/version/uv-lock-file.ts var import_node_fs5 = __toESM(require("node:fs"), 1); diff --git a/src/version/tool-versions-file.ts b/src/version/tool-versions-file.ts index c18abcc..760ead0 100644 --- a/src/version/tool-versions-file.ts +++ b/src/version/tool-versions-file.ts @@ -10,6 +10,12 @@ export function getUvVersionFromToolVersions( } const version = stripVersionPrefix(versions[0]); + if (isPath(version)) { + core.warning( + `The uv version ${versions[0]} in .tool-versions is not supported. Paths are not allowed.`, + ); + return undefined; + } if (version.startsWith("ref")) { core.warning( "The ref syntax of .tool-versions is not supported. Please use a released version instead.", @@ -37,7 +43,8 @@ export function getPythonVersionFromToolVersions( if ( version === "system" || version.startsWith("ref:") || - version.startsWith("path:") + version.startsWith("path:") || + isPath(version) ) { core.warning( `The Python version ${versions[0]} in .tool-versions is not supported. The Python entry will be ignored.`, @@ -73,3 +80,7 @@ function getToolVersions( function stripVersionPrefix(version: string): string { return version.startsWith("v") ? version.slice(1) : version; } + +function isPath(version: string): boolean { + return version.includes("/") || version.includes("\\"); +}