fix: Subinfo parse error

This commit is contained in:
MystiPanda 2023-12-15 11:35:10 +08:00
parent 8955ca5216
commit a719237556
2 changed files with 20 additions and 24 deletions

View File

@ -247,12 +247,11 @@ impl PrfItem {
let extra = match header.get("Subscription-Userinfo") { let extra = match header.get("Subscription-Userinfo") {
Some(value) => { Some(value) => {
let sub_info = value.to_str().unwrap_or(""); let sub_info = value.to_str().unwrap_or("");
Some(PrfExtra { Some(PrfExtra {
upload: help::parse_str(sub_info, "upload=").unwrap_or(0), upload: help::parse_str(sub_info, "upload").unwrap_or(0),
download: help::parse_str(sub_info, "download=").unwrap_or(0), download: help::parse_str(sub_info, "download").unwrap_or(0),
total: help::parse_str(sub_info, "total=").unwrap_or(0), total: help::parse_str(sub_info, "total").unwrap_or(0),
expire: help::parse_str(sub_info, "expire=").unwrap_or(0), expire: help::parse_str(sub_info, "expire").unwrap_or(0),
}) })
} }
None => None, None => None,
@ -262,9 +261,9 @@ impl PrfItem {
let filename = match header.get("Content-Disposition") { let filename = match header.get("Content-Disposition") {
Some(value) => { Some(value) => {
let filename = value.to_str().unwrap_or(""); let filename = value.to_str().unwrap_or("");
match help::parse_str::<String>(filename, "filename=") { match help::parse_str::<String>(filename, "filename") {
Some(filename) => Some(filename), Some(filename) => Some(filename),
None => match help::parse_str::<String>(filename, "filename*=") { None => match help::parse_str::<String>(filename, "filename*") {
Some(filename) => { Some(filename) => {
let iter = percent_encoding::percent_decode(filename.as_bytes()); let iter = percent_encoding::percent_decode(filename.as_bytes());
let filename = iter.decode_utf8().unwrap_or_default(); let filename = iter.decode_utf8().unwrap_or_default();

View File

@ -71,15 +71,12 @@ pub fn get_uid(prefix: &str) -> String {
/// parse the string /// parse the string
/// xxx=123123; => 123123 /// xxx=123123; => 123123
pub fn parse_str<T: FromStr>(target: &str, key: &str) -> Option<T> { pub fn parse_str<T: FromStr>(target: &str, key: &str) -> Option<T> {
target.find(key).and_then(|idx| { target.split(';').map(str::trim).find_map(|s| {
let idx = idx + key.len(); let mut parts = s.splitn(2, '=');
let value = &target[idx..]; match (parts.next(), parts.next()) {
(Some(k), Some(v)) if k == key => v.parse::<T>().ok(),
match value.split(';').nth(0) { _ => None,
Some(value) => value.trim().parse(),
None => value.trim().parse(),
} }
.ok()
}) })
} }
@ -162,17 +159,17 @@ fn test_parse_value() {
let test_1 = "upload=111; download=2222; total=3333; expire=444"; let test_1 = "upload=111; download=2222; total=3333; expire=444";
let test_2 = "attachment; filename=Clash.yaml"; let test_2 = "attachment; filename=Clash.yaml";
assert_eq!(parse_str::<usize>(test_1, "upload=").unwrap(), 111); assert_eq!(parse_str::<usize>(test_1, "upload").unwrap(), 111);
assert_eq!(parse_str::<usize>(test_1, "download=").unwrap(), 2222); assert_eq!(parse_str::<usize>(test_1, "download").unwrap(), 2222);
assert_eq!(parse_str::<usize>(test_1, "total=").unwrap(), 3333); assert_eq!(parse_str::<usize>(test_1, "total").unwrap(), 3333);
assert_eq!(parse_str::<usize>(test_1, "expire=").unwrap(), 444); assert_eq!(parse_str::<usize>(test_1, "expire").unwrap(), 444);
assert_eq!( assert_eq!(
parse_str::<String>(test_2, "filename=").unwrap(), parse_str::<String>(test_2, "filename").unwrap(),
format!("Clash.yaml") format!("Clash.yaml")
); );
assert_eq!(parse_str::<usize>(test_1, "aaa="), None); assert_eq!(parse_str::<usize>(test_1, "aaa"), None);
assert_eq!(parse_str::<usize>(test_1, "upload1="), None); assert_eq!(parse_str::<usize>(test_1, "upload1"), None);
assert_eq!(parse_str::<usize>(test_1, "expire1="), None); assert_eq!(parse_str::<usize>(test_1, "expire1"), None);
assert_eq!(parse_str::<usize>(test_2, "attachment="), None); assert_eq!(parse_str::<usize>(test_2, "attachment"), None);
} }