summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2022-09-26 17:29:54 -0500
committerFederico Mena Quintero <federico@gnome.org>2022-09-26 19:07:30 -0500
commit8a225a3c5a4f2c89746d6d6d6cc83465da80ff87 (patch)
treefa2f03993e686cd8dacc93a62945963c7f1bd31a
parent6a5d15d61374292f244b235316dea5f83a2f0ca7 (diff)
downloadlibrsvg-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.rs20
-rw-r--r--src/xml/attributes.rs4
-rw-r--r--src/xml/xml2_load.rs6
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,