From bb872bef3c4d5bd5a52ea705c27f2b41fc8aa423 Mon Sep 17 00:00:00 2001 From: Slatian Date: Thu, 23 Feb 2023 13:20:18 +0100 Subject: [PATCH] Fixed some idn edge cases --- src/idna.rs | 6 +++++- src/main.rs | 29 +++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/idna.rs b/src/idna.rs index 39fb75f..9235420 100644 --- a/src/idna.rs +++ b/src/idna.rs @@ -11,8 +11,8 @@ use ::idna; #[derive(Deserialize, Serialize, Copy, Default, Clone, PartialEq)] #[serde(rename_all="lowercase")] pub enum NameType { - Ascii, #[default] + Ascii, Unicode, IDN, } @@ -33,6 +33,10 @@ pub struct IdnaName { impl IdnaName { pub fn from_string(s: &String) -> Self { + if s == "" { + return Default::default(); + } + let mut original_was = NameType::Unicode; let unicode: String; let decoder_error; diff --git a/src/main.rs b/src/main.rs index 587d70e..11d00a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -73,11 +73,16 @@ pub struct IpResult { ip_info: AddressInfo, } +// We need this one to hide the partial lookup field when irelevant +pub fn not(b: &bool) -> bool { !b } + #[derive(serde::Deserialize, serde::Serialize, Default, Clone)] pub struct DigResult { records: simple_dns::DnsLookupResult, #[serde(skip_serializing_if = "IdnaName::was_ascii")] idn: IdnaName, + #[serde(skip_serializing_if = "not")] + partial_lookup: bool, } struct ServiceSharedState { @@ -311,7 +316,9 @@ async fn handle_default_route( let state = Arc::clone(&arc_state); if let Some(search_query) = search_query.query { - return handle_search_request(search_query, false, settings, state).await; + if search_query.trim() != "" { + return handle_search_request(search_query, false, settings, state).await; + } } let result = get_ip_result(&address, &settings.lang, &state).await; @@ -333,7 +340,7 @@ async fn handle_default_route( async fn handle_search_request( search_query: String, - _this_should_have_been_an_ip: bool, + this_should_have_been_an_ip: bool, settings: TemplateSettings, arc_state: Arc, ) -> Response { @@ -362,7 +369,10 @@ async fn handle_search_request( } // Fall back to treating it as a hostname - return handle_dig_request(search_query.to_string(), settings, arc_state).await + return handle_dig_request( + search_query.to_string(), settings, arc_state, + !this_should_have_been_an_ip, + ).await } @@ -455,18 +465,19 @@ async fn handle_dig_route_with_path( State(arc_state): State>, extract::Path(name): extract::Path, ) -> Response { - return handle_dig_request(name, settings, arc_state).await + return handle_dig_request(name, settings, arc_state, true).await } async fn handle_dig_request( dig_query: String, settings: TemplateSettings, arc_state: Arc, + do_full_lookup: bool, ) -> Response { let state = Arc::clone(&arc_state); - let dig_result = get_dig_result(&dig_query, &state).await; + let dig_result = get_dig_result(&dig_query, &state, do_full_lookup).await; state.templating_engine.render_view( &settings, @@ -476,8 +487,9 @@ async fn handle_dig_request( } async fn get_dig_result( - dig_query: &String, - state: &ServiceSharedState, + dig_query: &String, + state: &ServiceSharedState, + do_full_lookup: bool, ) -> DigResult { let name = &dig_query.trim().trim_end_matches(".").to_string(); if match_domain_hidden_list(&name, &state.config.dns.hidden_suffixes) { @@ -488,8 +500,9 @@ async fn get_dig_result( records: simple_dns::lookup( &state.dns_resolver, &(idna_name.idn.clone().unwrap_or(name.to_owned())+"."), - true).await, + do_full_lookup).await, idn: idna_name, + partial_lookup: !do_full_lookup, } } }