From d9b3e745ccb37f4f2dcfead3caca48362c57ce0e Mon Sep 17 00:00:00 2001 From: Pratik Chowdhury <28534575+pratikpc@users.noreply.github.com> Date: Mon, 20 May 2024 18:59:52 +0000 Subject: [PATCH] refactor(ada_owned_string->String): change return type from ada_owned_string to String Ensures that ada_owned_string does not leak to user space and allows us to make internal breaking changes to its implementation. Fixes all leak issue. Causes small performance downgrades due to copies. Causes functions to be usable only if std is enabled. BREAKING CHANGE: Return type changed from ada_owned_string->String. Functions now work only with std feature enabled. --- src/idna.rs | 34 ++++++++++++++++++++-------------- src/lib.rs | 18 ++++++++++++++---- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/idna.rs b/src/idna.rs index 078ea6a..d6d6832 100644 --- a/src/idna.rs +++ b/src/idna.rs @@ -1,5 +1,12 @@ +#[cfg(feature = "std")] +extern crate std; + +#[cfg_attr(not(feature = "std"), allow(unused_imports))] use crate::ffi; +#[cfg(feature = "std")] +use std::string::String; + /// IDNA struct implements the `to_ascii` and `to_unicode` functions from the Unicode Technical /// Standard supporting a wide range of systems. It is suitable for URL parsing. /// For more information, [read the specification](https://www.unicode.org/reports/tr46/#ToUnicode) @@ -13,11 +20,12 @@ impl Idna { /// /// ``` /// use ada_url::Idna; - /// assert_eq!(Idna::unicode("xn--meagefactory-m9a.ca").as_ref(), "meßagefactory.ca"); + /// assert_eq!(Idna::unicode("xn--meagefactory-m9a.ca"), "meßagefactory.ca"); /// ``` #[must_use] - pub fn unicode(input: &str) -> ffi::ada_owned_string { - unsafe { ffi::ada_idna_to_unicode(input.as_ptr().cast(), input.len()) } + #[cfg(feature = "std")] + pub fn unicode(input: &str) -> String { + unsafe { ffi::ada_idna_to_unicode(input.as_ptr().cast(), input.len()) }.to_string() } /// Process international domains according to the UTS #46 standard. @@ -27,31 +35,29 @@ impl Idna { /// /// ``` /// use ada_url::Idna; - /// assert_eq!(Idna::ascii("meßagefactory.ca").as_ref(), "xn--meagefactory-m9a.ca"); + /// assert_eq!(Idna::ascii("meßagefactory.ca"), "xn--meagefactory-m9a.ca"); /// ``` #[must_use] - pub fn ascii(input: &str) -> ffi::ada_owned_string { - unsafe { ffi::ada_idna_to_ascii(input.as_ptr().cast(), input.len()) } + #[cfg(feature = "std")] + pub fn ascii(input: &str) -> String { + unsafe { ffi::ada_idna_to_ascii(input.as_ptr().cast(), input.len()) }.to_string() } } #[cfg(test)] mod tests { + #[cfg_attr(not(feature = "std"), allow(unused_imports))] use crate::idna::*; #[test] fn unicode_should_work() { - assert_eq!( - Idna::unicode("xn--meagefactory-m9a.ca").as_ref(), - "meßagefactory.ca" - ); + #[cfg(feature = "std")] + assert_eq!(Idna::unicode("xn--meagefactory-m9a.ca"), "meßagefactory.ca"); } #[test] fn ascii_should_work() { - assert_eq!( - Idna::ascii("meßagefactory.ca").as_ref(), - "xn--meagefactory-m9a.ca" - ); + #[cfg(feature = "std")] + assert_eq!(Idna::ascii("meßagefactory.ca"), "xn--meagefactory-m9a.ca"); } } diff --git a/src/lib.rs b/src/lib.rs index a8a94bf..8199db8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,12 @@ pub mod ffi; mod idna; pub use idna::Idna; +#[cfg(feature = "std")] +extern crate std; + +#[cfg(feature = "std")] +use std::string::String; + use core::{borrow, ffi::c_uint, fmt, hash, ops}; use derive_more::Display; @@ -267,11 +273,12 @@ impl Url { /// use ada_url::Url; /// /// let url = Url::parse("blob:https://example.com/foo", None).expect("Invalid URL"); - /// assert_eq!(url.origin().as_ref(), "https://example.com"); + /// assert_eq!(url.origin(), "https://example.com"); /// ``` #[must_use] - pub fn origin(&self) -> ffi::ada_owned_string { - unsafe { ffi::ada_get_origin(self.0) } + #[cfg(feature = "std")] + pub fn origin(&self) -> String { + unsafe { ffi::ada_get_origin(self.0) }.to_string() } /// Return the parsed version of the URL with all components. @@ -945,7 +952,10 @@ mod test { None, ) .expect("Should have parsed a simple url"); - assert_eq!(out.origin().as_ref(), "https://google.com:9090"); + + #[cfg(feature = "std")] + assert_eq!(out.origin(), "https://google.com:9090"); + assert_eq!( out.href(), "https://username:password@google.com:9090/search?query#hash"