From 500d4a5b2a85d63b359b7506e1a31b3357b41024 Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Sun, 23 Aug 2020 16:34:50 -0700 Subject: [PATCH 1/2] Support non-ASCII chars in mysql credentials --- sqlx-core/src/mysql/options/parse.rs | 29 ++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/sqlx-core/src/mysql/options/parse.rs b/sqlx-core/src/mysql/options/parse.rs index c7ecb3abb2..20aa0fa4ff 100644 --- a/sqlx-core/src/mysql/options/parse.rs +++ b/sqlx-core/src/mysql/options/parse.rs @@ -1,5 +1,6 @@ use crate::error::Error; use crate::mysql::MySqlConnectOptions; +use percent_encoding::percent_decode_str; use std::str::FromStr; use url::Url; @@ -20,11 +21,19 @@ impl FromStr for MySqlConnectOptions { let username = url.username(); if !username.is_empty() { - options = options.username(username); + options = options.username( + &*percent_decode_str(username) + .decode_utf8() + .map_err(Error::config)?, + ); } if let Some(password) = url.password() { - options = options.password(password); + options = options.password( + &*percent_decode_str(password) + .decode_utf8() + .map_err(Error::config)?, + ); } let path = url.path().trim_start_matches('/'); @@ -66,3 +75,19 @@ impl FromStr for MySqlConnectOptions { Ok(options) } } + +#[test] +fn it_parses_username_with_at_sign_correctly() { + let uri = "mysql://user@hostname:password@hostname:5432/database"; + let opts = MySqlConnectOptions::from_str(uri).unwrap(); + + assert_eq!("user@hostname", &opts.username); +} + +#[test] +fn it_parses_password_with_non_ascii_chars_correctly() { + let uri = "mysql://username:p@ssw0rd@hostname:5432/database"; + let opts = MySqlConnectOptions::from_str(uri).unwrap(); + + assert_eq!(Some("p@ssw0rd".into()), opts.password); +} From b48e008ef829b6d4f4c6479f27b2d15c9f6564ca Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Sun, 23 Aug 2020 16:48:59 -0700 Subject: [PATCH 2/2] Support non-ASCII chars in mssql credentials --- sqlx-core/src/mssql/options/parse.rs | 29 ++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/sqlx-core/src/mssql/options/parse.rs b/sqlx-core/src/mssql/options/parse.rs index d9af25a4bc..e91e3a73cd 100644 --- a/sqlx-core/src/mssql/options/parse.rs +++ b/sqlx-core/src/mssql/options/parse.rs @@ -1,5 +1,6 @@ use crate::error::Error; use crate::mssql::MssqlConnectOptions; +use percent_encoding::percent_decode_str; use std::str::FromStr; use url::Url; @@ -20,11 +21,19 @@ impl FromStr for MssqlConnectOptions { let username = url.username(); if !username.is_empty() { - options = options.username(username); + options = options.username( + &*percent_decode_str(username) + .decode_utf8() + .map_err(Error::config)?, + ); } if let Some(password) = url.password() { - options = options.password(password); + options = options.password( + &*percent_decode_str(password) + .decode_utf8() + .map_err(Error::config)?, + ); } let path = url.path().trim_start_matches('/'); @@ -35,3 +44,19 @@ impl FromStr for MssqlConnectOptions { Ok(options) } } + +#[test] +fn it_parses_username_with_at_sign_correctly() { + let uri = "mysql://user@hostname:password@hostname:5432/database"; + let opts = MssqlConnectOptions::from_str(uri).unwrap(); + + assert_eq!("user@hostname", &opts.username); +} + +#[test] +fn it_parses_password_with_non_ascii_chars_correctly() { + let uri = "mysql://username:p@ssw0rd@hostname:5432/database"; + let opts = MssqlConnectOptions::from_str(uri).unwrap(); + + assert_eq!(Some("p@ssw0rd".into()), opts.password); +}