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
+ } ;
2
7
3
8
use crate :: {
4
9
class:: RegisteredClass ,
5
10
exception:: PhpResult ,
6
11
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 ,
10
15
} ,
11
- flags:: ZvalTypeFlags ,
16
+ flags:: { PropertyFlags , ZvalTypeFlags } ,
12
17
types:: { ZendClassObject , ZendHashTable , ZendObject , ZendStr , Zval } ,
13
18
} ;
14
19
@@ -92,6 +97,7 @@ impl ZendObjectHandlers {
92
97
let prop_name = member
93
98
. as_ref ( )
94
99
. ok_or ( "Invalid property name pointer given" ) ?;
100
+
95
101
let self_ = & mut * * obj;
96
102
let props = T :: get_metadata ( ) . get_properties ( ) ;
97
103
let prop = props. get ( prop_name. as_str ( ) ?) ;
@@ -102,6 +108,9 @@ impl ZendObjectHandlers {
102
108
103
109
Ok ( match prop {
104
110
Some ( prop_info) => {
111
+ if prop_info. flags . contains ( PropertyFlags :: Private ) {
112
+ bad_property_access :: < T > ( prop_name. as_str ( ) ?) ;
113
+ }
105
114
prop_info. prop . get ( self_, rv_mut) ?;
106
115
rv
107
116
}
@@ -148,6 +157,9 @@ impl ZendObjectHandlers {
148
157
149
158
Ok ( match prop {
150
159
Some ( prop_info) => {
160
+ if prop_info. flags . contains ( PropertyFlags :: Private ) {
161
+ bad_property_access :: < T > ( prop_name. as_str ( ) ?) ;
162
+ }
151
163
prop_info. prop . set ( self_, value_mut) ?;
152
164
value
153
165
}
@@ -186,9 +198,19 @@ impl ZendObjectHandlers {
186
198
if val. prop . get ( self_, & mut zv) . is_err ( ) {
187
199
continue ;
188
200
}
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) ;
192
214
}
193
215
194
216
Ok ( ( ) )
@@ -296,3 +318,22 @@ impl ZendObjectHandlers {
296
318
}
297
319
}
298
320
}
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 : & str ) {
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
335
+ ) )
336
+ . expect ( "Failed to convert property name" )
337
+ . as_ptr ( ) ,
338
+ ) ;
339
+ }
0 commit comments