chore(deps): update all cargo and pnpm dependencies to latest versions

This commit is contained in:
xfy 2026-07-09 18:12:54 +08:00
parent ecd5b441a0
commit 1584e01425
9 changed files with 971 additions and 1117 deletions

997
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -28,27 +28,27 @@ tracing-subscriber = { version = "0.3", optional = true }
rand = { version = "0.8", features = ["getrandom"], optional = true }
http = { version = "1", optional = true }
axum = { version = "0.8", optional = true, features = ["multipart"] }
tower-http = { version = "0.6", optional = true, features = ["compression-full", "timeout", "trace"] }
tower-http = { version = "0.7", optional = true, features = ["compression-full", "timeout", "trace"] }
serde_json = "1.0"
sha2 = { version = "0.10", optional = true }
hex = { version = "0.4", optional = true }
lol_html = { version = "2", optional = true }
lol_html = { version = "3", optional = true }
syntect = { version = "5", default-features = false, features = ["default-syntaxes", "default-themes", "default-fancy", "html", "parsing", "dump-load", "yaml-load"], optional = true }
# NOTE: WebP decoder is intentionally excluded from the image crate.
# We use zenwebp for both encoding and decoding to ensure consistency.
# Do NOT add "webp" to the features list without updating src/webp.rs.
image = { version = "0.25", optional = true, default-features = false, features = ["jpeg", "png", "gif"] }
zenwebp = { version = "0.3", optional = true }
zenwebp = { version = "0.4", optional = true }
moka = { version = "0.12", features = ["future", "sync"], optional = true }
governor = { version = "0.8", optional = true }
sysinfo = { version = "0.34", optional = true }
sqlparser = { version = "0.45", optional = true }
governor = { version = "0.10", optional = true }
sysinfo = { version = "0.39", optional = true }
sqlparser = { version = "0.62", optional = true }
dashmap = { version = "6.2", optional = true }
md-5 = { version = "0.10", optional = true }
futures = { version = "0.3", optional = true }
bytes = { version = "1", optional = true }
bollard = { version = "0.18", optional = true }
bollard = { version = "0.21", optional = true }
[target.'cfg(target_arch = "wasm32")'.dependencies]
web-sys = { version = "0.3", features = ["Document", "Window", "Storage", "Element", "HtmlElement", "DomTokenList", "MediaQueryList", "HtmlImageElement", "MouseEvent", "KeyboardEvent", "Node", "EventTarget", "Navigator", "File", "FileList", "FormData", "Request", "RequestInit", "Response", "Headers", "ClipboardEvent", "DataTransfer", "HtmlInputElement"] }

View File

@ -12,17 +12,17 @@
},
"dependencies": {
"@catppuccin/codemirror": "^1.0.3",
"@codemirror/autocomplete": "^6.18.0",
"@codemirror/commands": "^6.8.0",
"@codemirror/lang-javascript": "^6.2.3",
"@codemirror/lang-python": "^6.2.0",
"@codemirror/autocomplete": "^6.20.3",
"@codemirror/commands": "^6.10.4",
"@codemirror/lang-javascript": "^6.2.5",
"@codemirror/lang-python": "^6.2.1",
"@codemirror/lang-sql": "^6.10.0",
"@codemirror/language": "^6.11.0",
"@codemirror/language": "^6.12.4",
"@codemirror/lint": "^6.9.7",
"@codemirror/search": "^6.7.1",
"@codemirror/state": "^6.5.0",
"@codemirror/view": "^6.36.0",
"@codemirror/state": "^6.7.1",
"@codemirror/view": "^6.43.6",
"@replit/codemirror-vim": "^6.3.0",
"codemirror": "^6.0.1"
"codemirror": "^6.0.2"
}
}

View File

