From ed02cf6d06b01697e21ff53e1d5dcc3a069b7e65 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Mon, 21 Oct 2024 23:33:14 +0200 Subject: [PATCH 1/9] fix(globals): correctly fetch `$_REQUEST` super global Refs: #331 --- allowed_bindings.rs | 3 +++ src/zend/globals.rs | 39 ++++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/allowed_bindings.rs b/allowed_bindings.rs index ba628ff47..b21c1f80c 100644 --- a/allowed_bindings.rs +++ b/allowed_bindings.rs @@ -39,6 +39,7 @@ bind! { _zend_new_array, _zval_struct__bindgen_ty_1, _zval_struct__bindgen_ty_2, + _zend_known_string_id, // ext_php_rs_executor_globals, // ext_php_rs_php_build_id, // ext_php_rs_zend_object_alloc, @@ -84,6 +85,7 @@ bind! { zend_execute_data, zend_function_entry, zend_hash_clean, + zend_hash_find_known_hash, zend_hash_index_del, zend_hash_index_find, zend_hash_index_update, @@ -95,6 +97,7 @@ bind! { zend_is_callable, zend_is_identical, zend_is_iterable, + zend_known_strings, zend_long, zend_lookup_class_ex, zend_module_entry, diff --git a/src/zend/globals.rs b/src/zend/globals.rs index 17e360ee8..efc44e3c7 100644 --- a/src/zend/globals.rs +++ b/src/zend/globals.rs @@ -13,11 +13,12 @@ use crate::exception::PhpResult; #[cfg(php82)] use crate::ffi::zend_atomic_bool_store; use crate::ffi::{ - _sapi_module_struct, _zend_executor_globals, ext_php_rs_executor_globals, - ext_php_rs_file_globals, ext_php_rs_process_globals, ext_php_rs_sapi_globals, - ext_php_rs_sapi_module, php_core_globals, php_file_globals, sapi_globals_struct, - sapi_header_struct, sapi_headers_struct, sapi_request_info, zend_ini_entry, - zend_is_auto_global, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, TRACK_VARS_GET, + _sapi_module_struct, _zend_executor_globals, _zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST, + executor_globals, ext_php_rs_executor_globals, ext_php_rs_file_globals, + ext_php_rs_process_globals, ext_php_rs_sapi_globals, ext_php_rs_sapi_module, php_core_globals, + php_file_globals, sapi_globals_struct, sapi_header_struct, sapi_headers_struct, + sapi_request_info, zend_hash_find_known_hash, zend_ini_entry, zend_is_auto_global, + zend_known_strings, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, TRACK_VARS_GET, TRACK_VARS_POST, TRACK_VARS_SERVER, }; @@ -285,16 +286,24 @@ impl ProcessGlobals { /// Get the HTTP Request variables. Equivalent of $_REQUEST. /// /// # Panics - /// There is an outstanding issue with the implementation of this function. - /// Until resolved, this function will always panic. - /// - /// - - /// - - pub fn http_request_vars(&self) -> &ZendHashTable { - todo!("$_REQUEST super global was erroneously fetched from http_globals which resulted in an out-of-bounds access. A new implementation is needed."); - // self.http_globals[TRACK_VARS_REQUEST as usize] - // .array() - // .expect("Type is not a ZendArray") + /// - If the request global is not found or fails to be populated. + /// - If the request global is not a ZendArray. + pub fn http_request_vars(&self) -> Option<&ZendHashTable> { + let key = unsafe { + *zend_known_strings.add(_zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST as usize) + }; + + // `$_REQUEST` is lazy-initted, we need to call `zend_is_auto_global` to make sure it's populated. + if !unsafe { zend_is_auto_global(key) } { + panic!("Failed to get request global"); + } + + let request = unsafe { zend_hash_find_known_hash(&executor_globals.symbol_table, key) }; + if request.is_null() { + return None; + } + + Some(unsafe { (*request).array() }.expect("Type is not a ZendArray")) } /// Get the HTTP Environment variables. Equivalent of $_ENV. From 5dece57dcf07a0751bca43410f1483ff8aeef0ad Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Tue, 22 Oct 2024 20:12:02 +0200 Subject: [PATCH 2/9] fix(globals): fix request global fetching for php 8.0 Refs: #331 --- allowed_bindings.rs | 1 + src/zend/globals.rs | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/allowed_bindings.rs b/allowed_bindings.rs index b21c1f80c..78dc8e76e 100644 --- a/allowed_bindings.rs +++ b/allowed_bindings.rs @@ -86,6 +86,7 @@ bind! { zend_function_entry, zend_hash_clean, zend_hash_find_known_hash, + _zend_hash_find_known_hash, zend_hash_index_del, zend_hash_index_find, zend_hash_index_update, diff --git a/src/zend/globals.rs b/src/zend/globals.rs index efc44e3c7..decd4957b 100644 --- a/src/zend/globals.rs +++ b/src/zend/globals.rs @@ -10,16 +10,22 @@ use parking_lot::{const_rwlock, RwLock, RwLockReadGuard, RwLockWriteGuard}; use crate::boxed::ZBox; use crate::exception::PhpResult; +#[cfg(php80)] +use crate::ffi::_zend_hash_find_known_hash; #[cfg(php82)] use crate::ffi::zend_atomic_bool_store; use crate::ffi::{ - _sapi_module_struct, _zend_executor_globals, _zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST, - executor_globals, ext_php_rs_executor_globals, ext_php_rs_file_globals, - ext_php_rs_process_globals, ext_php_rs_sapi_globals, ext_php_rs_sapi_module, php_core_globals, - php_file_globals, sapi_globals_struct, sapi_header_struct, sapi_headers_struct, - sapi_request_info, zend_hash_find_known_hash, zend_ini_entry, zend_is_auto_global, - zend_known_strings, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, TRACK_VARS_GET, - TRACK_VARS_POST, TRACK_VARS_SERVER, + _sapi_module_struct, _zend_executor_globals, _zend_string, executor_globals, + ext_php_rs_executor_globals, ext_php_rs_file_globals, ext_php_rs_process_globals, + ext_php_rs_sapi_globals, ext_php_rs_sapi_module, php_core_globals, php_file_globals, + sapi_globals_struct, sapi_header_struct, sapi_headers_struct, sapi_request_info, + zend_ini_entry, zend_is_auto_global, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, + TRACK_VARS_GET, TRACK_VARS_POST, TRACK_VARS_SERVER, +}; +#[cfg(not(php80))] +use crate::ffi::{ + _zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST, zend_hash_find_known_hash, + zend_known_strings, }; use crate::types::{ZendHashTable, ZendObject, ZendStr}; @@ -289,6 +295,9 @@ impl ProcessGlobals { /// - If the request global is not found or fails to be populated. /// - If the request global is not a ZendArray. pub fn http_request_vars(&self) -> Option<&ZendHashTable> { + #[cfg(php80)] + let key = _zend_string::new("_REQUEST", false).as_mut_ptr(); + #[cfg(not(php80))] let key = unsafe { *zend_known_strings.add(_zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST as usize) }; @@ -298,7 +307,11 @@ impl ProcessGlobals { panic!("Failed to get request global"); } + #[cfg(php80)] + let request = unsafe { _zend_hash_find_known_hash(&executor_globals.symbol_table, key) }; + #[cfg(not(php80))] let request = unsafe { zend_hash_find_known_hash(&executor_globals.symbol_table, key) }; + if request.is_null() { return None; } From cddd678eb76c93ea567b92bc9976ccd43cdd942d Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Tue, 22 Oct 2024 20:43:43 +0200 Subject: [PATCH 3/9] fix(cfg): unified php version cfg Refs: #331 --- build.rs | 7 +++++-- src/builders/class.rs | 2 +- src/flags.rs | 6 +++--- src/zend/globals.rs | 22 +++++++++++----------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/build.rs b/build.rs index 523256497..f1cc56a96 100644 --- a/build.rs +++ b/build.rs @@ -235,13 +235,16 @@ fn check_php_version(info: &PHPInfo) -> Result<()> { println!( "cargo::rustc-check-cfg=cfg(php80, php81, php82, php83, php84, php_zts, php_debug, docs)" ); - println!("cargo:rustc-cfg=php80"); + + if version < PHP_81_API_VER { + println!("cargo:rustc-cfg=php80"); + } if (PHP_81_API_VER..PHP_82_API_VER).contains(&version) { println!("cargo:rustc-cfg=php81"); } - if version >= PHP_82_API_VER { + if (PHP_82_API_VER..PHP_83_API_VER).contains(&version) { println!("cargo:rustc-cfg=php82"); } diff --git a/src/builders/class.rs b/src/builders/class.rs index 922453690..3abf91016 100644 --- a/src/builders/class.rs +++ b/src/builders/class.rs @@ -247,7 +247,7 @@ impl ClassBuilder { // disable serialization if the class has an associated object if self.object_override.is_some() { cfg_if::cfg_if! { - if #[cfg(any(php81, php82))] { + if #[cfg(not(php80))] { class.ce_flags |= ClassFlags::NotSerializable.bits(); } else { class.serialize = Some(crate::ffi::zend_class_serialize_deny); diff --git a/src/flags.rs b/src/flags.rs index da3a6844c..aa2208543 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -2,7 +2,7 @@ use bitflags::bitflags; -#[cfg(not(php82))] +#[cfg(any(php80, php81))] use crate::ffi::ZEND_ACC_REUSE_GET_ITERATOR; use crate::ffi::{ CONST_CS, CONST_DEPRECATED, CONST_NO_FILE_CACHE, CONST_PERSISTENT, E_COMPILE_ERROR, @@ -84,14 +84,14 @@ bitflags! { const ConstantsUpdated = ZEND_ACC_CONSTANTS_UPDATED; const NoDynamicProperties = ZEND_ACC_NO_DYNAMIC_PROPERTIES; const HasStaticInMethods = ZEND_HAS_STATIC_IN_METHODS; - #[cfg(not(php82))] + #[cfg(any(php80, php81))] const ReuseGetIterator = ZEND_ACC_REUSE_GET_ITERATOR; const ResolvedParent = ZEND_ACC_RESOLVED_PARENT; const ResolvedInterfaces = ZEND_ACC_RESOLVED_INTERFACES; const UnresolvedVariance = ZEND_ACC_UNRESOLVED_VARIANCE; const NearlyLinked = ZEND_ACC_NEARLY_LINKED; - #[cfg(any(php81,php82))] + #[cfg(not(php80))] const NotSerializable = crate::ffi::ZEND_ACC_NOT_SERIALIZABLE; } } diff --git a/src/zend/globals.rs b/src/zend/globals.rs index decd4957b..2c9c84cb3 100644 --- a/src/zend/globals.rs +++ b/src/zend/globals.rs @@ -10,18 +10,18 @@ use parking_lot::{const_rwlock, RwLock, RwLockReadGuard, RwLockWriteGuard}; use crate::boxed::ZBox; use crate::exception::PhpResult; -#[cfg(php80)] -use crate::ffi::_zend_hash_find_known_hash; -#[cfg(php82)] +#[cfg(not(any(php80, php81)))] use crate::ffi::zend_atomic_bool_store; use crate::ffi::{ - _sapi_module_struct, _zend_executor_globals, _zend_string, executor_globals, - ext_php_rs_executor_globals, ext_php_rs_file_globals, ext_php_rs_process_globals, - ext_php_rs_sapi_globals, ext_php_rs_sapi_module, php_core_globals, php_file_globals, - sapi_globals_struct, sapi_header_struct, sapi_headers_struct, sapi_request_info, - zend_ini_entry, zend_is_auto_global, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, - TRACK_VARS_GET, TRACK_VARS_POST, TRACK_VARS_SERVER, + _sapi_module_struct, _zend_executor_globals, executor_globals, ext_php_rs_executor_globals, + ext_php_rs_file_globals, ext_php_rs_process_globals, ext_php_rs_sapi_globals, + ext_php_rs_sapi_module, php_core_globals, php_file_globals, sapi_globals_struct, + sapi_header_struct, sapi_headers_struct, sapi_request_info, zend_ini_entry, + zend_is_auto_global, TRACK_VARS_COOKIE, TRACK_VARS_ENV, TRACK_VARS_FILES, TRACK_VARS_GET, + TRACK_VARS_POST, TRACK_VARS_SERVER, }; +#[cfg(php80)] +use crate::ffi::{_zend_hash_find_known_hash, _zend_string}; #[cfg(not(php80))] use crate::ffi::{ _zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST, zend_hash_find_known_hash, @@ -161,7 +161,7 @@ impl ExecutorGlobals { /// set with [`crate::ffi::zend_interrupt_function`]. pub fn request_interrupt(&mut self) { cfg_if::cfg_if! { - if #[cfg(php82)] { + if #[cfg(not(any(php80, php81)))] { unsafe { zend_atomic_bool_store(&mut self.vm_interrupt, true); } @@ -174,7 +174,7 @@ impl ExecutorGlobals { /// Cancel a requested an interrupt of the PHP VM. pub fn cancel_interrupt(&mut self) { cfg_if::cfg_if! { - if #[cfg(php82)] { + if #[cfg(not(any(php80, php81)))] { unsafe { zend_atomic_bool_store(&mut self.vm_interrupt, false); } From f2097b3b07fe9631422619ae87ee7b765163b669 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:00:25 +0200 Subject: [PATCH 4/9] refactor(globals): use symbol table from `ExecutorGlobals` Refs: #331 --- src/zend/globals.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/zend/globals.rs b/src/zend/globals.rs index 2c9c84cb3..41f7034b3 100644 --- a/src/zend/globals.rs +++ b/src/zend/globals.rs @@ -13,7 +13,7 @@ use crate::exception::PhpResult; #[cfg(not(any(php80, php81)))] use crate::ffi::zend_atomic_bool_store; use crate::ffi::{ - _sapi_module_struct, _zend_executor_globals, executor_globals, ext_php_rs_executor_globals, + _sapi_module_struct, _zend_executor_globals, ext_php_rs_executor_globals, ext_php_rs_file_globals, ext_php_rs_process_globals, ext_php_rs_sapi_globals, ext_php_rs_sapi_module, php_core_globals, php_file_globals, sapi_globals_struct, sapi_header_struct, sapi_headers_struct, sapi_request_info, zend_ini_entry, @@ -307,10 +307,11 @@ impl ProcessGlobals { panic!("Failed to get request global"); } + let symbol_table = &ExecutorGlobals::get().symbol_table; #[cfg(php80)] - let request = unsafe { _zend_hash_find_known_hash(&executor_globals.symbol_table, key) }; + let request = unsafe { _zend_hash_find_known_hash(symbol_table, key) }; #[cfg(not(php80))] - let request = unsafe { zend_hash_find_known_hash(&executor_globals.symbol_table, key) }; + let request = unsafe { zend_hash_find_known_hash(symbol_table, key) }; if request.is_null() { return None; From 25efc76669563ca6acb363844bd43a5d3bd7ffe6 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:57:54 +0200 Subject: [PATCH 5/9] chore(bindings): update doc.rs bindings Refs: #331 --- docsrs_bindings.rs | 178 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 138 insertions(+), 40 deletions(-) diff --git a/docsrs_bindings.rs b/docsrs_bindings.rs index aade607af..0d570c0c7 100644 --- a/docsrs_bindings.rs +++ b/docsrs_bindings.rs @@ -82,6 +82,7 @@ where } pub const ZEND_DEBUG: u32 = 1; pub const _ZEND_TYPE_NAME_BIT: u32 = 16777216; +pub const _ZEND_TYPE_LITERAL_NAME_BIT: u32 = 8388608; pub const _ZEND_TYPE_NULLABLE_BIT: u32 = 2; pub const HT_MIN_SIZE: u32 = 8; pub const IS_UNDEF: u32 = 0; @@ -269,7 +270,7 @@ pub struct _IO_FILE { pub _wide_data: *mut _IO_wide_data, pub _freeres_list: *mut _IO_FILE, pub _freeres_buf: *mut ::std::os::raw::c_void, - pub __pad5: usize, + pub _prevchain: *mut *mut _IO_FILE, pub _mode: ::std::os::raw::c_int, pub _unused2: [::std::os::raw::c_char; 20usize], } @@ -537,6 +538,83 @@ pub type zend_string_init_interned_func_t = ::std::option::Option< extern "C" { pub static mut zend_string_init_interned: zend_string_init_interned_func_t; } +extern "C" { + pub static mut zend_known_strings: *mut *mut zend_string; +} +pub const _zend_known_string_id_ZEND_STR_FILE: _zend_known_string_id = 0; +pub const _zend_known_string_id_ZEND_STR_LINE: _zend_known_string_id = 1; +pub const _zend_known_string_id_ZEND_STR_FUNCTION: _zend_known_string_id = 2; +pub const _zend_known_string_id_ZEND_STR_CLASS: _zend_known_string_id = 3; +pub const _zend_known_string_id_ZEND_STR_OBJECT: _zend_known_string_id = 4; +pub const _zend_known_string_id_ZEND_STR_TYPE: _zend_known_string_id = 5; +pub const _zend_known_string_id_ZEND_STR_OBJECT_OPERATOR: _zend_known_string_id = 6; +pub const _zend_known_string_id_ZEND_STR_PAAMAYIM_NEKUDOTAYIM: _zend_known_string_id = 7; +pub const _zend_known_string_id_ZEND_STR_ARGS: _zend_known_string_id = 8; +pub const _zend_known_string_id_ZEND_STR_UNKNOWN: _zend_known_string_id = 9; +pub const _zend_known_string_id_ZEND_STR_UNKNOWN_CAPITALIZED: _zend_known_string_id = 10; +pub const _zend_known_string_id_ZEND_STR_EVAL: _zend_known_string_id = 11; +pub const _zend_known_string_id_ZEND_STR_INCLUDE: _zend_known_string_id = 12; +pub const _zend_known_string_id_ZEND_STR_REQUIRE: _zend_known_string_id = 13; +pub const _zend_known_string_id_ZEND_STR_INCLUDE_ONCE: _zend_known_string_id = 14; +pub const _zend_known_string_id_ZEND_STR_REQUIRE_ONCE: _zend_known_string_id = 15; +pub const _zend_known_string_id_ZEND_STR_SCALAR: _zend_known_string_id = 16; +pub const _zend_known_string_id_ZEND_STR_ERROR_REPORTING: _zend_known_string_id = 17; +pub const _zend_known_string_id_ZEND_STR_STATIC: _zend_known_string_id = 18; +pub const _zend_known_string_id_ZEND_STR_THIS: _zend_known_string_id = 19; +pub const _zend_known_string_id_ZEND_STR_VALUE: _zend_known_string_id = 20; +pub const _zend_known_string_id_ZEND_STR_KEY: _zend_known_string_id = 21; +pub const _zend_known_string_id_ZEND_STR_MAGIC_INVOKE: _zend_known_string_id = 22; +pub const _zend_known_string_id_ZEND_STR_PREVIOUS: _zend_known_string_id = 23; +pub const _zend_known_string_id_ZEND_STR_CODE: _zend_known_string_id = 24; +pub const _zend_known_string_id_ZEND_STR_MESSAGE: _zend_known_string_id = 25; +pub const _zend_known_string_id_ZEND_STR_SEVERITY: _zend_known_string_id = 26; +pub const _zend_known_string_id_ZEND_STR_STRING: _zend_known_string_id = 27; +pub const _zend_known_string_id_ZEND_STR_TRACE: _zend_known_string_id = 28; +pub const _zend_known_string_id_ZEND_STR_SCHEME: _zend_known_string_id = 29; +pub const _zend_known_string_id_ZEND_STR_HOST: _zend_known_string_id = 30; +pub const _zend_known_string_id_ZEND_STR_PORT: _zend_known_string_id = 31; +pub const _zend_known_string_id_ZEND_STR_USER: _zend_known_string_id = 32; +pub const _zend_known_string_id_ZEND_STR_PASS: _zend_known_string_id = 33; +pub const _zend_known_string_id_ZEND_STR_PATH: _zend_known_string_id = 34; +pub const _zend_known_string_id_ZEND_STR_QUERY: _zend_known_string_id = 35; +pub const _zend_known_string_id_ZEND_STR_FRAGMENT: _zend_known_string_id = 36; +pub const _zend_known_string_id_ZEND_STR_NULL: _zend_known_string_id = 37; +pub const _zend_known_string_id_ZEND_STR_BOOLEAN: _zend_known_string_id = 38; +pub const _zend_known_string_id_ZEND_STR_INTEGER: _zend_known_string_id = 39; +pub const _zend_known_string_id_ZEND_STR_DOUBLE: _zend_known_string_id = 40; +pub const _zend_known_string_id_ZEND_STR_ARRAY: _zend_known_string_id = 41; +pub const _zend_known_string_id_ZEND_STR_RESOURCE: _zend_known_string_id = 42; +pub const _zend_known_string_id_ZEND_STR_CLOSED_RESOURCE: _zend_known_string_id = 43; +pub const _zend_known_string_id_ZEND_STR_NAME: _zend_known_string_id = 44; +pub const _zend_known_string_id_ZEND_STR_ARGV: _zend_known_string_id = 45; +pub const _zend_known_string_id_ZEND_STR_ARGC: _zend_known_string_id = 46; +pub const _zend_known_string_id_ZEND_STR_ARRAY_CAPITALIZED: _zend_known_string_id = 47; +pub const _zend_known_string_id_ZEND_STR_BOOL: _zend_known_string_id = 48; +pub const _zend_known_string_id_ZEND_STR_INT: _zend_known_string_id = 49; +pub const _zend_known_string_id_ZEND_STR_FLOAT: _zend_known_string_id = 50; +pub const _zend_known_string_id_ZEND_STR_CALLABLE: _zend_known_string_id = 51; +pub const _zend_known_string_id_ZEND_STR_ITERABLE: _zend_known_string_id = 52; +pub const _zend_known_string_id_ZEND_STR_VOID: _zend_known_string_id = 53; +pub const _zend_known_string_id_ZEND_STR_NEVER: _zend_known_string_id = 54; +pub const _zend_known_string_id_ZEND_STR_FALSE: _zend_known_string_id = 55; +pub const _zend_known_string_id_ZEND_STR_TRUE: _zend_known_string_id = 56; +pub const _zend_known_string_id_ZEND_STR_NULL_LOWERCASE: _zend_known_string_id = 57; +pub const _zend_known_string_id_ZEND_STR_MIXED: _zend_known_string_id = 58; +pub const _zend_known_string_id_ZEND_STR_TRAVERSABLE: _zend_known_string_id = 59; +pub const _zend_known_string_id_ZEND_STR_SLEEP: _zend_known_string_id = 60; +pub const _zend_known_string_id_ZEND_STR_WAKEUP: _zend_known_string_id = 61; +pub const _zend_known_string_id_ZEND_STR_CASES: _zend_known_string_id = 62; +pub const _zend_known_string_id_ZEND_STR_FROM: _zend_known_string_id = 63; +pub const _zend_known_string_id_ZEND_STR_TRYFROM: _zend_known_string_id = 64; +pub const _zend_known_string_id_ZEND_STR_TRYFROM_LOWERCASE: _zend_known_string_id = 65; +pub const _zend_known_string_id_ZEND_STR_AUTOGLOBAL_SERVER: _zend_known_string_id = 66; +pub const _zend_known_string_id_ZEND_STR_AUTOGLOBAL_ENV: _zend_known_string_id = 67; +pub const _zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST: _zend_known_string_id = 68; +pub const _zend_known_string_id_ZEND_STR_COUNT: _zend_known_string_id = 69; +pub const _zend_known_string_id_ZEND_STR_SENSITIVEPARAMETER: _zend_known_string_id = 70; +pub const _zend_known_string_id_ZEND_STR_CONST_EXPR_PLACEHOLDER: _zend_known_string_id = 71; +pub const _zend_known_string_id_ZEND_STR_LAST_KNOWN: _zend_known_string_id = 72; +pub type _zend_known_string_id = ::std::os::raw::c_uint; extern "C" { pub fn zend_hash_clean(ht: *mut HashTable); } @@ -575,6 +653,9 @@ extern "C" { extern "C" { pub fn zend_hash_index_find(ht: *const HashTable, h: zend_ulong) -> *mut zval; } +extern "C" { + pub fn zend_hash_find_known_hash(ht: *const HashTable, key: *const zend_string) -> *mut zval; +} extern "C" { pub fn zend_hash_move_forward_ex(ht: *mut HashTable, pos: *mut HashPosition) -> zend_result; } @@ -1992,7 +2073,7 @@ pub struct _php_stream { pub wrapperthis: *mut ::std::os::raw::c_void, pub wrapperdata: zval, pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, pub mode: [::std::os::raw::c_char; 16usize], pub flags: u32, pub res: *mut zend_resource, @@ -2011,105 +2092,122 @@ pub struct _php_stream { } impl _php_stream { #[inline] - pub fn is_persistent(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } + pub fn is_persistent(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u16) } } #[inline] - pub fn set_is_persistent(&mut self, val: u8) { + pub fn set_is_persistent(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] - pub fn in_free(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 2u8) as u8) } + pub fn in_free(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(1usize, 2u8) as u16) } } #[inline] - pub fn set_in_free(&mut self, val: u8) { + pub fn set_in_free(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(1usize, 2u8, val as u64) } } #[inline] - pub fn eof(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u8) } + pub fn eof(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(3usize, 1u8) as u16) } } #[inline] - pub fn set_eof(&mut self, val: u8) { + pub fn set_eof(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(3usize, 1u8, val as u64) } } #[inline] - pub fn __exposed(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u8) } + pub fn __exposed(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 1u8) as u16) } } #[inline] - pub fn set___exposed(&mut self, val: u8) { + pub fn set___exposed(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(4usize, 1u8, val as u64) } } #[inline] - pub fn fclose_stdiocast(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 2u8) as u8) } + pub fn fclose_stdiocast(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(5usize, 2u8) as u16) } } #[inline] - pub fn set_fclose_stdiocast(&mut self, val: u8) { + pub fn set_fclose_stdiocast(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(5usize, 2u8, val as u64) } } #[inline] - pub fn has_buffered_data(&self) -> u8 { - unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u8) } + pub fn has_buffered_data(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(7usize, 1u8) as u16) } } #[inline] - pub fn set_has_buffered_data(&mut self, val: u8) { + pub fn set_has_buffered_data(&mut self, val: u16) { unsafe { - let val: u8 = ::std::mem::transmute(val); + let val: u16 = ::std::mem::transmute(val); self._bitfield_1.set(7usize, 1u8, val as u64) } } #[inline] + pub fn fclose_stdiocast_flush_in_progress(&self) -> u16 { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 1u8) as u16) } + } + #[inline] + pub fn set_fclose_stdiocast_flush_in_progress(&mut self, val: u16) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 1u8, val as u64) + } + } + #[inline] pub fn new_bitfield_1( - is_persistent: u8, - in_free: u8, - eof: u8, - __exposed: u8, - fclose_stdiocast: u8, - has_buffered_data: u8, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + is_persistent: u16, + in_free: u16, + eof: u16, + __exposed: u16, + fclose_stdiocast: u16, + has_buffered_data: u16, + fclose_stdiocast_flush_in_progress: u16, + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); __bindgen_bitfield_unit.set(0usize, 1u8, { - let is_persistent: u8 = unsafe { ::std::mem::transmute(is_persistent) }; + let is_persistent: u16 = unsafe { ::std::mem::transmute(is_persistent) }; is_persistent as u64 }); __bindgen_bitfield_unit.set(1usize, 2u8, { - let in_free: u8 = unsafe { ::std::mem::transmute(in_free) }; + let in_free: u16 = unsafe { ::std::mem::transmute(in_free) }; in_free as u64 }); __bindgen_bitfield_unit.set(3usize, 1u8, { - let eof: u8 = unsafe { ::std::mem::transmute(eof) }; + let eof: u16 = unsafe { ::std::mem::transmute(eof) }; eof as u64 }); __bindgen_bitfield_unit.set(4usize, 1u8, { - let __exposed: u8 = unsafe { ::std::mem::transmute(__exposed) }; + let __exposed: u16 = unsafe { ::std::mem::transmute(__exposed) }; __exposed as u64 }); __bindgen_bitfield_unit.set(5usize, 2u8, { - let fclose_stdiocast: u8 = unsafe { ::std::mem::transmute(fclose_stdiocast) }; + let fclose_stdiocast: u16 = unsafe { ::std::mem::transmute(fclose_stdiocast) }; fclose_stdiocast as u64 }); __bindgen_bitfield_unit.set(7usize, 1u8, { - let has_buffered_data: u8 = unsafe { ::std::mem::transmute(has_buffered_data) }; + let has_buffered_data: u16 = unsafe { ::std::mem::transmute(has_buffered_data) }; has_buffered_data as u64 }); + __bindgen_bitfield_unit.set(8usize, 1u8, { + let fclose_stdiocast_flush_in_progress: u16 = + unsafe { ::std::mem::transmute(fclose_stdiocast_flush_in_progress) }; + fclose_stdiocast_flush_in_progress as u64 + }); __bindgen_bitfield_unit } } From 8489aaa54dffaeb63b901e02443638c2f7f75611 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:13:12 +0200 Subject: [PATCH 6/9] refactor(globals): use `cfg_if` for php versions Refs: #331 --- src/zend/globals.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/zend/globals.rs b/src/zend/globals.rs index 41f7034b3..f5221ff28 100644 --- a/src/zend/globals.rs +++ b/src/zend/globals.rs @@ -295,11 +295,14 @@ impl ProcessGlobals { /// - If the request global is not found or fails to be populated. /// - If the request global is not a ZendArray. pub fn http_request_vars(&self) -> Option<&ZendHashTable> { - #[cfg(php80)] - let key = _zend_string::new("_REQUEST", false).as_mut_ptr(); - #[cfg(not(php80))] - let key = unsafe { - *zend_known_strings.add(_zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST as usize) + cfg_if::cfg_if! { + if #[cfg(php80)] { + let key = _zend_string::new("_REQUEST", false).as_mut_ptr(); + } else { + let key = unsafe { + *zend_known_strings.add(_zend_known_string_id_ZEND_STR_AUTOGLOBAL_REQUEST as usize) + }; + } }; // `$_REQUEST` is lazy-initted, we need to call `zend_is_auto_global` to make sure it's populated. @@ -308,10 +311,13 @@ impl ProcessGlobals { } let symbol_table = &ExecutorGlobals::get().symbol_table; - #[cfg(php80)] - let request = unsafe { _zend_hash_find_known_hash(symbol_table, key) }; - #[cfg(not(php80))] - let request = unsafe { zend_hash_find_known_hash(symbol_table, key) }; + cfg_if::cfg_if! { + if #[cfg(php80)] { + let request = unsafe { _zend_hash_find_known_hash(symbol_table, key) }; + } else { + let request = unsafe { zend_hash_find_known_hash(symbol_table, key) }; + } + }; if request.is_null() { return None; From 4aa8bb4e5be51ae44e084426058e7d759188e31c Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Tue, 22 Oct 2024 23:19:01 +0200 Subject: [PATCH 7/9] test(globals): add integration tests Refs: #331 --- tests/src/integration/globals.php | 8 ++++++ tests/src/integration/globals.rs | 4 +++ tests/src/lib.rs | 43 ++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/src/integration/globals.php create mode 100644 tests/src/integration/globals.rs diff --git a/tests/src/integration/globals.php b/tests/src/integration/globals.php new file mode 100644 index 000000000..119845cdd --- /dev/null +++ b/tests/src/integration/globals.php @@ -0,0 +1,8 @@ + &mut ZendObject { a } +// GLOBALS +#[php_function] +pub fn test_globals_http_get() -> ZBox { + ProcessGlobals::get().http_get_vars().to_owned() +} + +#[php_function] +pub fn test_globals_http_post() -> ZBox { + ProcessGlobals::get().http_post_vars().to_owned() +} + +#[php_function] +pub fn test_globals_http_cookie() -> ZBox { + ProcessGlobals::get().http_cookie_vars().to_owned() +} + +#[php_function] +pub fn test_globals_http_server() -> ZBox { + ProcessGlobals::get().http_server_vars().unwrap().to_owned() +} + +#[php_function] +pub fn test_globals_http_request() -> ZBox { + ProcessGlobals::get() + .http_request_vars() + .unwrap() + .to_owned() +} + +#[php_function] +pub fn test_globals_http_files() -> ZBox { + ProcessGlobals::get().http_files_vars().to_owned() +} + #[php_function] pub fn test_closure() -> Closure { Closure::wrap(Box::new(|a| a) as Box String>) @@ -179,6 +219,7 @@ mod integration { mod callable; mod class; mod closure; + mod globals; mod nullable; mod number; mod object; From f0e446b2a691cc350058f596c27414dc1f1b1ea7 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Wed, 27 Nov 2024 22:06:35 +0100 Subject: [PATCH 8/9] style(build): fix style and removed outdated comment Refs: 331 --- build.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/build.rs b/build.rs index f1cc56a96..f711047d3 100644 --- a/build.rs +++ b/build.rs @@ -221,9 +221,6 @@ fn check_php_version(info: &PHPInfo) -> Result<()> { // introduced in PHP 8.1). // // PHP 8.0 is the baseline - no feature flags will be introduced here. - // - // The PHP version cfg flags should also stack - if you compile on PHP 8.2 you - // should get both the `php81` and `php82` flags. const PHP_81_API_VER: u32 = 20210902; const PHP_82_API_VER: u32 = 20220829; From daa3095e496eeb084b1028b8aeb7748fd8c4c755 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Thu, 28 Nov 2024 20:21:55 +0100 Subject: [PATCH 9/9] fix(type): fix cfg for 8.4 Refs: 331 --- src/zend/_type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zend/_type.rs b/src/zend/_type.rs index 771851449..825ee2bba 100644 --- a/src/zend/_type.rs +++ b/src/zend/_type.rs @@ -83,7 +83,7 @@ impl ZendType { flags |= _ZEND_TYPE_NULLABLE_BIT } cfg_if::cfg_if! { - if #[cfg(php83)] { + if #[cfg(not(any(php80, php81, php82)))] { flags |= crate::ffi::_ZEND_TYPE_LITERAL_NAME_BIT } else { flags |= crate::ffi::_ZEND_TYPE_NAME_BIT