• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

davidcole1340 / ext-php-rs / 16006197694

01 Jul 2025 05:33PM UTC coverage: 21.654% (-0.3%) from 21.978%
16006197694

Pull #471

github

web-flow
Merge 7af465c1e into 68e218f9b
Pull Request #471: feat(sapi): expand `SapiBuilder`

66 of 69 new or added lines in 1 file covered. (95.65%)

748 existing lines in 21 files now uncovered.

830 of 3833 relevant lines covered (21.65%)

3.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/src/alloc.rs
1
//! Functions relating to the Zend Memory Manager, used to allocate
2
//! request-bound memory.
3

4
use cfg_if::cfg_if;
5

6
use crate::ffi::{_efree, _emalloc, _estrdup};
7
use std::{
8
    alloc::Layout,
9
    ffi::{c_char, c_void, CString},
10
};
11

12
/// Uses the PHP memory allocator to allocate request-bound memory.
13
///
14
/// # Parameters
15
///
16
/// * `layout` - The layout of the requested memory.
17
///
18
/// # Returns
19
///
20
/// A pointer to the memory allocated.
21
#[must_use]
22
pub fn emalloc(layout: Layout) -> *mut u8 {
1✔
23
    // TODO account for alignment
24
    let size = layout.size();
3✔
25

26
    (unsafe {
27
        cfg_if! {
28
            if #[cfg(php_debug)] {
29
                #[allow(clippy::used_underscore_items)]
30
                _emalloc(size as _, std::ptr::null_mut(), 0, std::ptr::null_mut(), 0)
31
            } else {
32
                #[allow(clippy::used_underscore_items)]
33
                _emalloc(size as _)
2✔
34
            }
35
        }
36
    })
37
    .cast::<u8>()
38
}
39

40
/// Frees a given memory pointer which was allocated through the PHP memory
41
/// manager.
42
///
43
/// # Parameters
44
///
45
/// * `ptr` - The pointer to the memory to free.
46
///
47
/// # Safety
48
///
49
/// Caller must guarantee that the given pointer is valid (aligned and non-null)
50
/// and was originally allocated through the Zend memory manager.
51
pub unsafe fn efree(ptr: *mut u8) {
2✔
52
    cfg_if! {
53
        if #[cfg(php_debug)] {
54
            #[allow(clippy::used_underscore_items)]
55
            _efree(
56
                ptr.cast::<c_void>(),
57
                std::ptr::null_mut(),
58
                0,
59
                std::ptr::null_mut(),
60
                0,
61
            )
62
        } else {
63
            #[allow(clippy::used_underscore_items)]
64
            _efree(ptr.cast::<c_void>());
6✔
65
        }
66
    }
67
}
68

69
/// Duplicates a string using the PHP memory manager.
70
///
71
/// # Parameters
72
///
73
/// * `string` - The string to duplicate, which can be any type that can be
74
///   converted into a `Vec<u8>`.
75
///
76
/// # Returns
77
///
78
/// A pointer to the duplicated string in the PHP memory manager.
79
pub fn estrdup(string: impl Into<Vec<u8>>) -> *mut c_char {
1✔
80
    let string = unsafe { CString::from_vec_unchecked(string.into()) }.into_raw();
5✔
81

82
    let result = unsafe {
UNCOV
83
        cfg_if! {
×
UNCOV
84
            if #[cfg(php_debug)] {
×
UNCOV
85
                #[allow(clippy::used_underscore_items)]
×
UNCOV
86
                _estrdup(string, std::ptr::null_mut(), 0, std::ptr::null_mut(), 0)
×
87
            } else {
UNCOV
88
                #[allow(clippy::used_underscore_items)]
×
89
                _estrdup(string)
2✔
90
            }
91
        }
92
    };
93

94
    drop(unsafe { CString::from_raw(string) });
3✔
95
    result
1✔
96
}
97

98
#[cfg(test)]
99
#[cfg(feature = "embed")]
100
mod test {
101
    use super::*;
102
    use crate::embed::Embed;
103
    use std::ffi::CStr;
104

105
    #[test]
106
    fn test_emalloc() {
107
        Embed::run(|| {
108
            let layout = Layout::from_size_align(16, 8).expect("should create layout");
109
            let ptr = emalloc(layout);
110
            assert!(!ptr.is_null());
111
            unsafe { efree(ptr) };
112
        });
113
    }
114

115
    #[test]
116
    fn test_estrdup() {
117
        Embed::run(|| {
118
            let original = "Hello, world!";
119
            let duplicated = estrdup(original);
120
            assert!(!duplicated.is_null());
121

122
            let duplicated_str = unsafe { CStr::from_ptr(duplicated) };
123
            assert_eq!(
124
                duplicated_str.to_str().expect("should convert to str"),
125
                original
126
            );
127

128
            unsafe { efree(duplicated.cast::<u8>()) }
129
        });
130
    }
131
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc