Skip to content

Commit 7b2dd27

Browse files
committed
Add ProcessGlobals
This is akin to ExecutorGlobals, but for the process globals
1 parent 8b87e40 commit 7b2dd27

File tree

3 files changed

+102
-2
lines changed

3 files changed

+102
-2
lines changed

allowed_bindings.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,16 @@ bind! {
224224
gc_possible_root,
225225
ZEND_ACC_NOT_SERIALIZABLE,
226226
executor_globals,
227+
php_core_globals,
228+
core_globals,
227229
php_printf,
228230
__zend_malloc,
229231
tsrm_get_ls_cache,
230-
executor_globals_offset
232+
TRACK_VARS_POST,
233+
TRACK_VARS_GET,
234+
TRACK_VARS_COOKIE,
235+
TRACK_VARS_SERVER,
236+
TRACK_VARS_ENV,
237+
TRACK_VARS_FILES,
238+
TRACK_VARS_REQUEST
231239
}

src/zend/globals.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ use std::ops::{Deref, DerefMut};
55
use parking_lot::{const_rwlock, RwLock, RwLockReadGuard, RwLockWriteGuard};
66

77
use crate::boxed::ZBox;
8-
use crate::ffi::{_zend_executor_globals, ext_php_rs_executor_globals};
8+
use crate::ffi::{
9+
_zend_executor_globals, core_globals, ext_php_rs_executor_globals, php_core_globals,
10+
TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, TRACK_VARS_GET, TRACK_VARS_POST,
11+
TRACK_VARS_REQUEST, TRACK_VARS_SERVER,
12+
};
913

1014
use crate::types::{ZendHashTable, ZendObject};
1115

@@ -67,11 +71,98 @@ impl ExecutorGlobals {
6771
}
6872
}
6973

74+
/// Stores global variables used in the PHP executor.
75+
pub type ProcessGlobals = php_core_globals;
76+
77+
impl ProcessGlobals {
78+
/// Returns a reference to the PHP process globals.
79+
///
80+
/// The process globals are guarded by a RwLock. There can be multiple
81+
/// immutable references at one time but only ever one mutable reference.
82+
/// Attempting to retrieve the globals while already holding the global
83+
/// guard will lead to a deadlock. Dropping the globals guard will release
84+
/// the lock.
85+
pub fn get() -> GlobalReadGuard<Self> {
86+
// SAFETY: PHP executor globals are statically declared therefore should never
87+
// return an invalid pointer.
88+
let globals = unsafe { &core_globals };
89+
let guard = PROCESS_GLOBALS_LOCK.read();
90+
GlobalReadGuard { globals, guard }
91+
}
92+
93+
/// Returns a mutable reference to the PHP executor globals.
94+
///
95+
/// The executor globals are guarded by a RwLock. There can be multiple
96+
/// immutable references at one time but only ever one mutable reference.
97+
/// Attempting to retrieve the globals while already holding the global
98+
/// guard will lead to a deadlock. Dropping the globals guard will release
99+
/// the lock.
100+
pub fn get_mut() -> GlobalWriteGuard<Self> {
101+
// SAFETY: PHP executor globals are statically declared therefore should never
102+
// return an invalid pointer.
103+
let globals = unsafe { &mut core_globals };
104+
let guard = PROCESS_GLOBALS_LOCK.write();
105+
GlobalWriteGuard { globals, guard }
106+
}
107+
108+
/// Get the HTTP Server variables. Equivalent of $_SERVER.
109+
pub fn http_server_vars(&self) -> Option<&ZendHashTable> {
110+
if self.http_globals[TRACK_VARS_SERVER as usize].is_array() {
111+
self.http_globals[TRACK_VARS_SERVER as usize].array()
112+
} else {
113+
None
114+
}
115+
}
116+
117+
/// Get the HTTP POST variables. Equivalent of $_POST.
118+
pub fn http_post_vars(&self) -> &ZendHashTable {
119+
self.http_globals[TRACK_VARS_POST as usize]
120+
.array()
121+
.expect("Type is not a ZendArray")
122+
}
123+
124+
/// Get the HTTP GET variables. Equivalent of $_GET.
125+
pub fn http_get_vars(&self) -> &ZendHashTable {
126+
self.http_globals[TRACK_VARS_GET as usize]
127+
.array()
128+
.expect("Type is not a ZendArray")
129+
}
130+
131+
/// Get the HTTP Cookie variables. Equivalent of $_COOKIE.
132+
pub fn http_cookie_vars(&self) -> &ZendHashTable {
133+
self.http_globals[TRACK_VARS_COOKIE as usize]
134+
.array()
135+
.expect("Type is not a ZendArray")
136+
}
137+
138+
/// Get the HTTP Request variables. Equivalent of $_REQUEST.
139+
pub fn http_request_vars(&self) -> &ZendHashTable {
140+
self.http_globals[TRACK_VARS_REQUEST as usize]
141+
.array()
142+
.expect("Type is not a ZendArray")
143+
}
144+
145+
/// Get the HTTP Environment variables. Equivalent of $_ENV.
146+
pub fn http_env_vars(&self) -> &ZendHashTable {
147+
self.http_globals[TRACK_VARS_ENV as usize]
148+
.array()
149+
.expect("Type is not a ZendArray")
150+
}
151+
152+
/// Get the HTTP Files variables. Equivalent of $_FILES.
153+
pub fn http_files_vars(&self) -> &ZendHashTable {
154+
self.http_globals[TRACK_VARS_FILES as usize]
155+
.array()
156+
.expect("Type is not a ZendArray")
157+
}
158+
}
159+
70160
/// Executor globals rwlock.
71161
///
72162
/// PHP provides no indication if the executor globals are being accessed so
73163
/// this is only effective on the Rust side.
74164
static GLOBALS_LOCK: RwLock<()> = const_rwlock(());
165+
static PROCESS_GLOBALS_LOCK: RwLock<()> = const_rwlock(());
75166

76167
/// Wrapper guard that contains a reference to a given type `T`. Dropping a
77168
/// guard releases the lock on the relevant rwlock.

src/zend/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub use class::ClassEntry;
1717
pub use ex::ExecuteData;
1818
pub use function::FunctionEntry;
1919
pub use globals::ExecutorGlobals;
20+
pub use globals::ProcessGlobals;
2021
pub use handlers::ZendObjectHandlers;
2122
pub use module::ModuleEntry;
2223

0 commit comments

Comments
 (0)