Move the global scope check into the code-mode runtime (#39703)

## What changed

Replace the core integration test for allowed `globalThis` properties with an
in-process code-mode runtime test. The test continues to fail when the runtime
exposes a global outside the allowlist without requiring the core network test
harness.

GitOrigin-RevId: f33846ae2bb35e6779b5bec0a3f0ba5729eb707d
This commit is contained in:
felixxia-oai
2026-08-20 12:02:42 +00:00
committed by copyberry
parent 585b97d394
commit 37a9da9901
2 changed files with 118 additions and 113 deletions
@@ -785,6 +785,124 @@ text("done");
);
}
#[tokio::test]
async fn global_scope_contains_only_allowed_items() {
let service = InProcessCodeModeSession::new();
let response = execute(
&service,
ExecuteRequest {
enabled_tools: vec![echo_tool()],
source: "text(JSON.stringify(Object.getOwnPropertyNames(globalThis).sort()));"
.to_string(),
yield_time_ms: None,
..execute_request("")
},
)
.await;
let RuntimeResponse::Result {
content_items,
error_text: None,
..
} = response
else {
panic!("global scope inspection failed unexpectedly: {response:?}");
};
let [FunctionCallOutputContentItem::InputText { text }] = content_items.as_slice() else {
panic!("global scope inspection returned unexpected output: {content_items:?}");
};
let globals = serde_json::from_str::<Vec<String>>(text)
.expect("global scope inspection should return a JSON array");
let expected = [
"AggregateError",
"ALL_TOOLS",
"Array",
"ArrayBuffer",
"AsyncDisposableStack",
"BigInt",
"BigInt64Array",
"BigUint64Array",
"Boolean",
"clearTimeout",
"DataView",
"Date",
"DisposableStack",
"Error",
"EvalError",
"FinalizationRegistry",
"Float16Array",
"Float32Array",
"Float64Array",
"Function",
"Infinity",
"Int16Array",
"Int32Array",
"Int8Array",
"Intl",
"Iterator",
"JSON",
"Map",
"Math",
"NaN",
"Number",
"Object",
"Promise",
"Proxy",
"RangeError",
"ReferenceError",
"Reflect",
"RegExp",
"Set",
"String",
"SuppressedError",
"Symbol",
"SyntaxError",
"Temporal",
"TypeError",
"URIError",
"Uint16Array",
"Uint32Array",
"Uint8Array",
"Uint8ClampedArray",
"WeakMap",
"WeakRef",
"WeakSet",
"__codexContentItems",
"add_content",
"audio",
"decodeURI",
"decodeURIComponent",
"encodeURI",
"encodeURIComponent",
"escape",
"exit",
"eval",
"generatedImage",
"globalThis",
"image",
"isFinite",
"isNaN",
"load",
"notify",
"parseFloat",
"parseInt",
"setTimeout",
"store",
"text",
"tools",
"undefined",
"unescape",
"yield_control",
];
for global in &globals {
assert!(
expected.contains(&global.as_str()),
"unexpected global {global} in {globals:?}"
);
}
}
#[tokio::test]
async fn v8_console_is_not_exposed_on_global_this() {
let service = InProcessCodeModeSession::new();
-113
View File
@@ -97,7 +97,6 @@ use image::metadata::Orientation;
use pretty_assertions::assert_eq;
use serde_json::Value;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fs;
use std::io::Cursor;
use std::path::Path;
@@ -5121,118 +5120,6 @@ text(`echo=${result.structuredContent.echo}`);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn code_mode_lists_global_scope_items() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = responses::start_mock_server().await;
let code = r#"
text(JSON.stringify(Object.getOwnPropertyNames(globalThis).sort()));
"#;
let (_test, second_mock) =
run_code_mode_turn_with_rmcp(&server, "use exec to inspect global scope", code).await?;
let req = second_mock.single_request();
let (output, success) = custom_tool_output_body_and_success(&req, "call-1");
assert_ne!(
success,
Some(false),
"exec global scope inspection failed unexpectedly: {output}"
);
let globals = serde_json::from_str::<Vec<String>>(&output)?;
let globals = globals.into_iter().collect::<HashSet<_>>();
let expected = [
"AggregateError",
"ALL_TOOLS",
"Array",
"ArrayBuffer",
"AsyncDisposableStack",
"BigInt",
"BigInt64Array",
"BigUint64Array",
"Boolean",
"clearTimeout",
"DataView",
"Date",
"DisposableStack",
"Error",
"EvalError",
"FinalizationRegistry",
"Float16Array",
"Float32Array",
"Float64Array",
"Function",
"Infinity",
"Int16Array",
"Int32Array",
"Int8Array",
"Intl",
"Iterator",
"JSON",
"Map",
"Math",
"NaN",
"Number",
"Object",
"Promise",
"Proxy",
"RangeError",
"ReferenceError",
"Reflect",
"RegExp",
"Set",
"String",
"SuppressedError",
"Symbol",
"SyntaxError",
"Temporal",
"TypeError",
"URIError",
"Uint16Array",
"Uint32Array",
"Uint8Array",
"Uint8ClampedArray",
"WeakMap",
"WeakRef",
"WeakSet",
"__codexContentItems",
"add_content",
"audio",
"decodeURI",
"decodeURIComponent",
"encodeURI",
"encodeURIComponent",
"escape",
"exit",
"eval",
"generatedImage",
"globalThis",
"image",
"isFinite",
"isNaN",
"load",
"notify",
"parseFloat",
"parseInt",
"setTimeout",
"store",
"text",
"tools",
"undefined",
"unescape",
"yield_control",
];
for g in &globals {
assert!(
expected.contains(&g.as_str()),
"unexpected global {g} in {globals:?}"
);
}
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn code_mode_exports_all_tools_metadata_for_builtin_tools() -> Result<()> {
skip_if_no_network!(Ok(()));