Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 680 lines (560 sloc) 22.889 kB
cf33fe5 Initial Release
pollita authored
1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
70c9aa4 @zenovich switched to The BSD 3-Clause License
authored
5 | Copyright (c) 1997-2006 The PHP Group, (c) 2008-2012 Dmitry Zenovich |
2a3ad06 Update (c) info
pollita authored
6 +----------------------------------------------------------------------+
70c9aa4 @zenovich switched to The BSD 3-Clause License
authored
7 | This source file is subject to the new BSD license, |
cf33fe5 Initial Release
pollita authored
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
70c9aa4 @zenovich switched to The BSD 3-Clause License
authored
10 | http://www.opensource.org/licenses/BSD-3-Clause |
11 | If you did not receive a copy of the license and are unable to |
cf33fe5 Initial Release
pollita authored
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Sara Golemon <pollita@php.net> |
42a929e @zenovich Preparing for release
authored
16 | Modified by Dmitry Zenovich <dzenovich@gmail.com> |
cf33fe5 Initial Release
pollita authored
17 +----------------------------------------------------------------------+
18 */
19
20 /* $Id$ */
21
22 #include "php_runkit.h"
23
a4ddec3 Allow partial-runkit support.
pollita authored
24 #ifdef PHP_RUNKIT_MANIPULATION
25
0ffba87 @zenovich fixed revertion of protected methods, no segmentation fault on callin…
authored
26 /* {{{ _php_runkit_get_method_prototype
27 Locates the prototype method */
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
28 static inline zend_function* _php_runkit_get_method_prototype(zend_class_entry *ce, const char* func_lower, int func_len TSRMLS_DC) {
0ffba87 @zenovich fixed revertion of protected methods, no segmentation fault on callin…
authored
29 zend_class_entry *pce = ce;
30 zend_function *proto = NULL;
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
31
0ffba87 @zenovich fixed revertion of protected methods, no segmentation fault on callin…
authored
32 while (pce) {
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
33 if (zend_hash_find(&pce->function_table, (char *) func_lower, func_len+1, (void*) &proto) != FAILURE) {
0ffba87 @zenovich fixed revertion of protected methods, no segmentation fault on callin…
authored
34 break;
35 }
36 pce = pce->parent;
37 }
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
38 if (!pce) {
39 proto = NULL;
40 }
0ffba87 @zenovich fixed revertion of protected methods, no segmentation fault on callin…
authored
41 return proto;
42 }
43 /* }}} */
cf33fe5 Initial Release
pollita authored
44
5a24561 @zenovich New features:
authored
45 /* {{{ php_runkit_fetch_class_int
cf33fe5 Initial Release
pollita authored
46 */
3b227ec @zenovich Build system improvements:
authored
47 int php_runkit_fetch_class_int(const char *classname, int classname_len, zend_class_entry **pce TSRMLS_DC)
cf33fe5 Initial Release
pollita authored
48 {
5a24561 @zenovich New features:
authored
49 char *lclass;
cf33fe5 Initial Release
pollita authored
50 zend_class_entry *ce;
51 zend_class_entry **ze;
52
cb8d02b @zenovich skip the leading slash in class names everywhere
authored
53 /* Ignore leading "\" */
54 if (classname[0] == '\\') {
55 ++classname;
56 --classname_len;
57 }
58
5a24561 @zenovich New features:
authored
59 lclass = estrndup(classname, classname_len);
60 if (lclass == NULL) {
3b227ec @zenovich Build system improvements:
authored
61 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
5a24561 @zenovich New features:
authored
62 return FAILURE;
63 }
64 php_strtolower(lclass, classname_len);
cf33fe5 Initial Release
pollita authored
65
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
66 if (zend_hash_find(EG(class_table), lclass, classname_len + 1, (void*)&ze) == FAILURE ||
cf33fe5 Initial Release
pollita authored
67 !ze || !*ze) {
5a24561 @zenovich New features:
authored
68 efree(lclass);
7d99f95 @zenovich fix for PHP4
authored
69 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s not found", classname);
cf33fe5 Initial Release
pollita authored
70 return FAILURE;
71 }
72 ce = *ze;
73
5a24561 @zenovich New features:
authored
74 if (pce) {
75 *pce = ce;
76 }
77
78 efree(lclass);
79 return SUCCESS;
80 }
81 /* }}} */
82
83 /* {{{ php_runkit_fetch_class
84 */
3b227ec @zenovich Build system improvements:
authored
85 int php_runkit_fetch_class(const char *classname, int classname_len, zend_class_entry **pce TSRMLS_DC)
5a24561 @zenovich New features:
authored
86 {
87 zend_class_entry *ce;
88
89 if (php_runkit_fetch_class_int(classname, classname_len, &ce TSRMLS_CC) == FAILURE) {
90 return FAILURE;
91 }
92
cf33fe5 Initial Release
pollita authored
93 if (ce->type != ZEND_USER_CLASS) {
94 php_error_docref(NULL TSRMLS_CC, E_WARNING, "class %s is not a user-defined class", classname);
95 return FAILURE;
96 }
97
98 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
99 php_error_docref(NULL TSRMLS_CC, E_WARNING, "class %s is an interface", classname);
100 return FAILURE;
101 }
102
103 if (pce) {
104 *pce = ce;
105 }
106
5a24561 @zenovich New features:
authored
107 return SUCCESS;
cf33fe5 Initial Release
pollita authored
108 }
109 /* }}} */
110
111 /* {{{ php_runkit_fetch_interface
112 */
3b227ec @zenovich Build system improvements:
authored
113 int php_runkit_fetch_interface(const char *classname, int classname_len, zend_class_entry **pce TSRMLS_DC)
cf33fe5 Initial Release
pollita authored
114 {
3b227ec @zenovich Build system improvements:
authored
115 char *lclass;
116
cb8d02b @zenovich skip the leading slash in class names everywhere
authored
117 /* Ignore leading "\" */
118 if (classname[0] == '\\') {
119 ++classname;
120 --classname_len;
121 }
122
3b227ec @zenovich Build system improvements:
authored
123 lclass = estrndup(classname, classname_len);
124 if (lclass == NULL) {
125 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
126 return FAILURE;
127 }
128 php_strtolower(lclass, classname_len);
cf33fe5 Initial Release
pollita authored
129
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
130 if (zend_hash_find(EG(class_table), lclass, classname_len + 1, (void*)&pce) == FAILURE ||
cf33fe5 Initial Release
pollita authored
131 !pce || !*pce) {
3b227ec @zenovich Build system improvements:
authored
132 efree(lclass);
cf33fe5 Initial Release
pollita authored
133 php_error_docref(NULL TSRMLS_CC, E_WARNING, "interface %s not found", classname);
134 return FAILURE;
135 }
136
137 if (!((*pce)->ce_flags & ZEND_ACC_INTERFACE)) {
3b227ec @zenovich Build system improvements:
authored
138 efree(lclass);
cf33fe5 Initial Release
pollita authored
139 php_error_docref(NULL TSRMLS_CC, E_WARNING, "class %s is not an interface", classname);
140 return FAILURE;
141 }
142
cb8d02b @zenovich skip the leading slash in class names everywhere
authored
143 return SUCCESS;
cf33fe5 Initial Release
pollita authored
144 }
145 /* }}} */
146
147 /* {{{ php_runkit_fetch_class_method
148 */
3b227ec @zenovich Build system improvements:
authored
149 static int php_runkit_fetch_class_method(const char *classname, int classname_len, const char *fname, int fname_len, zend_class_entry **pce, zend_function **pfe
cf33fe5 Initial Release
pollita authored
150 TSRMLS_DC)
151 {
152 HashTable *ftable = EG(function_table);
153 zend_class_entry *ce;
154 zend_function *fe;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
155 char *fname_lower;
cf33fe5 Initial Release
pollita authored
156
cb8d02b @zenovich skip the leading slash in class names everywhere
authored
157 if (php_runkit_fetch_class_int(classname, classname_len, &ce TSRMLS_CC) == FAILURE) {
cf33fe5 Initial Release
pollita authored
158 return FAILURE;
159 }
160
161 if (ce->type != ZEND_USER_CLASS) {
162 php_error_docref(NULL TSRMLS_CC, E_WARNING, "class %s is not a user-defined class", classname);
163 return FAILURE;
164 }
165
166 if (pce) {
167 *pce = ce;
168 }
169
170 ftable = &ce->function_table;
171
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
172 fname_lower = estrndup(fname, fname_len);
173 if (fname_lower == NULL) {
3b227ec @zenovich Build system improvements:
authored
174 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
175 return FAILURE;
176 }
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
177 php_strtolower(fname_lower, fname_len);
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
178
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
179 if (zend_hash_find(ftable, fname_lower, fname_len + 1, (void*)&fe) == FAILURE) {
cf33fe5 Initial Release
pollita authored
180 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::%s() not found", classname, fname);
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
181 efree(fname_lower);
cf33fe5 Initial Release
pollita authored
182 return FAILURE;
183 }
184
185 if (fe->type != ZEND_USER_FUNCTION) {
186 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::%s() is not a user function", classname, fname);
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
187 efree(fname_lower);
cf33fe5 Initial Release
pollita authored
188 return FAILURE;
189 }
190
191 if (pfe) {
192 *pfe = fe;
193 }
194
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
195 efree(fname_lower);
cf33fe5 Initial Release
pollita authored
196 return SUCCESS;
197 }
198 /* }}} */
199
200 /* {{{ php_runkit_update_children_methods
201 Scan the class_table for children of the class just updated */
bed9004 @zenovich welcome to 5.3zts!
authored
202 int php_runkit_update_children_methods(RUNKIT_53_TSRMLS_ARG(zend_class_entry *ce), int num_args, va_list args, zend_hash_key *hash_key)
cf33fe5 Initial Release
pollita authored
203 {
204 zend_class_entry *ancestor_class = va_arg(args, zend_class_entry*);
205 zend_class_entry *parent_class = va_arg(args, zend_class_entry*);
206 zend_class_entry *scope;
207 zend_function *fe = va_arg(args, zend_function*);
48426c7 @zenovich small optimization
authored
208 char *fname_lower = va_arg(args, char*);
cf33fe5 Initial Release
pollita authored
209 int fname_len = va_arg(args, int);
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
210 zend_function *orig_fe = va_arg(args, zend_function*);
cf33fe5 Initial Release
pollita authored
211 zend_function *cfe = NULL;
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
212
bed9004 @zenovich welcome to 5.3zts!
authored
213 RUNKIT_UNDER53_TSRMLS_FETCH();
cf33fe5 Initial Release
pollita authored
214
215 ce = *((zend_class_entry**)ce);
216
217 if (ce->parent != parent_class) {
218 /* Not a child, ignore */
219 return ZEND_HASH_APPLY_KEEP;
220 }
221
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
222 if (zend_hash_find(&ce->function_table, fname_lower, fname_len + 1, (void*)&cfe) == SUCCESS) {
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
223 scope = php_runkit_locate_scope(ce, cfe, fname_lower, fname_len);
cf33fe5 Initial Release
pollita authored
224 if (scope != ancestor_class) {
225 /* This method was defined below our current level, leave it be */
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
226 cfe->common.prototype = _php_runkit_get_method_prototype(scope->parent, fname_lower, fname_len TSRMLS_CC);
acdbb2f @zenovich stop supporting php4
authored
227 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_update_children_methods,
228 6, ancestor_class, ce, fe, fname_lower, fname_len, orig_fe);
cf33fe5 Initial Release
pollita authored
229 return ZEND_HASH_APPLY_KEEP;
230 }
231 }
232
c37ad34 @zenovich Highly probable crashes after modifying removing or renaming of funct…
authored
233 if (cfe) {
234 php_runkit_remove_function_from_reflection_objects(cfe TSRMLS_CC);
235 if (zend_hash_del(&ce->function_table, fname_lower, fname_len + 1) == FAILURE) {
236 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error updating child class");
237 return ZEND_HASH_APPLY_KEEP;
238 }
cf33fe5 Initial Release
pollita authored
239 }
240
5a24561 @zenovich New features:
authored
241 if (zend_hash_add(&ce->function_table, fname_lower, fname_len + 1, fe, sizeof(zend_function), NULL) == FAILURE) {
242 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error updating child class");
243 return ZEND_HASH_APPLY_KEEP;
244 }
245 PHP_RUNKIT_FUNCTION_ADD_REF(fe);
d6b0f05 @zenovich fix compilation against php 5.1
authored
246 PHP_RUNKIT_INHERIT_MAGIC(ce, fe, orig_fe);
5a24561 @zenovich New features:
authored
247
f8daf39 @zenovich the issue with inheritance of methods, which have been created by the…
authored
248 /* Process children of this child */
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
249 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_update_children_methods, 6,
48426c7 @zenovich small optimization
authored
250 ancestor_class, ce, fe, fname_lower, fname_len, orig_fe);
f8daf39 @zenovich the issue with inheritance of methods, which have been created by the…
authored
251
cf33fe5 Initial Release
pollita authored
252 return ZEND_HASH_APPLY_KEEP;
253 }
254 /* }}} */
255
256 /* {{{ php_runkit_clean_children
257 Scan the class_table for children of the class just updated */
bed9004 @zenovich welcome to 5.3zts!
authored
258 int php_runkit_clean_children_methods(RUNKIT_53_TSRMLS_ARG(zend_class_entry *ce), int num_args, va_list args, zend_hash_key *hash_key)
cf33fe5 Initial Release
pollita authored
259 {
260 zend_class_entry *ancestor_class = va_arg(args, zend_class_entry*);
261 zend_class_entry *parent_class = va_arg(args, zend_class_entry*);
262 zend_class_entry *scope;
48426c7 @zenovich small optimization
authored
263 char *fname_lower = va_arg(args, char*);
cf33fe5 Initial Release
pollita authored
264 int fname_len = va_arg(args, int);
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
265 zend_function *orig_cfe = va_arg(args, zend_function *);
cf33fe5 Initial Release
pollita authored
266 zend_function *cfe = NULL;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
267 RUNKIT_UNDER53_TSRMLS_FETCH();
cf33fe5 Initial Release
pollita authored
268
269 ce = *((zend_class_entry**)ce);
270
271 if (ce->parent != parent_class) {
272 /* Not a child, ignore */
273 return ZEND_HASH_APPLY_KEEP;
274 }
275
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
276 if (zend_hash_find(&ce->function_table, fname_lower, fname_len + 1, (void*)&cfe) == SUCCESS) {
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
277 scope = php_runkit_locate_scope(ce, cfe, fname_lower, fname_len);
cf33fe5 Initial Release
pollita authored
278 if (scope != ancestor_class) {
279 /* This method was defined below our current level, leave it be */
280 return ZEND_HASH_APPLY_KEEP;
281 }
282 }
283
284 if (!cfe) {
285 /* Odd.... nothing to destroy.... */
286 return ZEND_HASH_APPLY_KEEP;
287 }
288
289 /* Process children of this child */
48426c7 @zenovich small optimization
authored
290 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_clean_children_methods, 5, ancestor_class, ce, fname_lower, fname_len, orig_cfe);
cf33fe5 Initial Release
pollita authored
291
c37ad34 @zenovich Highly probable crashes after modifying removing or renaming of funct…
authored
292 php_runkit_remove_function_from_reflection_objects(cfe TSRMLS_CC);
293
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
294 zend_hash_del(&ce->function_table, fname_lower, fname_len + 1);
cf33fe5 Initial Release
pollita authored
295
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
296 PHP_RUNKIT_DEL_MAGIC_METHOD(ce, orig_cfe);
cf33fe5 Initial Release
pollita authored
297
298 return ZEND_HASH_APPLY_KEEP;
299 }
300 /* }}} */
301
302 /* {{{ php_runkit_method_add_or_update
303 */
304 static void php_runkit_method_add_or_update(INTERNAL_FUNCTION_PARAMETERS, int add_or_update)
305 {
3b227ec @zenovich Build system improvements:
authored
306 const char *classname, *methodname, *arguments, *phpcode;
cf33fe5 Initial Release
pollita authored
307 int classname_len, methodname_len, arguments_len, phpcode_len;
308 zend_class_entry *ce, *ancestor_class = NULL;
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
309 zend_function func, *fe, *orig_fe = NULL;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
310 char *methodname_lower;
cf33fe5 Initial Release
pollita authored
311 long argc = ZEND_NUM_ARGS();
312 long flags = ZEND_ACC_PUBLIC;
313
3b227ec @zenovich Build system improvements:
authored
314 if (zend_parse_parameters(argc TSRMLS_CC, "s/s/ss|l",
315 &classname, &classname_len,
316 &methodname, &methodname_len,
317 &arguments, &arguments_len,
318 &phpcode, &phpcode_len,
319 &flags) == FAILURE) {
cf33fe5 Initial Release
pollita authored
320 RETURN_FALSE;
321 }
322
323 if (!classname_len || !methodname_len) {
324 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty parameter given");
325 RETURN_FALSE;
326 }
327
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
328 methodname_lower = estrndup(methodname, methodname_len);
329 if (methodname_lower == NULL) {
3b227ec @zenovich Build system improvements:
authored
330 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
331 RETURN_FALSE;
332 }
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
333 php_strtolower(methodname_lower, methodname_len);
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
334
cf33fe5 Initial Release
pollita authored
335 if (add_or_update == HASH_UPDATE) {
336 if (php_runkit_fetch_class_method(classname, classname_len, methodname, methodname_len, &ce, &fe TSRMLS_CC) == FAILURE) {
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
337 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
338 RETURN_FALSE;
339 }
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
340 ancestor_class = php_runkit_locate_scope(ce, fe, methodname_lower, methodname_len);
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
341 orig_fe = fe;
cf33fe5 Initial Release
pollita authored
342
343 if (php_runkit_check_call_stack(&fe->op_array TSRMLS_CC) == FAILURE) {
344 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot redefine a method while that method is active.");
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
345 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
346 RETURN_FALSE;
347 }
348 } else {
349 if (php_runkit_fetch_class(classname, classname_len, &ce TSRMLS_CC) == FAILURE) {
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
350 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
351 RETURN_FALSE;
352 }
353 ancestor_class = ce;
354 }
355
159306b @zenovich Adding and redefining functions and methods, which return references,…
authored
356 if (php_runkit_generate_lambda_method(arguments, arguments_len, phpcode, phpcode_len, &fe,
357 (flags & PHP_RUNKIT_ACC_RETURN_REFERENCE) == PHP_RUNKIT_ACC_RETURN_REFERENCE
358 TSRMLS_CC) == FAILURE) {
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
359 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
360 RETURN_FALSE;
361 }
362
363 func = *fe;
7fefe5a PHP6 updates: Part 1 - function_add_ref()
pollita authored
364 PHP_RUNKIT_FUNCTION_ADD_REF(&func);
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
365 efree((void*)func.common.function_name);
cf33fe5 Initial Release
pollita authored
366 func.common.function_name = estrndup(methodname, methodname_len);
367 if (flags & ZEND_ACC_PRIVATE) {
368 func.common.fn_flags &= ~ZEND_ACC_PPP_MASK;
369 func.common.fn_flags |= ZEND_ACC_PRIVATE;
370 } else if (flags & ZEND_ACC_PROTECTED) {
371 func.common.fn_flags &= ~ZEND_ACC_PPP_MASK;
372 func.common.fn_flags |= ZEND_ACC_PROTECTED;
775f466 Bugfix: ZEND_ACC_PUBLIC visibility wasn't being set during runkit_met…
pollita authored
373 } else {
374 func.common.fn_flags &= ~ZEND_ACC_PPP_MASK;
375 func.common.fn_flags |= ZEND_ACC_PUBLIC;
cf33fe5 Initial Release
pollita authored
376 }
377
5a24561 @zenovich New features:
authored
378 if (flags & ZEND_ACC_STATIC) {
379 func.common.fn_flags |= ZEND_ACC_STATIC;
380 } else {
381 func.common.fn_flags |= ZEND_ACC_ALLOW_STATIC;
382 }
cf33fe5 Initial Release
pollita authored
383
1a3af5e @zenovich functions and methods redefining in PHP 5.4 was corrected in all plac…
authored
384 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
385 php_runkit_clear_all_functions_runtime_cache(TSRMLS_C);
386 #endif
387
c37ad34 @zenovich Highly probable crashes after modifying removing or renaming of funct…
authored
388 if(orig_fe) {
389 php_runkit_remove_function_from_reflection_objects(orig_fe TSRMLS_CC);
390 }
391
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
392 if (zend_hash_add_or_update(&ce->function_table, methodname_lower, methodname_len + 1, &func, sizeof(zend_function), NULL, add_or_update) == FAILURE) {
cf33fe5 Initial Release
pollita authored
393 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add method to class");
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
394 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
395 RETURN_FALSE;
396 }
397
398 if (zend_hash_del(EG(function_table), RUNKIT_TEMP_FUNCNAME, sizeof(RUNKIT_TEMP_FUNCNAME)) == FAILURE) {
399 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to remove temporary function entry");
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
400 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
401 RETURN_FALSE;
402 }
403
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
404 if (zend_hash_find(&ce->function_table, methodname_lower, methodname_len + 1, (void*)&fe) == FAILURE ||
cf33fe5 Initial Release
pollita authored
405 !fe) {
406 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate newly added method");
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
407 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
408 RETURN_FALSE;
409 }
410
510d34b @tony2001 also update method's own prototype
tony2001 authored
411 fe->common.scope = ce;
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
412 fe->common.prototype = _php_runkit_get_method_prototype(ce->parent, methodname_lower, methodname_len TSRMLS_CC);
510d34b @tony2001 also update method's own prototype
tony2001 authored
413
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
414 PHP_RUNKIT_ADD_MAGIC_METHOD(ce, methodname_lower, methodname_len, fe, orig_fe);
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
415 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_update_children_methods, 6,
48426c7 @zenovich small optimization
authored
416 ancestor_class, ce, fe, methodname_lower, methodname_len, orig_fe);
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
417
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
418 efree(methodname_lower);
3b227ec @zenovich Build system improvements:
authored
419
7edfe55 Be sure to *actually* return TRUE (Thanks Jakub)
pollita authored
420 RETURN_TRUE;
cf33fe5 Initial Release
pollita authored
421 }
422 /* }}} */
423
424 /* {{{ php_runkit_method_copy
425 */
3b227ec @zenovich Build system improvements:
authored
426 static int php_runkit_method_copy(const char *dclass, int dclass_len, const char *dfunc, int dfunc_len,
427 const char *sclass, int sclass_len, const char *sfunc, int sfunc_len TSRMLS_DC)
cf33fe5 Initial Release
pollita authored
428 {
429 zend_class_entry *dce, *sce;
570e579 - Fix #10053: memory exhausted, patch by Stefan Marr.
sebastian authored
430 zend_function dfe, *sfe, *dfeInHashTable;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
431 char *dfunc_lower;
cf33fe5 Initial Release
pollita authored
432
433 if (php_runkit_fetch_class_method(sclass, sclass_len, sfunc, sfunc_len, &sce, &sfe TSRMLS_CC) == FAILURE) {
434 return FAILURE;
435 }
436
437 if (php_runkit_fetch_class(dclass, dclass_len, &dce TSRMLS_CC) == FAILURE) {
438 return FAILURE;
439 }
440
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
441 dfunc_lower = estrndup(dfunc, dfunc_len);
442 if (dfunc_lower == NULL) {
3b227ec @zenovich Build system improvements:
authored
443 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
444 return FAILURE;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
445 }
446 php_strtolower(dfunc_lower, dfunc_len);
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
447
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
448 if (zend_hash_exists(&dce->function_table, dfunc_lower, dfunc_len + 1)) {
cf33fe5 Initial Release
pollita authored
449 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Destination method %s::%s() already exists", dclass, dfunc);
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
450 efree(dfunc_lower);
cf33fe5 Initial Release
pollita authored
451 return FAILURE;
452 }
453
454 dfe = *sfe;
3b227ec @zenovich Build system improvements:
authored
455 php_runkit_function_copy_ctor(&dfe, dfunc, dfunc_len TSRMLS_CC);
cf33fe5 Initial Release
pollita authored
456
d39962b @zenovich There should be no more "dereferencing type-punned pointer will break…
authored
457 if (zend_hash_add(&dce->function_table, dfunc_lower, dfunc_len + 1, &dfe, sizeof(zend_function), (void*) &dfeInHashTable) == FAILURE) {
cf33fe5 Initial Release
pollita authored
458 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error adding method to class %s::%s()", dclass, dfunc);
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
459 efree(dfunc_lower);
cf33fe5 Initial Release
pollita authored
460 return FAILURE;
461 }
462
510d34b @tony2001 also update method's own prototype
tony2001 authored
463 dfeInHashTable->common.scope = dce;
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
464 dfeInHashTable->common.prototype = _php_runkit_get_method_prototype(dce->parent, dfunc_lower, dfunc_len TSRMLS_CC);
510d34b @tony2001 also update method's own prototype
tony2001 authored
465
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
466 PHP_RUNKIT_ADD_MAGIC_METHOD(dce, dfunc_lower, dfunc_len, dfeInHashTable, NULL);
cf33fe5 Initial Release
pollita authored
467
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
468 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_update_children_methods, 7,
acdbb2f @zenovich stop supporting php4
authored
469 dce, dce, dfeInHashTable, dfunc_lower, dfunc_len, NULL, 0);
cf33fe5 Initial Release
pollita authored
470
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
471 efree(dfunc_lower);
cf33fe5 Initial Release
pollita authored
472 return SUCCESS;
473 }
474 /* }}} */
475
476 /* **************
477 * Method API *
478 ************** */
479
480 /* {{{ proto bool runkit_method_add(string classname, string methodname, string args, string code[, long flags])
481 Add a method to an already defined class */
482 PHP_FUNCTION(runkit_method_add)
483 {
484 php_runkit_method_add_or_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, HASH_ADD);
485 }
486 /* }}} */
487
488 /* {{{ proto bool runkit_method_redefine(string classname, string methodname, string args, string code[, long flags])
489 Redefine an already defined class method */
490 PHP_FUNCTION(runkit_method_redefine)
491 {
492 php_runkit_method_add_or_update(INTERNAL_FUNCTION_PARAM_PASSTHRU, HASH_UPDATE);
493 }
494 /* }}} */
495
496 /* {{{ proto bool runkit_method_remove(string classname, string methodname)
497 Remove a method from a class definition */
498 PHP_FUNCTION(runkit_method_remove)
499 {
500 char *classname, *methodname;
501 int classname_len, methodname_len;
502 zend_class_entry *ce, *ancestor_class = NULL;
503 zend_function *fe;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
504 char *methodname_lower;
cf33fe5 Initial Release
pollita authored
505
3b227ec @zenovich Build system improvements:
authored
506 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/s/", &classname, &classname_len,
507 &methodname, &methodname_len) == FAILURE) {
508 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't parse parameters");
cf33fe5 Initial Release
pollita authored
509 RETURN_FALSE;
510 }
511
512 if (!classname_len || !methodname_len) {
513 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty parameter given");
514 RETURN_FALSE;
515 }
516
517 if (php_runkit_fetch_class_method(classname, classname_len, methodname, methodname_len, &ce, &fe TSRMLS_CC) == FAILURE) {
518 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown method %s::%s()", classname, methodname);
519 RETURN_FALSE;
520 }
521
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
522 methodname_lower = estrndup(methodname, methodname_len);
523 if (methodname_lower == NULL) {
3b227ec @zenovich Build system improvements:
authored
524 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
525 RETURN_FALSE;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
526 }
527 php_strtolower(methodname_lower, methodname_len);
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
528
a978619 @zenovich Merge branch 'update_children_method_prototype' of https://github.com…
authored
529 ancestor_class = php_runkit_locate_scope(ce, fe, methodname_lower, methodname_len);
530
48426c7 @zenovich small optimization
authored
531 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_clean_children_methods, 5, ancestor_class, ce, methodname_lower, methodname_len, fe);
cf33fe5 Initial Release
pollita authored
532
1a3af5e @zenovich functions and methods redefining in PHP 5.4 was corrected in all plac…
authored
533 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
534 php_runkit_clear_all_functions_runtime_cache(TSRMLS_C);
535 #endif
536
c37ad34 @zenovich Highly probable crashes after modifying removing or renaming of funct…
authored
537 php_runkit_remove_function_from_reflection_objects(fe TSRMLS_CC);
538
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
539 if (zend_hash_del(&ce->function_table, methodname_lower, methodname_len + 1) == FAILURE) {
cf33fe5 Initial Release
pollita authored
540 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to remove method from class");
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
541 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
542 RETURN_FALSE;
543 }
544
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
545 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
546 PHP_RUNKIT_DEL_MAGIC_METHOD(ce, fe);
1a3af5e @zenovich functions and methods redefining in PHP 5.4 was corrected in all plac…
authored
547
7edfe55 Be sure to *actually* return TRUE (Thanks Jakub)
pollita authored
548 RETURN_TRUE;
cf33fe5 Initial Release
pollita authored
549 }
550 /* }}} */
551
552 /* {{{ proto bool runkit_method_rename(string classname, string methodname, string newname)
553 Rename a method within a class */
554 PHP_FUNCTION(runkit_method_rename)
555 {
3b227ec @zenovich Build system improvements:
authored
556 const char *classname, *methodname, *newname;
cf33fe5 Initial Release
pollita authored
557 int classname_len, methodname_len, newname_len;
558 zend_class_entry *ce, *ancestor_class = NULL;
559 zend_function *fe, func;
3b227ec @zenovich Build system improvements:
authored
560 char *newname_lower, *methodname_lower;
cf33fe5 Initial Release
pollita authored
561
7e8032d Assorted reference safty fixes
pollita authored
562 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/s/s/", &classname, &classname_len,
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
563 &methodname, &methodname_len, &newname, &newname_len) == FAILURE) {
cf33fe5 Initial Release
pollita authored
564 RETURN_FALSE;
565 }
566
567 if (!classname_len || !methodname_len || !newname_len) {
568 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty parameter given");
569 RETURN_FALSE;
570 }
571
572 if (php_runkit_fetch_class_method(classname, classname_len, methodname, methodname_len, &ce, &fe TSRMLS_CC) == FAILURE) {
573 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown method %s::%s()", classname, methodname);
574 RETURN_FALSE;
575 }
576
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
577 newname_lower = estrndup(newname, newname_len);
578 if (newname_lower == NULL) {
3b227ec @zenovich Build system improvements:
authored
579 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
580 RETURN_FALSE;
581 }
582 methodname_lower = estrndup(methodname, methodname_len);
583 if (methodname_lower == NULL) {
584 efree(newname_lower);
585 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Not enough memory");
91fa221 @zenovich Fixed the issue that the runkit used to create new methods with lower…
authored
586 RETURN_FALSE;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
587 }
588 php_strtolower(newname_lower, newname_len);
3b227ec @zenovich Build system improvements:
authored
589 php_strtolower(methodname_lower, methodname_len);
cf33fe5 Initial Release
pollita authored
590
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
591 if (zend_hash_exists(&ce->function_table, newname_lower, newname_len + 1)) {
592 efree(newname_lower);
3b227ec @zenovich Build system improvements:
authored
593 efree(methodname_lower);
594 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::%s() already exists", classname, newname);
cf33fe5 Initial Release
pollita authored
595 RETURN_FALSE;
596 }
597
3b227ec @zenovich Build system improvements:
authored
598 ancestor_class = php_runkit_locate_scope(ce, fe, methodname_lower, methodname_len);
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
599 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_clean_children_methods, 5,
600 ancestor_class, ce, methodname_lower, methodname_len, fe);
cf33fe5 Initial Release
pollita authored
601
1a3af5e @zenovich functions and methods redefining in PHP 5.4 was corrected in all plac…
authored
602 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION > 5)
603 php_runkit_clear_all_functions_runtime_cache(TSRMLS_C);
604 #endif
605
cf33fe5 Initial Release
pollita authored
606 func = *fe;
c592699 @zenovich Bug 57649 (https://bugs.php.net/bug.php?id=57649) has been fixed with…
authored
607 php_runkit_function_copy_ctor(&func, newname, newname_len TSRMLS_CC);
cf33fe5 Initial Release
pollita authored
608
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
609 if (zend_hash_add(&ce->function_table, newname_lower, newname_len + 1, &func, sizeof(zend_function), NULL) == FAILURE) {
3b227ec @zenovich Build system improvements:
authored
610 efree(newname_lower);
611 efree(methodname_lower);
cf33fe5 Initial Release
pollita authored
612 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add new reference to class method");
613 zend_function_dtor(&func);
614 RETURN_FALSE;
615 }
616
c37ad34 @zenovich Highly probable crashes after modifying removing or renaming of funct…
authored
617 php_runkit_remove_function_from_reflection_objects(fe TSRMLS_CC);
618
3b227ec @zenovich Build system improvements:
authored
619 if (zend_hash_del(&ce->function_table, methodname_lower, methodname_len + 1) == FAILURE) {
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
620 efree(newname_lower);
3b227ec @zenovich Build system improvements:
authored
621 efree(methodname_lower);
622 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to remove old method reference from class");
cf33fe5 Initial Release
pollita authored
623 RETURN_FALSE;
624 }
625
626 PHP_RUNKIT_DEL_MAGIC_METHOD(ce, fe);
627
628 if (php_runkit_fetch_class_method(classname, classname_len, newname, newname_len, &ce, &fe TSRMLS_CC) == FAILURE) {
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
629 efree(newname_lower);
3b227ec @zenovich Build system improvements:
authored
630 efree(methodname_lower);
631 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate newly renamed method");
cf33fe5 Initial Release
pollita authored
632 RETURN_FALSE;
633 }
634
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
635 PHP_RUNKIT_ADD_MAGIC_METHOD(ce, newname_lower, newname_len, fe, NULL);
636 zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_update_children_methods, 7,
acdbb2f @zenovich stop supporting php4
authored
637 ce, ce, fe, newname_lower, newname_len, NULL, 0);
7f5b7b1 @zenovich All ways of adding and removing magic methods and old-style construct…
authored
638
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
639 efree(newname_lower);
3b227ec @zenovich Build system improvements:
authored
640 efree(methodname_lower);
f8daf39 @zenovich the issue with inheritance of methods, which have been created by the…
authored
641
7edfe55 Be sure to *actually* return TRUE (Thanks Jakub)
pollita authored
642 RETURN_TRUE;
cf33fe5 Initial Release
pollita authored
643 }
644 /* }}} */
645
646 /* {{{ proto bool runkit_method_copy(string destclass, string destmethod, string srcclass[, string srcmethod])
647 Copy a method from one name to another or from one class to another */
648 PHP_FUNCTION(runkit_method_copy)
649 {
3b227ec @zenovich Build system improvements:
authored
650 const char *dclass, *dfunc, *sclass, *sfunc = NULL;
cf33fe5 Initial Release
pollita authored
651 int dclass_len, dfunc_len, sclass_len, sfunc_len = 0;
652
3b227ec @zenovich Build system improvements:
authored
653 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/s/s/|s/", &dclass, &dclass_len,
654 &dfunc, &dfunc_len,
655 &sclass, &sclass_len,
656 &sfunc, &sfunc_len) == FAILURE) {
cf33fe5 Initial Release
pollita authored
657 RETURN_FALSE;
658 }
659
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
660 if (!sfunc) {
cf33fe5 Initial Release
pollita authored
661 sfunc = dfunc;
662 sfunc_len = dfunc_len;
961abd4 @zenovich Disappointing incompatibility issue with php 5.3+ in untested code wa…
authored
663 }
cf33fe5 Initial Release
pollita authored
664
665 RETURN_BOOL(php_runkit_method_copy( dclass, dclass_len, dfunc, dfunc_len,
3b227ec @zenovich Build system improvements:
authored
666 sclass, sclass_len, sfunc, sfunc_len TSRMLS_CC) == SUCCESS ? 1 : 0);
cf33fe5 Initial Release
pollita authored
667 }
668 /* }}} */
a4ddec3 Allow partial-runkit support.
pollita authored
669 #endif /* PHP_RUNKIT_MANIPULATION */
cf33fe5 Initial Release
pollita authored
670
671 /*
672 * Local variables:
673 * tab-width: 4
674 * c-basic-offset: 4
675 * End:
676 * vim600: noet sw=4 ts=4 fdm=marker
677 * vim<600: noet sw=4 ts=4
678 */
679
Something went wrong with that request. Please try again.