diff --git a/Cargo.lock b/Cargo.lock index f9ee70ae6..68f4acb47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1973,6 +1973,7 @@ dependencies = [ "sqlx", "thiserror", "url", + "urlencoding", "validator", "xml-rs", "yaserde", @@ -3941,6 +3942,12 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b90931029ab9b034b300b797048cf23723400aa757e8a2bfb9d748102f9821" + [[package]] name = "uuid" version = "0.8.2" diff --git a/Cargo.toml b/Cargo.toml index 6a2b27be9..1e2e254da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ zip = "0.5.12" validator = { version = "0.13", features = ["derive"] } regex = "1.5.4" url = "2.2.2" +urlencoding = "2.1.0" gumdrop = "0.8.0" dotenv = "0.15" diff --git a/src/routes/version_creation.rs b/src/routes/version_creation.rs index f255228b5..30db98db9 100644 --- a/src/routes/version_creation.rs +++ b/src/routes/version_creation.rs @@ -633,7 +633,9 @@ pub async fn upload_file( content_type, &format!( "data/{}/versions/{}/{}", - project_id, version_number, file_name + project_id, + version_number, + urlencoding::encode(&file_name) ), data.freeze(), ) diff --git a/src/routes/version_file.rs b/src/routes/version_file.rs index 3373c0f91..df5a33cea 100644 --- a/src/routes/version_file.rs +++ b/src/routes/version_file.rs @@ -306,7 +306,6 @@ pub async fn delete_file( #[derive(Deserialize)] pub struct UpdateData { - pub hash: (String, String), pub loaders: Vec, pub game_versions: Vec, } diff --git a/src/validate/pack.rs b/src/validate/pack.rs index 4d6628389..c8187fa3c 100644 --- a/src/validate/pack.rs +++ b/src/validate/pack.rs @@ -34,12 +34,17 @@ pub struct PackFile<'a> { fn validate_download_url(values: &Vec<&str>) -> Result<(), validator::ValidationError> { for value in values { + let url = url::Url::parse(value) + .ok() + .ok_or_else(|| validator::ValidationError::new("invalid URL"))?; + + if &url.as_str() != value { + return Err(validator::ValidationError::new("invalid URL")); + } + let domains = parse_strings_from_var("WHITELISTED_MODPACK_DOMAINS").unwrap_or_default(); if !domains.contains( - &url::Url::parse(value) - .ok() - .ok_or_else(|| validator::ValidationError::new("invalid URL"))? - .domain() + &url.domain() .ok_or_else(|| validator::ValidationError::new("invalid URL"))? .to_string(), ) {