diff options
author | Federico Mena Quintero <federico@gnome.org> | 2022-09-26 17:29:54 -0500 |
---|---|---|
committer | Federico Mena Quintero <federico@gnome.org> | 2022-09-26 19:07:30 -0500 |
commit | 8a225a3c5a4f2c89746d6d6d6cc83465da80ff87 (patch) | |
tree | fa2f03993e686cd8dacc93a62945963c7f1bd31a | |
parent | 6a5d15d61374292f244b235316dea5f83a2f0ca7 (diff) | |
download | librsvg-8a225a3c5a4f2c89746d6d6d6cc83465da80ff87.tar.gz |
Add helper function to avoid of trivial pointer casts that only appear on aarch64
On aarch64, libc::c_char is unsigned, so this produces a trivial cast
to u8:
let my_slice: &[u8] = std::slice::from_raw_parts(p as *const u8, len);
On Intel, libc::c_char is signed, and produces no such warning.
I couldn't find a way to do this without waerning; "*const _" fails;
plain "_" fails.
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/754>
-rw-r--r-- | src/util.rs | 20 | ||||
-rw-r--r-- | src/xml/attributes.rs | 4 | ||||
-rw-r--r-- | src/xml/xml2_load.rs | 6 |
3 files changed, 25 insertions, 5 deletions
diff --git a/src/util.rs b/src/util.rs index e308359a..1375b860 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::ffi::CStr; +use std::mem::transmute; use std::str; /// Converts a `char *` which is known to be valid UTF-8 into a `&str` @@ -32,6 +33,25 @@ pub unsafe fn cstr<'a>(s: *const libc::c_char) -> Cow<'a, str> { CStr::from_ptr(s).to_string_lossy() } +/// Casts a pointer to `c_char` to a pointer to `u8`. +/// +/// The obvious `p as *const u8` or `p as *const _` produces a +/// trivial_casts warning when compiled on aarch64, where `c_char` is +/// unsigned (on Intel, it is signed, so the cast works). +/// +/// We do this here with a `transmute`, which is awkward to type, +/// so wrap it in a function. +pub unsafe fn c_char_as_u8_ptr(p: *const libc::c_char) -> *const u8 { + transmute::<_, *const u8>(p) +} + +/// Casts a pointer to `c_char` to a pointer to mutable `u8`. +/// +/// See [`c_char_as_u8_ptr`] for the reason for this. +pub unsafe fn c_char_as_u8_ptr_mut(p: *mut libc::c_char) -> *mut u8 { + transmute::<_, *mut u8>(p) +} + pub fn clamp<T: PartialOrd>(val: T, low: T, high: T) -> T { if val < low { low diff --git a/src/xml/attributes.rs b/src/xml/attributes.rs index 9c8ebe96..844066cd 100644 --- a/src/xml/attributes.rs +++ b/src/xml/attributes.rs @@ -10,7 +10,7 @@ use string_cache::DefaultAtom; use crate::error::{ImplementationLimit, LoadingError}; use crate::limits; -use crate::util::{opt_utf8_cstr, utf8_cstr}; +use crate::util::{c_char_as_u8_ptr, opt_utf8_cstr, utf8_cstr}; /// Type used to store attribute values. /// @@ -103,7 +103,7 @@ impl Attributes { let end = value_end as usize; let len = end - start; - let value_slice = slice::from_raw_parts(value_start as *const u8, len); + let value_slice = slice::from_raw_parts(c_char_as_u8_ptr(value_start), len); let value_str = str::from_utf8_unchecked(value_slice); let value_atom = DefaultAtom::from(value_str); diff --git a/src/xml/xml2_load.rs b/src/xml/xml2_load.rs index c916c4f7..9dcdac4e 100644 --- a/src/xml/xml2_load.rs +++ b/src/xml/xml2_load.rs @@ -16,7 +16,7 @@ use glib::translate::*; use markup5ever::{namespace_url, ns, LocalName, Namespace, Prefix, QualName}; use crate::error::LoadingError; -use crate::util::{cstr, opt_utf8_cstr, utf8_cstr}; +use crate::util::{c_char_as_u8_ptr, c_char_as_u8_ptr_mut, cstr, opt_utf8_cstr, utf8_cstr}; use super::xml2::*; use super::Attributes; @@ -267,7 +267,7 @@ unsafe extern "C" fn sax_characters_cb( // libxml2 already validated the incoming string as UTF-8. Note that // it is *not* nul-terminated; this is why we create a byte slice first. - let bytes = std::slice::from_raw_parts(unterminated_text as *const u8, len as usize); + let bytes = std::slice::from_raw_parts(c_char_as_u8_ptr(unterminated_text), len as usize); let utf8 = str::from_utf8_unchecked(bytes); xml2_parser.state.characters(utf8); @@ -347,7 +347,7 @@ unsafe extern "C" fn stream_ctx_read( return -1; } - let buf: &mut [u8] = slice::from_raw_parts_mut(buffer as *mut u8, len as usize); + let buf: &mut [u8] = slice::from_raw_parts_mut(c_char_as_u8_ptr_mut(buffer), len as usize); match ctx.stream.read(buf, ctx.cancellable.as_ref()) { Ok(size) => size as libc::c_int, |