@ -10,11 +10,11 @@
"format": "biome format --write ."
},
"devDependencies": {
"@biomejs/biome": "^2.4.16",
"@biomejs/biome": "^2.5.3",
"happy-dom": "^20.10.6",
"typescript": "^6.0.3",
"vite": "^8.1.0",
"vitest": "^4.1.9"
"vite": "^8.1.3",
"vitest": "^4.1.10"
},
"packageManager": "pnpm@11.8.0",
"engines": {

944
libs/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -11,17 +11,17 @@
"test:watch": "vitest"
},
"dependencies": {
"@tiptap/core": "^3.27.1",
"@tiptap/extension-code-block-lowlight": "^3.27.1",
"@tiptap/extension-file-handler": "^3.27.1",
"@tiptap/extension-image": "^3.27.1",
"@tiptap/extension-link": "^3.27.1",
"@tiptap/extension-list": "^3.27.1",
"@tiptap/extension-table": "^3.27.1",
"@tiptap/markdown": "^3.27.1",
"@tiptap/pm": "^3.27.1",
"@tiptap/starter-kit": "^3.27.1",
"@tiptap/suggestion": "^3.27.1",
"@tiptap/core": "^3.27.3",
"@tiptap/extension-code-block-lowlight": "^3.27.3",
"@tiptap/extension-file-handler": "^3.27.3",
"@tiptap/extension-image": "^3.27.3",
"@tiptap/extension-link": "^3.27.3",
"@tiptap/extension-list": "^3.27.3",
"@tiptap/extension-table": "^3.27.3",
"@tiptap/markdown": "^3.27.3",
"@tiptap/pm": "^3.27.3",
"@tiptap/starter-kit": "^3.27.3",
"@tiptap/suggestion": "^3.27.3",
"lowlight": "^3.3.0"
}
}

View File

