-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(copy): support advanced copy configuration with custom target paths #1711
base: master
Are you sure you want to change the base?
Changes from 1 commit
a3ddec7
464b49c
ffc0081
5d42e4f
f2c75e3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
use std::fs; | ||
use std::path::Path; | ||
use std::sync::Arc; | ||
|
||
|
@@ -11,6 +12,7 @@ use tracing::debug; | |
|
||
use crate::ast::file::win_path; | ||
use crate::compiler::Context; | ||
use crate::config::CopyConfig; | ||
use crate::plugin::Plugin; | ||
use crate::stats::StatsJsonMap; | ||
use crate::utils::tokio_runtime; | ||
|
@@ -29,8 +31,12 @@ impl CopyPlugin { | |
notify::Config::default(), | ||
) | ||
.unwrap(); | ||
for src in context.config.copy.iter() { | ||
let src = context.root.join(src); | ||
for config in context.config.copy.iter() { | ||
let src = match config { | ||
CopyConfig::Basic(src) => context.root.join(src), | ||
CopyConfig::Advanced { from, .. } => context.root.join(from), | ||
}; | ||
|
||
Comment on lines
+34
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 建议检查源路径是否存在 当前代码在处理 示例修改: for config in context.config.copy.iter() {
let src = match config {
CopyConfig::Basic(src) => context.root.join(src),
CopyConfig::Advanced { from, .. } => context.root.join(from),
};
+ if !src.exists() {
+ eprintln!("Source path {:?} does not exist", src);
+ continue;
+ }
if src.exists() {
debug!("watch {:?}", src);
// ...
}
}
|
||
if src.exists() { | ||
debug!("watch {:?}", src); | ||
let mode = if src.is_dir() { | ||
|
@@ -62,10 +68,26 @@ impl CopyPlugin { | |
fn copy(context: &Arc<Context>) -> Result<()> { | ||
debug!("copy"); | ||
let dest = context.config.output.path.as_path(); | ||
for src in context.config.copy.iter() { | ||
let src = context.root.join(src); | ||
debug!("copy {:?} to {:?}", src, dest); | ||
copy(src.as_path(), dest)?; | ||
for config in context.config.copy.iter() { | ||
match config { | ||
CopyConfig::Basic(src) => { | ||
let src = context.root.join(src); | ||
debug!("copy {:?} to {:?}", src, dest); | ||
copy(&src, dest)?; | ||
} | ||
|
||
CopyConfig::Advanced { from, to } => { | ||
let src = context.root.join(from); | ||
let target = dest.join(to.trim_start_matches("/")); | ||
|
||
if !target.exists() { | ||
fs::create_dir_all(&target)?; | ||
} | ||
|
||
debug!("copy {:?} to {:?}", src, target); | ||
copy(&src, &target)?; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 防止目标路径的目录遍历漏洞 在处理 示例修改: let target = dest.join(to.trim_start_matches("/"));
+ let target = target.canonicalize()?;
+ let dest_canonical = dest.canonicalize()?;
+ if !target.starts_with(&dest_canonical) {
+ return Err(anyhow!("Invalid target path: {:?}", target));
+ }
if !target.exists() {
fs::create_dir_all(&target)?;
}
|
||
} | ||
} | ||
Ok(()) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
为
CopyConfig
添加配置验证CopyConfig
中的from
和to
字段直接来自用户配置,可能包含非法或不安全的路径。建议在配置解析时添加路径验证,确保路径不存在注入风险并且指向合法的位置。