chore(deps): update all cargo and pnpm dependencies to latest versions
This commit is contained in:
parent
ecd5b441a0
commit
1584e01425
997
Cargo.lock
generated
997
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
@ -28,27 +28,27 @@ tracing-subscriber = { version = "0.3", optional = true }
|
|||||||
rand = { version = "0.8", features = ["getrandom"], optional = true }
|
rand = { version = "0.8", features = ["getrandom"], optional = true }
|
||||||
http = { version = "1", optional = true }
|
http = { version = "1", optional = true }
|
||||||
axum = { version = "0.8", optional = true, features = ["multipart"] }
|
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"
|
serde_json = "1.0"
|
||||||
sha2 = { version = "0.10", optional = true }
|
sha2 = { version = "0.10", optional = true }
|
||||||
hex = { version = "0.4", 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 }
|
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.
|
# NOTE: WebP decoder is intentionally excluded from the image crate.
|
||||||
# We use zenwebp for both encoding and decoding to ensure consistency.
|
# We use zenwebp for both encoding and decoding to ensure consistency.
|
||||||
# Do NOT add "webp" to the features list without updating src/webp.rs.
|
# 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"] }
|
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 }
|
moka = { version = "0.12", features = ["future", "sync"], optional = true }
|
||||||
governor = { version = "0.8", optional = true }
|
governor = { version = "0.10", optional = true }
|
||||||
sysinfo = { version = "0.34", optional = true }
|
sysinfo = { version = "0.39", optional = true }
|
||||||
sqlparser = { version = "0.45", optional = true }
|
sqlparser = { version = "0.62", optional = true }
|
||||||
dashmap = { version = "6.2", optional = true }
|
dashmap = { version = "6.2", optional = true }
|
||||||
md-5 = { version = "0.10", optional = true }
|
md-5 = { version = "0.10", optional = true }
|
||||||
futures = { version = "0.3", optional = true }
|
futures = { version = "0.3", optional = true }
|
||||||
bytes = { version = "1", 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]
|
[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"] }
|
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"] }
|
||||||
|
|||||||
@ -12,17 +12,17 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@catppuccin/codemirror": "^1.0.3",
|
"@catppuccin/codemirror": "^1.0.3",
|
||||||
"@codemirror/autocomplete": "^6.18.0",
|
"@codemirror/autocomplete": "^6.20.3",
|
||||||
"@codemirror/commands": "^6.8.0",
|
"@codemirror/commands": "^6.10.4",
|
||||||
"@codemirror/lang-javascript": "^6.2.3",
|
"@codemirror/lang-javascript": "^6.2.5",
|
||||||
"@codemirror/lang-python": "^6.2.0",
|
"@codemirror/lang-python": "^6.2.1",
|
||||||
"@codemirror/lang-sql": "^6.10.0",
|
"@codemirror/lang-sql": "^6.10.0",
|
||||||
"@codemirror/language": "^6.11.0",
|
"@codemirror/language": "^6.12.4",
|
||||||
"@codemirror/lint": "^6.9.7",
|
"@codemirror/lint": "^6.9.7",
|
||||||
"@codemirror/search": "^6.7.1",
|
"@codemirror/search": "^6.7.1",
|
||||||
"@codemirror/state": "^6.5.0",
|
"@codemirror/state": "^6.7.1",
|
||||||
"@codemirror/view": "^6.36.0",
|
"@codemirror/view": "^6.43.6",
|
||||||
"@replit/codemirror-vim": "^6.3.0",
|
"@replit/codemirror-vim": "^6.3.0",
|
||||||
"codemirror": "^6.0.1"
|
"codemirror": "^6.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,11 +10,11 @@
|
|||||||
"format": "biome format --write ."
|
"format": "biome format --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.4.16",
|
"@biomejs/biome": "^2.5.3",
|
||||||
"happy-dom": "^20.10.6",
|
"happy-dom": "^20.10.6",
|
||||||
"typescript": "^6.0.3",
|
"typescript": "^6.0.3",
|
||||||
"vite": "^8.1.0",
|
"vite": "^8.1.3",
|
||||||
"vitest": "^4.1.9"
|
"vitest": "^4.1.10"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@11.8.0",
|
"packageManager": "pnpm@11.8.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
944
libs/pnpm-lock.yaml
generated
944
libs/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -11,17 +11,17 @@
|
|||||||
"test:watch": "vitest"
|
"test:watch": "vitest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tiptap/core": "^3.27.1",
|
"@tiptap/core": "^3.27.3",
|
||||||
"@tiptap/extension-code-block-lowlight": "^3.27.1",
|
"@tiptap/extension-code-block-lowlight": "^3.27.3",
|
||||||
"@tiptap/extension-file-handler": "^3.27.1",
|
"@tiptap/extension-file-handler": "^3.27.3",
|
||||||
"@tiptap/extension-image": "^3.27.1",
|
"@tiptap/extension-image": "^3.27.3",
|
||||||
"@tiptap/extension-link": "^3.27.1",
|
"@tiptap/extension-link": "^3.27.3",
|
||||||
"@tiptap/extension-list": "^3.27.1",
|
"@tiptap/extension-list": "^3.27.3",
|
||||||
"@tiptap/extension-table": "^3.27.1",
|
"@tiptap/extension-table": "^3.27.3",
|
||||||
"@tiptap/markdown": "^3.27.1",
|
"@tiptap/markdown": "^3.27.3",
|
||||||
"@tiptap/pm": "^3.27.1",
|
"@tiptap/pm": "^3.27.3",
|
||||||
"@tiptap/starter-kit": "^3.27.1",
|
"@tiptap/starter-kit": "^3.27.3",
|
||||||
"@tiptap/suggestion": "^3.27.1",
|
"@tiptap/suggestion": "^3.27.3",
|
||||||
"lowlight": "^3.3.0"
|
"lowlight": "^3.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -120,15 +120,20 @@ fn check_guards(
|
|||||||
|
|
||||||
for stmt in asts {
|
for stmt in asts {
|
||||||
match stmt {
|
match stmt {
|
||||||
// 护栏 1(绝禁):DROP SCHEMA 永远禁止(ObjectType 无 Database 变体,
|
// 护栏 1(绝禁):DROP SCHEMA 和 DROP DATABASE 永远禁止。
|
||||||
// DROP DATABASE 仅字符串预检拦截——见 is_absolutely_forbidden)。
|
// 这里在 AST 层结构性禁止,防 SQL 注释/空白绕过字符串预检。
|
||||||
// 这里在 AST 层结构性禁止 DROP SCHEMA,防 SQL 注释/空白绕过字符串预检。
|
|
||||||
Statement::Drop {
|
Statement::Drop {
|
||||||
object_type: ObjectType::Schema,
|
object_type: ObjectType::Schema,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
return GuardResult::Forbidden("禁止 DROP SCHEMA".to_string());
|
return GuardResult::Forbidden("禁止 DROP SCHEMA".to_string());
|
||||||
}
|
}
|
||||||
|
Statement::Drop {
|
||||||
|
object_type: ObjectType::Database,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
return GuardResult::Forbidden("禁止 DROP DATABASE".to_string());
|
||||||
|
}
|
||||||
// 护栏 1(绝禁):CREATE DATABASE 永远禁止。sqlparser 能解析它,
|
// 护栏 1(绝禁):CREATE DATABASE 永远禁止。sqlparser 能解析它,
|
||||||
// 故在 AST 层补上结构禁止——这是字符串预检之外的第二道防线,
|
// 故在 AST 层补上结构禁止——这是字符串预检之外的第二道防线,
|
||||||
// 防多空格/注释绕过 is_absolutely_forbidden 的 token 匹配。
|
// 防多空格/注释绕过 is_absolutely_forbidden 的 token 匹配。
|
||||||
@ -142,13 +147,13 @@ fn check_guards(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 护栏 2:UPDATE 无 WHERE
|
// 护栏 2:UPDATE 无 WHERE
|
||||||
Statement::Update { selection: None, .. } => {
|
Statement::Update(sqlparser::ast::Update { selection: None, .. }) => {
|
||||||
return GuardResult::Forbidden(
|
return GuardResult::Forbidden(
|
||||||
"UPDATE 缺少 WHERE 子句,将影响全表。请加 WHERE 条件。".to_string(),
|
"UPDATE 缺少 WHERE 子句,将影响全表。请加 WHERE 条件。".to_string(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// 护栏 2:DELETE 无 WHERE
|
// 护栏 2:DELETE 无 WHERE
|
||||||
Statement::Delete { selection: None, .. } => {
|
Statement::Delete(sqlparser::ast::Delete { selection: None, .. }) => {
|
||||||
return GuardResult::Forbidden(
|
return GuardResult::Forbidden(
|
||||||
"DELETE 缺少 WHERE 子句,将影响全表。请加 WHERE 条件。".to_string(),
|
"DELETE 缺少 WHERE 子句,将影响全表。请加 WHERE 条件。".to_string(),
|
||||||
);
|
);
|
||||||
@ -165,9 +170,9 @@ fn statement_type_name(stmt: &sqlparser::ast::Statement) -> String {
|
|||||||
use sqlparser::ast::Statement;
|
use sqlparser::ast::Statement;
|
||||||
let name = match stmt {
|
let name = match stmt {
|
||||||
Statement::Query(_) => "Select",
|
Statement::Query(_) => "Select",
|
||||||
Statement::Insert { .. } => "Insert",
|
Statement::Insert(_) => "Insert",
|
||||||
Statement::Update { .. } => "Update",
|
Statement::Update(_) => "Update",
|
||||||
Statement::Delete { .. } => "Delete",
|
Statement::Delete(_) => "Delete",
|
||||||
Statement::CreateTable { .. } => "CreateTable",
|
Statement::CreateTable { .. } => "CreateTable",
|
||||||
Statement::AlterTable { .. } => "AlterTable",
|
Statement::AlterTable { .. } => "AlterTable",
|
||||||
Statement::Drop { .. } => "Drop",
|
Statement::Drop { .. } => "Drop",
|
||||||
@ -475,11 +480,13 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn drop_database_cannot_be_parsed_so_precheck_is_sole_guard() {
|
fn drop_database_is_guarded_by_both_precheck_and_ast_check() {
|
||||||
// 安全不变量:sqlparser 的 PostgreSqlDialect 无法解析 DROP DATABASE。
|
let asts = parse("DROP DATABASE x");
|
||||||
// 故 is_absolutely_forbidden 是 DROP DATABASE 的唯一防线。
|
assert!(!asts.is_empty(), "DROP DATABASE 应可被 sqlparser 解析");
|
||||||
// 若未来 sqlparser 升级后能解析它,必须在 check_guards 补 AST 分支。
|
assert!(matches!(
|
||||||
assert!(parse("DROP DATABASE x").is_empty());
|
check_guards(&asts, true),
|
||||||
|
GuardResult::Forbidden(_)
|
||||||
|
));
|
||||||
assert!(is_absolutely_forbidden("DROP DATABASE x").is_some());
|
assert!(is_absolutely_forbidden("DROP DATABASE x").is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -339,18 +339,14 @@ fn sanitize(input: &str, config: &SanitizerConfig) -> String {
|
|||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
lol_html::rewrite_str(
|
let settings = lol_html::RewriteStrSettings::new()
|
||||||
input,
|
.append_element_content_handler(lol_html::element!("*", element_handler))
|
||||||
lol_html::RewriteStrSettings {
|
.append_document_content_handler(lol_html::doc_comments!(|c| {
|
||||||
element_content_handlers: vec![lol_html::element!("*", element_handler)],
|
c.remove();
|
||||||
document_content_handlers: vec![lol_html::doc_comments!(|c| {
|
Ok(())
|
||||||
c.remove();
|
}));
|
||||||
Ok(())
|
|
||||||
})],
|
lol_html::rewrite_str(input, settings).unwrap_or_default()
|
||||||
..lol_html::RewriteStrSettings::new()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
|
|||||||
@ -5,8 +5,12 @@ use tokio::time::timeout;
|
|||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
use bollard::container::{Config, CreateContainerOptions, StartContainerOptions, RemoveContainerOptions, LogOutput, WaitContainerOptions};
|
use bollard::container::LogOutput;
|
||||||
use bollard::models::{HostConfig, ResourcesUlimits};
|
use bollard::models::{HostConfig, ResourcesUlimits, ContainerCreateBody};
|
||||||
|
use bollard::query_parameters::{
|
||||||
|
CreateContainerOptions, StartContainerOptions, RemoveContainerOptions, WaitContainerOptions,
|
||||||
|
AttachContainerOptions,
|
||||||
|
};
|
||||||
use crate::infra::runner_config::{ResourceLimits, RUNNER_CONFIG};
|
use crate::infra::runner_config::{ResourceLimits, RUNNER_CONFIG};
|
||||||
|
|
||||||
pub static DOCKER_CLIENT: LazyLock<Docker> = LazyLock::new(|| {
|
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 setup_cmd = format!("cat > /code/main.{} && exec {}", ext, run_cmd);
|
||||||
let cmd = vec!["sh".to_string(), "-c".to_string(), setup_cmd];
|
let cmd = vec!["sh".to_string(), "-c".to_string(), setup_cmd];
|
||||||
|
|
||||||
let config = Config {
|
let config = ContainerCreateBody {
|
||||||
image: Some(image_name.to_string()),
|
image: Some(image_name.to_string()),
|
||||||
cmd: Some(cmd),
|
cmd: Some(cmd),
|
||||||
host_config: Some(host_config),
|
host_config: Some(host_config),
|
||||||
@ -96,7 +100,7 @@ pub async fn run_in_container(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let container = docker.create_container(
|
let container = docker.create_container(
|
||||||
None::<CreateContainerOptions<String>>,
|
None::<CreateContainerOptions>,
|
||||||
config
|
config
|
||||||
).await?;
|
).await?;
|
||||||
|
|
||||||
@ -109,11 +113,12 @@ pub async fn run_in_container(
|
|||||||
// Attach to container to stream stdin, stdout, and stderr
|
// Attach to container to stream stdin, stdout, and stderr
|
||||||
let attach_res = docker.attach_container(
|
let attach_res = docker.attach_container(
|
||||||
&container_id,
|
&container_id,
|
||||||
Some(bollard::container::AttachContainerOptions::<String> {
|
Some(AttachContainerOptions {
|
||||||
stdin: Some(true),
|
stdin: true,
|
||||||
stdout: Some(true),
|
stdout: true,
|
||||||
stderr: Some(true),
|
stderr: true,
|
||||||
stream: Some(true),
|
stream: true,
|
||||||
|
logs: false,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
).await;
|
).await;
|
||||||
@ -125,7 +130,7 @@ pub async fn run_in_container(
|
|||||||
|
|
||||||
// Start container
|
// Start container
|
||||||
docker
|
docker
|
||||||
.start_container(&container_id, None::<StartContainerOptions<String>>)
|
.start_container(&container_id, None::<StartContainerOptions>)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Write source code to stdin and drop/close the writer
|
// 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
|
// Wait for execution with timeout control
|
||||||
let wait_future = async {
|
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
|
wait_stream.next().await
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -162,7 +167,7 @@ pub async fn run_in_container(
|
|||||||
Err(_) => {
|
Err(_) => {
|
||||||
// timeout, kill container
|
// timeout, kill container
|
||||||
timed_out = true;
|
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]
|
#[tokio::test]
|
||||||
#[serial_test::serial]
|
#[serial_test::serial]
|
||||||
async fn test_run_in_container_cancellation() {
|
async fn test_run_in_container_cancellation() {
|
||||||
|
use bollard::query_parameters::ListContainersOptions;
|
||||||
let docker = &*DOCKER_CLIENT;
|
let docker = &*DOCKER_CLIENT;
|
||||||
|
|
||||||
let before = docker.list_containers(Some(bollard::container::ListContainersOptions::<String> {
|
let before = docker.list_containers(Some(ListContainersOptions {
|
||||||
all: true,
|
all: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})).await.unwrap();
|
})).await.unwrap();
|
||||||
@ -364,7 +370,7 @@ mod tests {
|
|||||||
|
|
||||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
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,
|
all: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})).await.unwrap();
|
})).await.unwrap();
|
||||||
@ -379,7 +385,7 @@ mod tests {
|
|||||||
|
|
||||||
let leaked_count = leaked.len();
|
let leaked_count = leaked.len();
|
||||||
for id in leaked {
|
for id in leaked {
|
||||||
let _ = docker.remove_container(&id, Some(bollard::container::RemoveContainerOptions {
|
let _ = docker.remove_container(&id, Some(RemoveContainerOptions {
|
||||||
force: true,
|
force: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})).await;
|
})).await;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user