Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/COMMAND-PROFILE-SCHEMA.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,13 @@ Fixed built-in commands (not config-driven, fixed variants): `browser_public_qa`
- No explicit output-size/log-byte cap or memory/CPU limit is documented here for
the generic runner; only `timeoutMs` and `--parallel 2` are enforced by profile.
Verify against `src/jobs.js` before claiming bounds.
- Qt-specific profiles do not exist; Qt builds go through CMake only.
- Qt-specific profiles do not exist; Qt builds go through CMake only. Commands
whose gate starts with `command:cmake_` additionally inherit `CMAKE_PREFIX_PATH`
on Windows (at most 16 absolute directories, no control characters, no `..`
segments, at most 4096 characters); no other job inherits it.
- Windows MAX_PATH: a CMake project configured inside an isolated lane under the
agent state folder can exceed the Visual Studio generator's path limit
(FileTracker error FTK1011 seen on the P520). Status: open; no fix claimed.
- Any GUI/HIL interaction needs explicit user consent and stays pending.

## 6. What is not claimed
Expand Down
24 changes: 23 additions & 1 deletion src/jobs.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function redact(text) {
export function jobEnvironment(
source = process.env,
platform = process.platform,
{ allowReaProviderPaths = false } = {},
{ allowReaProviderPaths = false, allowCmakePrefixPath = false } = {},
) {
// Only standard OS paths needed for native build tools may be inherited.
const env = {
Expand Down Expand Up @@ -99,6 +99,27 @@ export function jobEnvironment(
env[key] = value;
}
}
// Qt and other CMake packages are found through CMAKE_PREFIX_PATH. Only the
// approved cmake-standard commands inherit it, and only when every entry is
// an absolute Windows directory without control characters or ".." parts.
if (allowCmakePrefixPath) {
const value = source.CMAKE_PREFIX_PATH;
const parts =
typeof value === "string" && value.length <= 4096
? value.split(";").filter((part) => part.length > 0)
: [];
if (
parts.length > 0 &&
parts.length <= 16 &&
parts.every(
(part) =>
path.win32.isAbsolute(part) &&
!Array.from(part).some((ch) => ch.charCodeAt(0) < 32) &&
!part.split(/[\\/]/).includes(".."),
)
)
env.CMAKE_PREFIX_PATH = parts.join(";");
}
}
return env;
}
Expand Down Expand Up @@ -560,6 +581,7 @@ export class JobRunner {
j.gate.startsWith("command:rea_doctor:check:inspect@");
const env = jobEnvironment(process.env, process.platform, {
allowReaProviderPaths: isReaDoctor,
allowCmakePrefixPath: j.gate.startsWith("command:cmake_"),
});
// Composer requires HOME even when the job runner deliberately strips
// inherited user environment. Use a private, deterministic directory in
Expand Down
41 changes: 41 additions & 0 deletions tests/windows-job-environment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,44 @@ test("REA doctor opt-in refuses relative, control-character and oversized provid
);
assert.equal(Object.hasOwn(longEnv, "JAVA_HOME"), false);
});

test("CMAKE_PREFIX_PATH is inherited only by approved cmake commands and only when safe", () => {
const base = { PATH: "C:\\Windows\\System32", SystemRoot: "C:\\Windows" };
const good = "C:\\Qt\\6.10.3\\msvc2022_64;D:\\libs\\opencv";
const withPrefix = { ...base, CMAKE_PREFIX_PATH: good };
assert.equal(
Object.hasOwn(jobEnvironment(withPrefix, "win32"), "CMAKE_PREFIX_PATH"),
false,
);
assert.equal(
jobEnvironment(withPrefix, "win32", { allowCmakePrefixPath: true })
.CMAKE_PREFIX_PATH,
good,
);
assert.equal(
Object.hasOwn(
jobEnvironment(withPrefix, "linux", { allowCmakePrefixPath: true }),
"CMAKE_PREFIX_PATH",
),
false,
);
for (const bad of [
"relative\\qt",
"C:\\Qt;..\\evil",
"C:\\Qt\\..\\evil",
"C:\\Qt" + String.fromCharCode(10) + "x",
"C:\\" + "a".repeat(5000),
";;",
]) {
assert.equal(
Object.hasOwn(
jobEnvironment({ ...base, CMAKE_PREFIX_PATH: bad }, "win32", {
allowCmakePrefixPath: true,
}),
"CMAKE_PREFIX_PATH",
),
false,
bad.slice(0, 20),
);
}
});