[Pkg-rust-maintainers] Bug#1120061: rust-apr - FTBFS on most architectures, issues with the signedness of char.

Peter Green plugwash at debian.org
Tue Nov 4 17:01:57 GMT 2025


Package: rust-apr
Version: 0.3.3-1
Severity: serious

Many apis in apr use the C type "char", depending on the architecture
this may map to either the i8 (x86-64, loong64) or the u8 (arm64,
ppc64el, s390x, ppc64) type in rust. The standard library offers
a type alias "c_char" which is an alias for either i8 or u8 depending
on the architecture.

However, rust-apr has a bunch of hardcoded use of i8, which causes
it to fail to build on architectures where char is unsigned.

Attatched is a patch that fixes that.
-------------- next part --------------
Index: rust-apr-0.3.3/src/base64.rs
===================================================================
--- rust-apr-0.3.3.orig/src/base64.rs
+++ rust-apr-0.3.3/src/base64.rs
@@ -2,6 +2,7 @@
 
 use crate::{Error, Status};
 use std::ffi::CString;
+use std::ffi::c_char;
 
 /// Get the length of the encoded base64 string for a given input length.
 pub fn base64_encode_len(len: usize) -> usize {
@@ -24,7 +25,7 @@ pub fn base64_encode(data: &[u8]) -> Str
 
     unsafe {
         apr_sys::apr_base64_encode_binary(
-            encoded.as_mut_ptr() as *mut i8,
+            encoded.as_mut_ptr() as *mut c_char,
             data.as_ptr(),
             data.len() as i32,
         );
Index: rust-apr-0.3.3/src/crypto.rs
===================================================================
--- rust-apr-0.3.3.orig/src/crypto.rs
+++ rust-apr-0.3.3/src/crypto.rs
@@ -6,6 +6,7 @@
 use crate::pool::Pool;
 use crate::{Error, Status};
 use std::ffi::CString;
+use std::ffi::c_char;
 use std::marker::PhantomData;
 use std::ptr;
 
@@ -124,7 +125,7 @@ pub fn get_driver<'pool>(name: &str, poo
         .map_err(|_| Error::from_status(Status::from(apr_sys::APR_EINVAL as i32)))?;
 
     let mut driver: *const apr_sys::apr_crypto_driver_t = ptr::null();
-    let params_ptr: *const i8 = ptr::null();
+    let params_ptr: *const c_char = ptr::null();
     let mut error_ptr: *const apr_sys::apu_err_t = ptr::null();
 
     let status = unsafe {
@@ -164,7 +165,7 @@ impl<'pool> CryptoDriver<'pool> {
     /// Create a crypto factory from this driver.
     pub fn make_crypto(&self, pool: &'pool Pool) -> Result<Crypto<'pool>, Error> {
         let mut factory: *mut apr_sys::apr_crypto_t = ptr::null_mut();
-        let params_ptr: *const i8 = ptr::null();
+        let params_ptr: *const c_char = ptr::null();
 
         let status = unsafe {
             apr_sys::apr_crypto_make(
@@ -202,7 +203,7 @@ impl<'pool> Crypto<'pool> {
             apr_sys::apr_crypto_passphrase(
                 &mut key,
                 &mut iv_size,
-                key_data.as_ptr() as *const i8,
+                key_data.as_ptr() as *const c_char,
                 key_data.len() as apr_sys::apr_size_t,
                 ptr::null(), // salt
                 0,           // saltLen
Index: rust-apr-0.3.3/src/md5.rs
===================================================================
--- rust-apr-0.3.3.orig/src/md5.rs
+++ rust-apr-0.3.3/src/md5.rs
@@ -3,6 +3,7 @@
 use crate::pool::Pool;
 use crate::{Error, Status};
 use std::ffi::CStr;
+use std::ffi::c_char;
 use std::marker::PhantomData;
 use std::mem::MaybeUninit;
 
@@ -98,13 +99,13 @@ pub fn md5_encode_password(password: &st
         apr_sys::apr_md5_encode(
             password_cstr.as_ptr(),
             salt_cstr.as_ptr(),
-            result_buf.as_mut_ptr() as *mut i8,
+            result_buf.as_mut_ptr() as *mut c_char,
             result_buf.len() as apr_sys::apr_size_t,
         )
     };
 
     if status == apr_sys::APR_SUCCESS as i32 {
-        let cstr = unsafe { CStr::from_ptr(result_buf.as_ptr() as *const i8) };
+        let cstr = unsafe { CStr::from_ptr(result_buf.as_ptr() as *const c_char) };
         Ok(cstr.to_string_lossy().into_owned())
     } else {
         Err(Error::from_status(Status::from(status)))
Index: rust-apr-0.3.3/src/network.rs
===================================================================
--- rust-apr-0.3.3.orig/src/network.rs
+++ rust-apr-0.3.3/src/network.rs
@@ -2,6 +2,7 @@
 
 use crate::{pool::Pool, Result};
 use std::ffi::{CStr, CString};
+use std::ffi::c_char;
 use std::marker::PhantomData;
 use std::net::{Ipv4Addr, Ipv6Addr};
 use std::ptr;
@@ -300,7 +301,7 @@ impl<'a> Socket<'a> {
     pub fn send(&mut self, data: &[u8]) -> Result<usize> {
         let mut len = data.len();
         let status =
-            unsafe { apr_sys::apr_socket_send(self.raw, data.as_ptr() as *const i8, &mut len) };
+            unsafe { apr_sys::apr_socket_send(self.raw, data.as_ptr() as *const c_char, &mut len) };
 
         if status != apr_sys::APR_SUCCESS as i32 {
             return Err(crate::Error::from_status(status.into()));
@@ -313,7 +314,7 @@ impl<'a> Socket<'a> {
     pub fn recv(&mut self, buf: &mut [u8]) -> Result<usize> {
         let mut len = buf.len();
         let status =
-            unsafe { apr_sys::apr_socket_recv(self.raw, buf.as_mut_ptr() as *mut i8, &mut len) };
+            unsafe { apr_sys::apr_socket_recv(self.raw, buf.as_mut_ptr() as *mut c_char, &mut len) };
 
         if status != apr_sys::APR_SUCCESS as i32 && status != apr_sys::APR_EOF as i32 {
             return Err(crate::Error::from_status(status.into()));
@@ -326,7 +327,7 @@ impl<'a> Socket<'a> {
     pub fn sendto(&mut self, data: &[u8], addr: &SockAddr) -> Result<usize> {
         let mut len = data.len();
         let status = unsafe {
-            apr_sys::apr_socket_sendto(self.raw, addr.raw, 0, data.as_ptr() as *const i8, &mut len)
+            apr_sys::apr_socket_sendto(self.raw, addr.raw, 0, data.as_ptr() as *const c_char, &mut len)
         };
 
         if status != apr_sys::APR_SUCCESS as i32 {
@@ -346,7 +347,7 @@ impl<'a> Socket<'a> {
                 from_addr,
                 self.raw,
                 0,
-                buf.as_mut_ptr() as *mut i8,
+                buf.as_mut_ptr() as *mut c_char,
                 &mut len,
             )
         };
@@ -459,7 +460,7 @@ impl<'a> Drop for Socket<'a> {
 
 /// Get the hostname of the local machine
 pub fn hostname_get(pool: &Pool) -> Result<String> {
-    let hostname_buf = unsafe { apr_sys::apr_palloc(pool.as_mut_ptr(), 256) as *mut i8 };
+    let hostname_buf = unsafe { apr_sys::apr_palloc(pool.as_mut_ptr(), 256) as *mut c_char };
 
     if hostname_buf.is_null() {
         return Err(crate::Error::from_status(apr_sys::APR_ENOMEM.into()));
Index: rust-apr-0.3.3/src/uuid.rs
===================================================================
--- rust-apr-0.3.3.orig/src/uuid.rs
+++ rust-apr-0.3.3/src/uuid.rs
@@ -2,6 +2,7 @@
 
 use crate::{Error, Status};
 use std::ffi::CStr;
+use std::ffi::c_char;
 use std::fmt;
 
 /// A universally unique identifier (UUID).
@@ -43,9 +44,9 @@ impl Uuid {
     pub fn format(&self) -> String {
         let mut buffer = vec![0u8; 37]; // 36 chars + null terminator
         unsafe {
-            apr_sys::apr_uuid_format(buffer.as_mut_ptr() as *mut i8, &self.uuid);
+            apr_sys::apr_uuid_format(buffer.as_mut_ptr() as *mut c_char, &self.uuid);
         }
-        let c_str = unsafe { CStr::from_ptr(buffer.as_ptr() as *const i8) };
+        let c_str = unsafe { CStr::from_ptr(buffer.as_ptr() as *const c_char) };
         c_str.to_string_lossy().into_owned()
     }
 
Index: rust-apr-0.3.3/src/xlate.rs
===================================================================
--- rust-apr-0.3.3.orig/src/xlate.rs
+++ rust-apr-0.3.3/src/xlate.rs
@@ -5,6 +5,7 @@
 use crate::pool::Pool;
 use crate::{Error, Status};
 use std::ffi::CString;
+use std::ffi::c_char;
 use std::marker::PhantomData;
 use std::ptr;
 
@@ -52,8 +53,8 @@ impl<'pool> Xlate<'pool> {
         let mut outbytes_left = inbytes_left * 4; // Allocate extra space for worst case
         let mut output = vec![0u8; outbytes_left];
 
-        let inbuf_ptr = input_bytes.as_ptr() as *const i8;
-        let outbuf_ptr = output.as_mut_ptr() as *mut i8;
+        let inbuf_ptr = input_bytes.as_ptr() as *const c_char;
+        let outbuf_ptr = output.as_mut_ptr() as *mut c_char;
 
         let status = unsafe {
             apr_sys::apr_xlate_conv_buffer(
@@ -81,8 +82,8 @@ impl<'pool> Xlate<'pool> {
         let mut outbytes_left = inbytes_left * 4; // Allocate extra space for worst case
         let mut output = vec![0u8; outbytes_left];
 
-        let inbuf_ptr = input.as_ptr() as *const i8;
-        let outbuf_ptr = output.as_mut_ptr() as *mut i8;
+        let inbuf_ptr = input.as_ptr() as *const c_char;
+        let outbuf_ptr = output.as_mut_ptr() as *mut c_char;
 
         let status = unsafe {
             apr_sys::apr_xlate_conv_buffer(
Index: rust-apr-0.3.3/src/xml.rs
===================================================================
--- rust-apr-0.3.3.orig/src/xml.rs
+++ rust-apr-0.3.3/src/xml.rs
@@ -5,6 +5,7 @@
 use crate::pool::Pool;
 use crate::{Error, Status};
 use std::ffi::CStr;
+use std::ffi::c_char;
 use std::marker::PhantomData;
 use std::ptr;
 
@@ -53,7 +54,7 @@ impl<'pool> XmlParser<'pool> {
         let status = unsafe {
             apr_sys::apr_xml_parser_feed(
                 self.parser,
-                data.as_ptr() as *const i8,
+                data.as_ptr() as *const c_char,
                 data.len() as apr_sys::apr_size_t,
             )
         };
@@ -83,7 +84,7 @@ impl<'pool> XmlParser<'pool> {
 
     /// Get error information if parsing failed.
     pub fn get_error(&self) -> Option<String> {
-        let mut errbuf = [0i8; 200];
+        let mut errbuf = [0 as c_char; 200];
         let errbufsize = errbuf.len() as apr_sys::apr_size_t;
 
         unsafe {
@@ -117,7 +118,7 @@ impl<'pool> XmlDoc<'pool> {
 
     /// Convert the document to a string representation.
     pub fn to_string(&self, pool: &Pool, style: i32) -> Result<String, Error> {
-        let mut buf_ptr: *const i8 = ptr::null();
+        let mut buf_ptr: *const c_char = ptr::null();
 
         unsafe {
             apr_sys::apr_xml_to_text(


More information about the Pkg-rust-maintainers mailing list