1- use std:: { ffi:: c_void, mem:: MaybeUninit , os:: raw:: c_int, ptr} ;
1+ use std:: {
2+ ffi:: { c_void, CString } ,
3+ mem:: MaybeUninit ,
4+ os:: raw:: c_int,
5+ ptr,
6+ } ;
27
38use crate :: {
49 class:: RegisteredClass ,
510 exception:: PhpResult ,
611 ffi:: {
7- std_object_handlers , zend_is_true , zend_object_handlers , zend_object_std_dtor ,
8- zend_std_get_properties , zend_std_has_property , zend_std_read_property ,
9- zend_std_write_property,
12+ _zend_class_entry , std_object_handlers , zend_hash_update_ind , zend_is_true ,
13+ zend_object_handlers , zend_object_std_dtor , zend_std_get_properties , zend_std_has_property ,
14+ zend_std_read_property , zend_std_write_property, zend_throw_error ,
1015 } ,
11- flags:: ZvalTypeFlags ,
16+ flags:: { PropertyFlags , ZvalTypeFlags } ,
1217 types:: { ZendClassObject , ZendHashTable , ZendObject , ZendStr , Zval } ,
1318} ;
1419
@@ -92,6 +97,7 @@ impl ZendObjectHandlers {
9297 let prop_name = member
9398 . as_ref ( )
9499 . ok_or ( "Invalid property name pointer given" ) ?;
100+
95101 let self_ = & mut * * obj;
96102 let props = T :: get_metadata ( ) . get_properties ( ) ;
97103 let prop = props. get ( prop_name. as_str ( ) ?) ;
@@ -102,6 +108,9 @@ impl ZendObjectHandlers {
102108
103109 Ok ( match prop {
104110 Some ( prop_info) => {
111+ if prop_info. flags . contains ( PropertyFlags :: Private ) {
112+ bad_property_access :: < T > ( prop_name. as_str ( ) ?) ;
113+ }
105114 prop_info. prop . get ( self_, rv_mut) ?;
106115 rv
107116 }
@@ -148,6 +157,9 @@ impl ZendObjectHandlers {
148157
149158 Ok ( match prop {
150159 Some ( prop_info) => {
160+ if prop_info. flags . contains ( PropertyFlags :: Private ) {
161+ bad_property_access :: < T > ( prop_name. as_str ( ) ?) ;
162+ }
151163 prop_info. prop . set ( self_, value_mut) ?;
152164 value
153165 }
@@ -186,9 +198,19 @@ impl ZendObjectHandlers {
186198 if val. prop . get ( self_, & mut zv) . is_err ( ) {
187199 continue ;
188200 }
189- props. insert ( name, zv) . map_err ( |e| {
190- format ! ( "Failed to insert value into properties hashtable: {e:?}" )
191- } ) ?;
201+
202+ let name = if val. flags . contains ( PropertyFlags :: Private ) {
203+ println ! ( "Private property {name}" ) ;
204+ format ! ( "\0 {}\0 {name}" , T :: CLASS_NAME )
205+ } else if val. flags . contains ( PropertyFlags :: Protected ) {
206+ println ! ( "Protected property {name}" ) ;
207+ format ! ( "\0 *\0 {name}" )
208+ } else {
209+ name. to_string ( )
210+ } ;
211+ let mut name = ZendStr :: new ( name, false ) ;
212+
213+ zend_hash_update_ind ( props, name. as_mut_ptr ( ) , & mut zv) ;
192214 }
193215
194216 Ok ( ( ) )
@@ -296,3 +318,22 @@ impl ZendObjectHandlers {
296318 }
297319 }
298320}
321+
322+ /// Throws the error if a property is accessed incorrectly.
323+ /// This only throws the error and does not perform any checks.
324+ ///
325+ /// # Panics
326+ ///
327+ /// * If the property name is not a valid c string.
328+ unsafe fn bad_property_access < T : RegisteredClass > ( prop_name : impl ToString ) {
329+ zend_throw_error (
330+ ptr:: null_mut :: < _zend_class_entry > ( ) ,
331+ CString :: new ( format ! (
332+ "Cannot access private property {}::${}" ,
333+ T :: CLASS_NAME ,
334+ prop_name. to_string( )
335+ ) )
336+ . unwrap ( )
337+ . as_ptr ( ) ,
338+ ) ;
339+ }
0 commit comments