fix(runner): load sealed CommonJS entrypoints by descriptor

This commit is contained in:
Dotta 2026-09-02 19:00:11 -05:00
parent 7c85257f66
commit 325e1e813d
3 changed files with 67 additions and 5 deletions

View File

@ -213,7 +213,8 @@ impl AcpxProviderDescriptor {
let verified_args = launch_profile
.args
.iter()
.map(|argument| {
.enumerate()
.map(|(index, argument)| {
let path = Path::new(argument);
if !path.is_absolute() {
return Ok(VerifiedProcessArgument::Literal(argument.clone()));
@ -221,7 +222,13 @@ impl AcpxProviderDescriptor {
verified
.get(path)
.cloned()
.map(VerifiedProcessArgument::Artifact)
.map(|artifact| {
if index == 0 {
VerifiedProcessArgument::CommonJsArtifact(artifact)
} else {
VerifiedProcessArgument::Artifact(artifact)
}
})
.ok_or_else(|| {
DurableRunnerError::invalid(
"ACPX runner launch profile does not authenticate an absolute argument",
@ -1419,7 +1426,7 @@ mod tests {
let verified_launch = transport.verified_launch.as_ref().unwrap();
assert!(matches!(
verified_launch.arguments().first(),
Some(VerifiedProcessArgument::Artifact(_))
Some(VerifiedProcessArgument::CommonJsArtifact(_))
));
let mut drifted_path = descriptor.clone();

View File

@ -1995,7 +1995,7 @@ fn verified_opencode_launch(
let executable = verify_launch_artifact(&profile.executable, "OpenCode provider executable")
.map_err(|error| LocalRunnerError::invalid(error.to_string()))?;
let args = vec![
VerifiedProcessArgument::Artifact(proxy),
VerifiedProcessArgument::CommonJsArtifact(proxy),
VerifiedProcessArgument::Literal(TRUSTED_OPENCODE_EXECUTABLE_ARG.to_owned()),
VerifiedProcessArgument::ExecutableArtifact(executable),
];
@ -2746,7 +2746,7 @@ mod tests {
let launch = verified_opencode_launch(&profile).unwrap();
assert!(matches!(
launch.arguments().first(),
Some(VerifiedProcessArgument::Artifact(_))
Some(VerifiedProcessArgument::CommonJsArtifact(_))
));
assert!(matches!(
launch.arguments().get(1),

View File

@ -26,6 +26,7 @@ use sha2::{Digest, Sha256};
use crate::local_runner::LocalRunnerError;
const PROCESS_OUTPUT_QUEUE_CAPACITY: usize = 256;
const VERIFIED_COMMONJS_ARTIFACT_LOADER: &str = r#"const fs=require("node:fs");const Module=require("node:module");const filename=process.argv[1];const source=fs.readFileSync(filename,"utf8").replace(/^#![^\r\n]*(?:\r?\n|$)/,"");const artifact=new Module(filename);artifact.filename=filename;artifact.paths=[];artifact._compile(source,filename);"#;
#[derive(Clone, Debug)]
pub struct VerifiedProcessArtifact {
@ -185,6 +186,7 @@ fn snapshot_error(display_path: &Path, error: impl std::fmt::Display) -> LocalRu
pub enum VerifiedProcessArgument {
Literal(String),
Artifact(VerifiedProcessArtifact),
CommonJsArtifact(VerifiedProcessArtifact),
ExecutableArtifact(VerifiedProcessArtifact),
}
@ -226,6 +228,13 @@ impl VerifiedProcessLaunch {
inherited.push(fd);
args.push(path.to_string_lossy().into_owned());
}
VerifiedProcessArgument::CommonJsArtifact(artifact) => {
let (fd, path) = inherited_artifact(artifact)?;
inherited.push(fd);
args.push("--eval".to_owned());
args.push(VERIFIED_COMMONJS_ARTIFACT_LOADER.to_owned());
args.push(path.to_string_lossy().into_owned());
}
VerifiedProcessArgument::ExecutableArtifact(artifact) => {
#[cfg(target_os = "linux")]
{
@ -858,3 +867,49 @@ fn exit_fact(status: ExitStatus) -> ProcessExitFact {
}
}
}
#[cfg(all(test, any(target_os = "linux", target_os = "macos")))]
mod tests {
use super::*;
use std::time::{SystemTime, UNIX_EPOCH};
fn verified_artifact(path: &Path, bytes: &[u8]) -> VerifiedProcessArtifact {
fs::write(path, bytes).unwrap();
let digest = format!("sha256:{:x}", Sha256::digest(bytes));
VerifiedProcessArtifact::snapshot_verified(
path.to_owned(),
File::open(path).unwrap(),
&digest,
)
.unwrap()
}
#[test]
fn commonjs_artifacts_use_the_bounded_descriptor_loader() {
let nonce = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let directory = std::env::temp_dir().join(format!(
"paperclip-commonjs-launch-{}-{nonce}",
std::process::id()
));
fs::create_dir_all(&directory).unwrap();
let program = verified_artifact(&directory.join("node"), b"node");
let script = verified_artifact(&directory.join("sidecar.cjs"), b"module.exports = {};\n");
let launch = VerifiedProcessLaunch::new(
program,
vec![VerifiedProcessArgument::CommonJsArtifact(script)],
);
let inherited = launch.inherited_command().unwrap();
assert_eq!(inherited.args[0], "--eval");
assert_eq!(inherited.args[1], VERIFIED_COMMONJS_ARTIFACT_LOADER);
#[cfg(target_os = "linux")]
assert!(inherited.args[2].starts_with("/proc/self/fd/"));
#[cfg(target_os = "macos")]
assert!(inherited.args[2].starts_with("/dev/fd/"));
fs::remove_dir_all(directory).unwrap();
}
}