fix(security): fix percent_decode to handle multi-byte UTF-8 properly
The previous implementation decoded percent-encoded bytes one at a time and cast each to char, which produces invalid characters for multi-byte UTF-8 sequences (e.g. Chinese filenames). Fixed to accumulate raw bytes first and convert to String at the end with proper UTF-8 validation.
This commit is contained in:
@@ -1624,29 +1624,29 @@ fn file_mkdir_route(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn percent_decode(s: &str) -> String {
|
fn percent_decode(s: &str) -> String {
|
||||||
let mut result = String::with_capacity(s.len());
|
let mut bytes = Vec::with_capacity(s.len());
|
||||||
let mut chars = s.bytes();
|
let mut chars = s.bytes();
|
||||||
while let Some(b) = chars.next() {
|
while let Some(b) = chars.next() {
|
||||||
if b == b'%' {
|
if b == b'%' {
|
||||||
let h = chars.next().unwrap_or(0);
|
let h = chars.next().unwrap_or(0);
|
||||||
let l = chars.next().unwrap_or(0);
|
let l = chars.next().unwrap_or(0);
|
||||||
let hex = [h, l];
|
let hex = [h, l];
|
||||||
if let Ok(s) = std::str::from_utf8(&hex) {
|
if let Ok(hex_str) = std::str::from_utf8(&hex) {
|
||||||
if let Ok(val) = u8::from_str_radix(s, 16) {
|
if let Ok(val) = u8::from_str_radix(hex_str, 16) {
|
||||||
result.push(val as char);
|
bytes.push(val);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.push('%');
|
bytes.push(b'%');
|
||||||
result.push(h as char);
|
bytes.push(h);
|
||||||
result.push(l as char);
|
bytes.push(l);
|
||||||
} else if b == b'+' {
|
} else if b == b'+' {
|
||||||
result.push(' ');
|
bytes.push(b' ');
|
||||||
} else {
|
} else {
|
||||||
result.push(b as char);
|
bytes.push(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
String::from_utf8(bytes).unwrap_or_else(|e| String::from_utf8_lossy(e.as_bytes()).into_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_video_files(dir: &Path) -> Vec<VideoFileInfo> {
|
fn list_video_files(dir: &Path) -> Vec<VideoFileInfo> {
|
||||||
|
|||||||
Reference in New Issue
Block a user