Align JSON-RPC bounds and parsing

This commit is contained in:
jif-oai
2026-07-09 18:38:34 +01:00
parent b6a506dfc6
commit 25c1b0df49
3 changed files with 30 additions and 1 deletions
+5
View File
@@ -184,6 +184,11 @@ impl<'de> Visitor<'de> for BoundedValueVisitor<'_> {
{
let mut values = Map::new();
while let Some(key) = object.next_key::<String>()? {
if values.contains_key(&key) {
return Err(de::Error::custom(format!(
"duplicate JSON object key `{key}`"
)));
}
let value = object.next_value_seed(BoundedValueSeed {
remaining: &mut *self.remaining,
})?;
@@ -60,6 +60,19 @@ fn accepts_large_scalar_payload() -> serde_json::Result<()> {
Ok(())
}
#[test]
fn rejects_duplicate_object_keys() {
let error = serde_json::from_str::<JSONRPCMessage>(r#"{"method":"safe","method":"dangerous"}"#)
.expect_err("duplicate JSON object keys should be rejected");
assert!(
error
.to_string()
.contains("duplicate JSON object key `method`"),
"unexpected error: {error}"
);
}
#[test]
fn rejects_compact_array_heap_amplification() {
const REPRO_VALUE_COUNT: usize = 2_097_137;
@@ -11,6 +11,7 @@ use crate::ExecutorFileSystem;
use crate::RemoveOptions;
use crate::file_read::FileReadHandleManager;
use crate::local_file_system::LocalFileSystem;
use crate::protocol::FS_READ_DIRECTORY_METHOD;
use crate::protocol::FS_WRITE_FILE_METHOD;
use crate::protocol::FsCanonicalizeParams;
use crate::protocol::FsCanonicalizeResponse;
@@ -42,6 +43,9 @@ use crate::rpc::invalid_request;
use crate::rpc::not_found;
const MAX_FILE_READ_HANDLE_ID_BYTES: usize = 32;
// Each read-directory entry needs four JSON values. Keep same-version
// producers comfortably below the shared 256K-value decoder budget.
const MAX_READ_DIRECTORY_ENTRIES: usize = 50_000;
#[derive(Clone)]
pub(crate) struct FileSystemHandler {
@@ -189,7 +193,14 @@ impl FileSystemHandler {
.file_system
.read_directory(&params.path, params.sandbox.as_ref())
.await
.map_err(map_fs_error)?
.map_err(map_fs_error)?;
let entry_count = entries.len();
if entry_count > MAX_READ_DIRECTORY_ENTRIES {
return Err(internal_error(format!(
"{FS_READ_DIRECTORY_METHOD} returned {entry_count} entries; limit is {MAX_READ_DIRECTORY_ENTRIES}"
)));
}
let entries = entries
.into_iter()
.map(|entry| FsReadDirectoryEntry {
file_name: entry.file_name,