Visitar URL original
Reject paths in .tool-versions (#1007) · astral-sh/setup-uv@f9cdb47 · GitHub
Skip to content

Commit f9cdb47

Browse files
authored
Reject paths in .tool-versions (#1007)
## Summary - reject path-like uv versions from `.tool-versions` - reject path-like Python versions from `.tool-versions` - document the restriction and cover Unix and Windows paths in tests ## Testing - `npm ci --ignore-scripts` - `npm run all` Refs: pi-session 019ff4bb-8b7c-7c4b-8bdf-7c188dfa2e3f
1 parent 4f6036f commit f9cdb47

5 files changed

Lines changed: 58 additions & 16 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,9 @@ python 3.13
161161
version-file: ".tool-versions"
162162
```
163163

164-
Only a single Python version is supported. Multiple fallback versions and the asdf `ref:`, `path:`,
165-
and `system` forms are ignored with a warning.
164+
Only a single Python version is supported. Filesystem paths are not supported for uv or Python.
165+
Multiple Python fallback versions and the asdf `ref:`, `path:`, and `system` forms are ignored with
166+
a warning.
166167

167168
```yaml
168169
- name: Install the latest version of uv and set the python version to 3.13t

‎__tests__/version/tool-versions-file.test.ts‎

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,20 @@ describe("getUvVersionFromToolVersions", () => {
113113
);
114114
});
115115

116+
it.each(["/my/python/exploit", "my/exploited/uv", "C:\\exploited\\uv"])(
117+
"should warn and return undefined for path %s",
118+
async (version) => {
119+
mockReadFileSync.mockReturnValue(`uv ${version}`);
120+
121+
const result = await getVersionFromToolVersions(".tool-versions");
122+
123+
expect(result).toBeUndefined();
124+
expect(mockWarning).toHaveBeenCalledWith(
125+
`The uv version ${version} in .tool-versions is not supported. Paths are not allowed.`,
126+
);
127+
},
128+
);
129+
116130
it("should handle file path with .tool-versions extension", async () => {
117131
const fileContent = "uv 0.1.0";
118132
mockReadFileSync.mockReturnValue(fileContent);
@@ -170,19 +184,23 @@ describe("getPythonVersionFromToolVersions", () => {
170184
);
171185
});
172186

173-
it.each(["ref:main", "path:~/src/python", "system"])(
174-
"should warn and return undefined for %s",
175-
async (version) => {
176-
mockReadFileSync.mockReturnValue(`python ${version}`);
187+
it.each([
188+
"ref:main",
189+
"path:~/src/python",
190+
"system",
191+
"/my/python/exploit",
192+
"my/exploited/python",
193+
"C:\\exploited\\python",
194+
])("should warn and return undefined for %s", async (version) => {
195+
mockReadFileSync.mockReturnValue(`python ${version}`);
177196

178-
const result = await getPythonVersionFromToolVersions(".tool-versions");
197+
const result = await getPythonVersionFromToolVersions(".tool-versions");
179198

180-
expect(result).toBeUndefined();
181-
expect(mockWarning).toHaveBeenCalledWith(
182-
`The Python version ${version} in .tool-versions is not supported. The Python entry will be ignored.`,
183-
);
184-
},
185-
);
199+
expect(result).toBeUndefined();
200+
expect(mockWarning).toHaveBeenCalledWith(
201+
`The Python version ${version} in .tool-versions is not supported. The Python entry will be ignored.`,
202+
);
203+
});
186204

187205
it("should return undefined for non-.tool-versions files", async () => {
188206
const result = await getPythonVersionFromToolVersions(".python-version");

‎dist/save-cache/index.cjs‎

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎dist/setup/index.cjs‎

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/version/tool-versions-file.ts‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export function getUvVersionFromToolVersions(
1010
}
1111

1212
const version = stripVersionPrefix(versions[0]);
13+
if (isPath(version)) {
14+
core.warning(
15+
`The uv version ${versions[0]} in .tool-versions is not supported. Paths are not allowed.`,
16+
);
17+
return undefined;
18+
}
1319
if (version.startsWith("ref")) {
1420
core.warning(
1521
"The ref syntax of .tool-versions is not supported. Please use a released version instead.",
@@ -37,7 +43,8 @@ export function getPythonVersionFromToolVersions(
3743
if (
3844
version === "system" ||
3945
version.startsWith("ref:") ||
40-
version.startsWith("path:")
46+
version.startsWith("path:") ||
47+
isPath(version)
4148
) {
4249
core.warning(
4350
`The Python version ${versions[0]} in .tool-versions is not supported. The Python entry will be ignored.`,
@@ -73,3 +80,7 @@ function getToolVersions(
7380
function stripVersionPrefix(version: string): string {
7481
return version.startsWith("v") ? version.slice(1) : version;
7582
}
83+
84+
function isPath(version: string): boolean {
85+
return version.includes("/") || version.includes("\\");
86+
}

0 commit comments

Comments
 (0)