Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

glib: Remove ending NUL when converting Variant to OsString. #625

Merged
merged 1 commit into from Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions glib/src/translate.rs
Expand Up @@ -579,7 +579,7 @@ impl GlibPtrDefault for String {
}

#[cfg(not(windows))]
fn path_to_c(path: &Path) -> CString {
pub(crate) fn path_to_c(path: &Path) -> CString {
// GLib paths on UNIX are always in the local encoding, just like in Rust
//
// Paths on UNIX must not contain NUL bytes, in which case the conversion
Expand All @@ -589,7 +589,7 @@ fn path_to_c(path: &Path) -> CString {
}

#[cfg(windows)]
fn path_to_c(path: &Path) -> CString {
pub(crate) fn path_to_c(path: &Path) -> CString {
// GLib paths are always UTF-8 strings on Windows, while in Rust they are
// WTF-8. As such, we need to convert to a UTF-8 string. This conversion can
// fail, see https://simonsapin.github.io/wtf-8/#converting-wtf-8-utf-8
Expand Down Expand Up @@ -617,7 +617,7 @@ fn path_to_c(path: &Path) -> CString {
}

#[cfg(not(windows))]
fn os_str_to_c(s: &OsStr) -> CString {
pub(crate) fn os_str_to_c(s: &OsStr) -> CString {
// GLib OS string (environment strings) on UNIX are always in the local encoding,
// just like in Rust
//
Expand All @@ -628,7 +628,7 @@ fn os_str_to_c(s: &OsStr) -> CString {
}

#[cfg(windows)]
fn os_str_to_c(s: &OsStr) -> CString {
pub(crate) fn os_str_to_c(s: &OsStr) -> CString {
// GLib OS string (environment strings) are always UTF-8 strings on Windows,
// while in Rust they are WTF-8. As such, we need to convert to a UTF-8 string.
// This conversion can fail, see https://simonsapin.github.io/wtf-8/#converting-wtf-8-utf-8
Expand Down Expand Up @@ -1516,7 +1516,7 @@ impl FromGlibPtrFull<*mut c_char> for String {
}

#[cfg(not(windows))]
unsafe fn c_to_path_buf(ptr: *const c_char) -> PathBuf {
pub(crate) unsafe fn c_to_path_buf(ptr: *const c_char) -> PathBuf {
assert!(!ptr.is_null());

// GLib paths on UNIX are always in the local encoding, which can be
Expand All @@ -1526,7 +1526,7 @@ unsafe fn c_to_path_buf(ptr: *const c_char) -> PathBuf {
}

#[cfg(windows)]
unsafe fn c_to_path_buf(ptr: *const c_char) -> PathBuf {
pub(crate) unsafe fn c_to_path_buf(ptr: *const c_char) -> PathBuf {
assert!(!ptr.is_null());

// GLib paths on Windows are always UTF-8, as such we can convert to a String
Expand All @@ -1539,7 +1539,7 @@ unsafe fn c_to_path_buf(ptr: *const c_char) -> PathBuf {
}

#[cfg(not(windows))]
unsafe fn c_to_os_string(ptr: *const c_char) -> OsString {
pub(crate) unsafe fn c_to_os_string(ptr: *const c_char) -> OsString {
assert!(!ptr.is_null());

// GLib OS string (environment strings) on UNIX are always in the local encoding,
Expand All @@ -1549,7 +1549,7 @@ unsafe fn c_to_os_string(ptr: *const c_char) -> OsString {
}

#[cfg(windows)]
unsafe fn c_to_os_string(ptr: *const c_char) -> OsString {
pub(crate) unsafe fn c_to_os_string(ptr: *const c_char) -> OsString {
assert!(!ptr.is_null());

// GLib OS string (environment strings) on Windows are always UTF-8,
Expand Down
117 changes: 15 additions & 102 deletions glib/src/variant.rs
Expand Up @@ -14,13 +14,6 @@
//! a full list of supported types. You may also implement [`ToVariant`] and [`FromVariant`]
//! manually, or derive them using the [`Variant`](derive@crate::Variant) derive macro.
//!
//! ## Portability Warning
//!
//! Variant conversion traits are also implemented for certain platform-specific data types from
//! the standard library like [`PathBuf`](std::path::PathBuf) and [`OsString`](std::ffi::OsString).
//! These types will be serialized to their platform-specific representation and **should not** be
//! deserialized on a different machine from where they were serialized.
//!
//! # Examples
//!
//! ```
Expand Down Expand Up @@ -1134,151 +1127,71 @@ impl ToVariant for str {
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(any(unix, windows))]
impl StaticVariantType for std::path::PathBuf {
fn static_variant_type() -> Cow<'static, VariantTy> {
std::ffi::OsStr::static_variant_type()
std::path::Path::static_variant_type()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(any(unix, windows))]
impl ToVariant for std::path::PathBuf {
fn to_variant(&self) -> Variant {
self.as_os_str().to_variant()
self.as_path().to_variant()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(any(unix, windows))]
impl FromVariant for std::path::PathBuf {
fn from_variant(variant: &Variant) -> Option<Self> {
Some(std::ffi::OsString::from_variant(variant)?.into())
unsafe {
let ptr = ffi::g_variant_get_bytestring(variant.to_glib_none().0);
Some(crate::translate::c_to_path_buf(ptr as *const _))
}
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(any(unix, windows))]
impl StaticVariantType for std::path::Path {
fn static_variant_type() -> Cow<'static, VariantTy> {
std::ffi::OsStr::static_variant_type()
<&[u8]>::static_variant_type()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(any(unix, windows))]
impl ToVariant for std::path::Path {
fn to_variant(&self) -> Variant {
self.as_os_str().to_variant()
let tmp = crate::translate::path_to_c(self);
unsafe { from_glib_none(ffi::g_variant_new_bytestring(tmp.as_ptr() as *const u8)) }
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(any(unix, windows))]
impl StaticVariantType for std::ffi::OsString {
fn static_variant_type() -> Cow<'static, VariantTy> {
std::ffi::OsStr::static_variant_type()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(any(unix, windows))]
impl ToVariant for std::ffi::OsString {
fn to_variant(&self) -> Variant {
self.as_os_str().to_variant()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(unix)]
impl FromVariant for std::ffi::OsString {
fn from_variant(variant: &Variant) -> Option<Self> {
let bytes = <_>::from_variant(variant)?;
Some(std::os::unix::ffi::OsStringExt::from_vec(bytes))
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(windows)]
impl FromVariant for std::ffi::OsString {
fn from_variant(variant: &Variant) -> Option<Self> {
let wide = <Vec<u16>>::from_variant(variant)?;
Some(std::os::windows::ffi::OsStringExt::from_wide(&wide))
unsafe {
let ptr = ffi::g_variant_get_bytestring(variant.to_glib_none().0);
Some(crate::translate::c_to_os_string(ptr as *const _))
}
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(unix)]
impl StaticVariantType for std::ffi::OsStr {
fn static_variant_type() -> Cow<'static, VariantTy> {
<&[u8]>::static_variant_type()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(unix)]
impl ToVariant for std::ffi::OsStr {
fn to_variant(&self) -> Variant {
use std::os::unix::ffi::OsStrExt;
self.as_bytes().to_variant()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(windows)]
impl StaticVariantType for std::ffi::OsStr {
fn static_variant_type() -> Cow<'static, VariantTy> {
<&[u16]>::static_variant_type()
}
}

/// ## Portability Warning
///
/// This impl is for a platform-specific type. Any variants serialized from this type should be
/// deserialized on the same machine.
#[cfg(windows)]
impl ToVariant for std::ffi::OsStr {
fn to_variant(&self) -> Variant {
use std::os::windows::ffi::OsStrExt;
let wide = self.encode_wide().collect::<Vec<u16>>();
wide.to_variant()
let tmp = crate::translate::os_str_to_c(self);
unsafe { from_glib_none(ffi::g_variant_new_bytestring(tmp.as_ptr() as *const u8)) }
}
}

Expand Down