@ -120,15 +120,20 @@ fn check_guards(
for stmt in asts {
match stmt {
// 护栏 1绝禁DROP SCHEMA 永远禁止ObjectType 无 Database 变体,
// DROP DATABASE 仅字符串预检拦截——见 is_absolutely_forbidden
// 这里在 AST 层结构性禁止 DROP SCHEMA防 SQL 注释/空白绕过字符串预检。
// 护栏 1绝禁DROP SCHEMA 和 DROP DATABASE 永远禁止。
// 这里在 AST 层结构性禁止,防 SQL 注释/空白绕过字符串预检。
Statement::Drop {
object_type: ObjectType::Schema,
..
} => {
return GuardResult::Forbidden("禁止 DROP SCHEMA".to_string());
}
Statement::Drop {
object_type: ObjectType::Database,
..
} => {
return GuardResult::Forbidden("禁止 DROP DATABASE".to_string());
}
// 护栏 1绝禁CREATE DATABASE 永远禁止。sqlparser 能解析它,
// 故在 AST 层补上结构禁止——这是字符串预检之外的第二道防线,
// 防多空格/注释绕过 is_absolutely_forbidden 的 token 匹配。
@ -142,13 +147,13 @@ fn check_guards(
}
}
// 护栏 2UPDATE 无 WHERE
Statement::Update { selection: None, .. } => {
Statement::Update(sqlparser::ast::Update { selection: None, .. }) => {
return GuardResult::Forbidden(
"UPDATE 缺少 WHERE 子句,将影响全表。请加 WHERE 条件。".to_string(),
);
}
// 护栏 2DELETE 无 WHERE
Statement::Delete { selection: None, .. } => {
Statement::Delete(sqlparser::ast::Delete { selection: None, .. }) => {
return GuardResult::Forbidden(
"DELETE 缺少 WHERE 子句,将影响全表。请加 WHERE 条件。".to_string(),
);
@ -165,9 +170,9 @@ fn statement_type_name(stmt: &sqlparser::ast::Statement) -> String {
use sqlparser::ast::Statement;
let name = match stmt {
Statement::Query(_) => "Select",
Statement::Insert { .. } => "Insert",
Statement::Update { .. } => "Update",
Statement::Delete { .. } => "Delete",
Statement::Insert(_) => "Insert",
Statement::Update(_) => "Update",
Statement::Delete(_) => "Delete",
Statement::CreateTable { .. } => "CreateTable",
Statement::AlterTable { .. } => "AlterTable",
Statement::Drop { .. } => "Drop",
@ -475,11 +480,13 @@ mod tests {
}
#[test]
fn drop_database_cannot_be_parsed_so_precheck_is_sole_guard() {
// 安全不变量:sqlparser 的 PostgreSqlDialect 无法解析 DROP DATABASE。
// 故 is_absolutely_forbidden 是 DROP DATABASE 的唯一防线。
// 若未来 sqlparser 升级后能解析它,必须在 check_guards 补 AST 分支。
assert!(parse("DROP DATABASE x").is_empty());
fn drop_database_is_guarded_by_both_precheck_and_ast_check() {
let asts = parse("DROP DATABASE x");
assert!(!asts.is_empty(), "DROP DATABASE 应可被 sqlparser 解析");
assert!(matches!(
check_guards(&asts, true),
GuardResult::Forbidden(_)
));
assert!(is_absolutely_forbidden("DROP DATABASE x").is_some());
}

View File

@ -339,18 +339,14 @@ fn sanitize(input: &str, config: &SanitizerConfig) -> String {
Ok(())
};
lol_html::rewrite_str(
input,
lol_html::RewriteStrSettings {
element_content_handlers: vec![lol_html::element!("*", element_handler)],
document_content_handlers: vec![lol_html::doc_comments!(|c| {
let settings = lol_html::RewriteStrSettings::new()
.append_element_content_handler(lol_html::element!("*", element_handler))
.append_document_content_handler(lol_html::doc_comments!(|c| {
c.remove();
Ok(())
})],
..lol_html::RewriteStrSettings::new()
},
)
.unwrap_or_default()
}));
lol_html::rewrite_str(input, settings).unwrap_or_default()
}
#[cfg(feature = "server")]

View File

@ -5,8 +5,12 @@ use tokio::time::timeout;
use futures::StreamExt;
use bollard::Docker;
use bollard::container::{Config, CreateContainerOptions, StartContainerOptions, RemoveContainerOptions, LogOutput, WaitContainerOptions};
use bollard::models::{HostConfig, ResourcesUlimits};
use bollard::container::LogOutput;
use bollard::models::{HostConfig, ResourcesUlimits, ContainerCreateBody};
use bollard::query_parameters::{
CreateContainerOptions, StartContainerOptions, RemoveContainerOptions, WaitContainerOptions,
AttachContainerOptions,
};
use crate::infra::runner_config::{ResourceLimits, RUNNER_CONFIG};
pub static DOCKER_CLIENT: LazyLock<Docker> = LazyLock::new(|| {
@ -81,7 +85,7 @@ pub async fn run_in_container(
let setup_cmd = format!("cat > /code/main.{} && exec {}", ext, run_cmd);
let cmd = vec!["sh".to_string(), "-c".to_string(), setup_cmd];
let config = Config {
let config = ContainerCreateBody {
image: Some(image_name.to_string()),
cmd: Some(cmd),
host_config: Some(host_config),
@ -96,7 +100,7 @@ pub async fn run_in_container(
};
let container = docker.create_container(
None::<CreateContainerOptions<String>>,
None::<CreateContainerOptions>,
config
).await?;
@ -109,11 +113,12 @@ pub async fn run_in_container(
// Attach to container to stream stdin, stdout, and stderr
let attach_res = docker.attach_container(
&container_id,
Some(bollard::container::AttachContainerOptions::<String> {
stdin: Some(true),
stdout: Some(true),
stderr: Some(true),
stream: Some(true),
Some(AttachContainerOptions {
stdin: true,
stdout: true,
stderr: true,
stream: true,
logs: false,
..Default::default()
})
).await;
@ -125,7 +130,7 @@ pub async fn run_in_container(
// Start container
docker
.start_container(&container_id, None::<StartContainerOptions<String>>)
.start_container(&container_id, None::<StartContainerOptions>)
.await?;
// Write source code to stdin and drop/close the writer
@ -145,7 +150,7 @@ pub async fn run_in_container(
// Wait for execution with timeout control
let wait_future = async {
let mut wait_stream = docker.wait_container(&container_id, None::<WaitContainerOptions<String>>);
let mut wait_stream = docker.wait_container(&container_id, None::<WaitContainerOptions>);
wait_stream.next().await
};
@ -162,7 +167,7 @@ pub async fn run_in_container(
Err(_) => {
// timeout, kill container
timed_out = true;
let _ = docker.kill_container::<String>(&container_id, None).await;
let _ = docker.kill_container(&container_id, None).await;
}
}
@ -329,9 +334,10 @@ mod tests {
#[tokio::test]
#[serial_test::serial]
async fn test_run_in_container_cancellation() {
use bollard::query_parameters::ListContainersOptions;
let docker = &*DOCKER_CLIENT;
let before = docker.list_containers(Some(bollard::container::ListContainersOptions::<String> {
let before = docker.list_containers(Some(ListContainersOptions {
all: true,
..Default::default()
})).await.unwrap();
@ -364,7 +370,7 @@ mod tests {
tokio::time::sleep(Duration::from_secs(2)).await;
let after = docker.list_containers(Some(bollard::container::ListContainersOptions::<String> {
let after = docker.list_containers(Some(ListContainersOptions {
all: true,
..Default::default()
})).await.unwrap();
@ -379,7 +385,7 @@ mod tests {
let leaked_count = leaked.len();
for id in leaked {
let _ = docker.remove_container(&id, Some(bollard::container::RemoveContainerOptions {
let _ = docker.remove_container(&id, Some(RemoveContainerOptions {
force: true,
..Default::default()
})).await;