fix: require valid email addresses in dc_provider_new_from_email[_with_dns]()

This commit is contained in:
link2xt
2023-09-25 14:03:09 +00:00
parent 56b2361f01
commit 4e5b41f150
2 changed files with 41 additions and 11 deletions

View File

@@ -4531,7 +4531,14 @@ pub unsafe extern "C" fn dc_provider_new_from_email(
let ctx = &*context; let ctx = &*context;
match block_on(provider::get_provider_info(ctx, addr.as_str(), true)) { match block_on(provider::get_provider_info_by_addr(
ctx,
addr.as_str(),
true,
))
.log_err(ctx)
.unwrap_or_default()
{
Some(provider) => provider, Some(provider) => provider,
None => ptr::null_mut(), None => ptr::null_mut(),
} }
@@ -4558,11 +4565,14 @@ pub unsafe extern "C" fn dc_provider_new_from_email_with_dns(
match socks5_enabled { match socks5_enabled {
Ok(socks5_enabled) => { Ok(socks5_enabled) => {
match block_on(provider::get_provider_info( match block_on(provider::get_provider_info_by_addr(
ctx, ctx,
addr.as_str(), addr.as_str(),
socks5_enabled, socks5_enabled,
)) { ))
.log_err(ctx)
.unwrap_or_default()
{
Some(provider) => provider, Some(provider) => provider,
None => ptr::null_mut(), None => ptr::null_mut(),
} }

View File

@@ -8,6 +8,7 @@ use trust_dns_resolver::{config, AsyncResolver, TokioAsyncResolver};
use crate::config::Config; use crate::config::Config;
use crate::context::Context; use crate::context::Context;
use crate::provider::data::{PROVIDER_DATA, PROVIDER_IDS}; use crate::provider::data::{PROVIDER_DATA, PROVIDER_IDS};
use crate::tools::EmailAddress;
/// Provider status according to manual testing. /// Provider status according to manual testing.
#[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)] #[derive(Debug, Display, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
@@ -175,21 +176,30 @@ fn get_resolver() -> Result<TokioAsyncResolver> {
Ok(resolver) Ok(resolver)
} }
/// Returns provider for the given an e-mail address.
///
/// Returns an error if provided address is not valid.
pub async fn get_provider_info_by_addr(
context: &Context,
addr: &str,
skip_mx: bool,
) -> Result<Option<&'static Provider>> {
let addr = EmailAddress::new(addr)?;
let provider = get_provider_info(context, &addr.domain, skip_mx).await;
Ok(provider)
}
/// Returns provider for the given domain. /// Returns provider for the given domain.
/// ///
/// This function looks up domain in offline database first. If not /// This function looks up domain in offline database first. If not
/// found, it queries MX record for the domain and looks up offline /// found, it queries MX record for the domain and looks up offline
/// database for MX domains. /// database for MX domains.
///
/// For compatibility, email address can be passed to this function
/// instead of the domain.
pub async fn get_provider_info( pub async fn get_provider_info(
context: &Context, context: &Context,
domain: &str, domain: &str,
skip_mx: bool, skip_mx: bool,
) -> Option<&'static Provider> { ) -> Option<&'static Provider> {
let domain = domain.rsplit('@').next()?;
if let Some(provider) = get_provider_by_domain(domain) { if let Some(provider) = get_provider_by_domain(domain) {
return Some(provider); return Some(provider);
} }
@@ -314,15 +324,25 @@ mod tests {
let t = TestContext::new().await; let t = TestContext::new().await;
assert!(get_provider_info(&t, "", false).await.is_none()); assert!(get_provider_info(&t, "", false).await.is_none());
assert!(get_provider_info(&t, "google.com", false).await.unwrap().id == "gmail"); assert!(get_provider_info(&t, "google.com", false).await.unwrap().id == "gmail");
assert!(get_provider_info(&t, "example@google.com", false)
.await
.is_none());
}
// get_provider_info() accepts email addresses for backwards compatibility #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_provider_info_by_addr() -> Result<()> {
let t = TestContext::new().await;
assert!(get_provider_info_by_addr(&t, "google.com", false)
.await
.is_err());
assert!( assert!(
get_provider_info(&t, "example@google.com", false) get_provider_info_by_addr(&t, "example@google.com", false)
.await .await?
.unwrap() .unwrap()
.id .id
== "gmail" == "gmail"
); );
Ok(())
} }
#[test] #[test]