Scripting: script.run reports .jsxbin scripts as unsupported (#176)
`effectcraft-cli script FILE` passes the file's text to script.run, which ran a compiled .jsxbin script as JavaScript and failed with "SyntaxError: unexpected '@'" at 1:1, while file.runScript already says .jsxbin isn't supported. script.run now refuses a script named `.jsxbin` or whose text starts with the `@JSXBIN@` header, with file.runScript's message (one shared constant). The check is in the command, so the CLI with or without --bridge, MCP run_script and the Script Console all report it. Tests: engine_entry_points (by header and by name), script_file_and_eval (the CLI exits 1 with the message and no SyntaxError). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
50f26e6a47
commit
3aaa840471
|
|
@ -239,4 +239,11 @@ fn script_file_and_eval() {
|
|||
let (code, v) = run_json(&["script", "--eval", "\nnope()"]);
|
||||
assert_eq!(code, 1);
|
||||
assert_eq!(v["error"]["line"], json!(2));
|
||||
// A compiled .jsxbin script is reported as unsupported, not as a SyntaxError (#176).
|
||||
let bin_script = tmp("compiled.jsxbin");
|
||||
std::fs::write(&bin_script, "@JSXBIN@ES@2.0@MyBbyBn0ABJAnAEjzFjBjMjFjSjUBfRBFeFjIjFjMjMjPff0DzACByB\n").unwrap();
|
||||
let out = bin().args(["script", bin_script.to_str().unwrap()]).output().unwrap();
|
||||
assert_eq!(out.status.code(), Some(1));
|
||||
let err = String::from_utf8_lossy(&out.stderr);
|
||||
assert!(err.contains(".jsxbin scripts are not supported: run the .jsx source") && !err.contains("SyntaxError"), "{err}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,8 +438,8 @@ fn run_script(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
&& p.get("steps").is_none()
|
||||
&& is_js_script(path)
|
||||
{
|
||||
if path.to_ascii_lowercase().ends_with(".jsxbin") {
|
||||
return Err(bad("file.runScript", "binary .jsxbin scripts are not supported: run the .jsx source"));
|
||||
if is_jsxbin(path) {
|
||||
return Err(bad("file.runScript", JSXBIN));
|
||||
}
|
||||
let bytes = s.services.read_file(path).map_err(|e| EngineError::Other(format!("cannot read {path}: {e}")))?;
|
||||
let code = String::from_utf8_lossy(&bytes).to_string();
|
||||
|
|
@ -487,7 +487,14 @@ fn run_script(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
/// command scripts.
|
||||
fn is_js_script(path: &str) -> bool {
|
||||
let l = path.to_ascii_lowercase();
|
||||
l.ends_with(".jsx") || l.ends_with(".js") || l.ends_with(".jsxbin")
|
||||
l.ends_with(".jsx") || l.ends_with(".js") || is_jsxbin(path)
|
||||
}
|
||||
|
||||
/// Compiled `.jsxbin` scripts are an undocumented binary encoding, not JavaScript.
|
||||
const JSXBIN: &str = "binary .jsxbin scripts are not supported: run the .jsx source";
|
||||
|
||||
fn is_jsxbin(name: &str) -> bool {
|
||||
name.to_ascii_lowercase().ends_with(".jsxbin")
|
||||
}
|
||||
|
||||
/// A script error becomes a toast and a command error.
|
||||
|
|
@ -519,6 +526,11 @@ fn run_js(s: &mut Session, code: &str, name: &str, console: bool) -> Result<Valu
|
|||
fn script_run(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let code = str_p(p, "code").ok_or_else(|| bad("script.run", "missing `code` (JavaScript)"))?.to_string();
|
||||
let name = str_p(p, "name").unwrap_or("script").to_string();
|
||||
// A compiled script (named `.jsxbin`, or its text starts with the format's header) would only
|
||||
// fail to parse at 1:1.
|
||||
if is_jsxbin(&name) || code.trim_start_matches('\u{feff}').trim_start().starts_with("@JSXBIN@") {
|
||||
return Err(bad("script.run", JSXBIN));
|
||||
}
|
||||
run_js(s, &code, &name, super::b_p(p, "console").unwrap_or(false))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -376,6 +376,12 @@ fn engine_entry_points() {
|
|||
// Scripts can't run scripts.
|
||||
let r = s.execute("script.run", json!({"code": "app.run('script.run', {code: '1'})"})).unwrap();
|
||||
assert!(r["error"]["message"].as_str().unwrap().contains("scripts can't run scripts"), "{r}");
|
||||
// Compiled .jsxbin scripts (by name or by their header) are unsupported, not a SyntaxError
|
||||
// at 1:1 (#176).
|
||||
for p in [json!({"code": "@JSXBIN@ES@2.0@MyBbyBn0AB", "name": "compiled.bin"}), json!({"code": "1", "name": "/x/compiled.JSXBIN"})] {
|
||||
let e = s.execute("script.run", p.clone()).unwrap_err().to_string();
|
||||
assert!(e.contains(".jsxbin scripts are not supported: run the .jsx source"), "{p}: {e}");
|
||||
}
|
||||
// File ▸ Scripts ▸ Run Script File… runs .jsx as JavaScript.
|
||||
let dir = std::env::temp_dir().join(format!("ec-script-file-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
|
|
|
|||
Loading…
Reference in New Issue