1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: |
14 +----------------------------------------------------------------------+
15 */
16
17 #ifdef HAVE_CONFIG_H
18 # include "config.h"
19 #endif
20
21 #include "php.h"
22 #include "php_ini.h"
23 #include "ext/standard/info.h"
24 #include "php_test.h"
25 #include "observer.h"
26 #include "fiber.h"
27 #include "iterators.h"
28 #include "zend_attributes.h"
29 #include "zend_enum.h"
30 #include "zend_interfaces.h"
31 #include "zend_weakrefs.h"
32 #include "Zend/Optimizer/zend_optimizer.h"
33 #include "Zend/zend_alloc.h"
34 #include "test.h"
35 #include "test_arginfo.h"
36
37 // `php.h` sets `NDEBUG` when not `PHP_DEBUG` which will make `assert()` from
38 // assert.h a no-op. In order to have `assert()` working on NDEBUG builds, we
39 // undefine `NDEBUG` and re-include assert.h
40 #undef NDEBUG
41 #include "assert.h"
42
43 #if defined(HAVE_LIBXML) && !defined(PHP_WIN32)
44 # include <libxml/globals.h>
45 # include <libxml/parser.h>
46 # include "ext/dom/php_dom.h"
47 #endif
48
49 ZEND_DECLARE_MODULE_GLOBALS(zend_test)
50
51 static zend_class_entry *zend_test_interface;
52 static zend_class_entry *zend_test_class;
53 static zend_class_entry *zend_test_child_class;
54 static zend_class_entry *zend_test_trait;
55 static zend_class_entry *zend_test_attribute;
56 static zend_class_entry *zend_test_parameter_attribute;
57 static zend_class_entry *zend_test_property_attribute;
58 static zend_class_entry *zend_test_class_with_method_with_parameter_attribute;
59 static zend_class_entry *zend_test_child_class_with_method_with_parameter_attribute;
60 static zend_class_entry *zend_test_forbid_dynamic_call;
61 static zend_class_entry *zend_test_ns_foo_class;
62 static zend_class_entry *zend_test_ns_unlikely_compile_error_class;
63 static zend_class_entry *zend_test_ns_not_unlikely_compile_error_class;
64 static zend_class_entry *zend_test_ns2_foo_class;
65 static zend_class_entry *zend_test_ns2_ns_foo_class;
66 static zend_class_entry *zend_test_unit_enum;
67 static zend_class_entry *zend_test_string_enum;
68 static zend_class_entry *zend_test_int_enum;
69 static zend_class_entry *zend_test_magic_call;
70 static zend_object_handlers zend_test_class_handlers;
71
ZEND_FUNCTION(zend_test_func)72 static ZEND_FUNCTION(zend_test_func)
73 {
74 RETVAL_STR_COPY(EX(func)->common.function_name);
75
76 /* Cleanup trampoline */
77 ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE);
78 zend_string_release(EX(func)->common.function_name);
79 zend_free_trampoline(EX(func));
80 EX(func) = NULL;
81 }
82
ZEND_FUNCTION(zend_test_array_return)83 static ZEND_FUNCTION(zend_test_array_return)
84 {
85 ZEND_PARSE_PARAMETERS_NONE();
86 }
87
ZEND_FUNCTION(zend_test_nullable_array_return)88 static ZEND_FUNCTION(zend_test_nullable_array_return)
89 {
90 ZEND_PARSE_PARAMETERS_NONE();
91 }
92
ZEND_FUNCTION(zend_test_void_return)93 static ZEND_FUNCTION(zend_test_void_return)
94 {
95 /* dummy */
96 ZEND_PARSE_PARAMETERS_NONE();
97 }
98
pass1(zend_script * script,void * context)99 static void pass1(zend_script *script, void *context)
100 {
101 php_printf("pass1\n");
102 }
103
pass2(zend_script * script,void * context)104 static void pass2(zend_script *script, void *context)
105 {
106 php_printf("pass2\n");
107 }
108
ZEND_FUNCTION(zend_test_deprecated)109 static ZEND_FUNCTION(zend_test_deprecated)
110 {
111 zval *arg1;
112
113 zend_parse_parameters(ZEND_NUM_ARGS(), "|z", &arg1);
114 }
115
116 /* Create a string without terminating null byte. Must be terminated with
117 * zend_terminate_string() before destruction, otherwise a warning is issued
118 * in debug builds. */
ZEND_FUNCTION(zend_create_unterminated_string)119 static ZEND_FUNCTION(zend_create_unterminated_string)
120 {
121 zend_string *str, *res;
122
123 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &str) == FAILURE) {
124 RETURN_THROWS();
125 }
126
127 res = zend_string_alloc(ZSTR_LEN(str), 0);
128 memcpy(ZSTR_VAL(res), ZSTR_VAL(str), ZSTR_LEN(str));
129 /* No trailing null byte */
130
131 RETURN_STR(res);
132 }
133
134 /* Enforce terminate null byte on string. This avoids a warning in debug builds. */
ZEND_FUNCTION(zend_terminate_string)135 static ZEND_FUNCTION(zend_terminate_string)
136 {
137 zend_string *str;
138
139 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &str) == FAILURE) {
140 RETURN_THROWS();
141 }
142
143 ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
144 }
145
146 /* Cause an intentional memory leak, for testing/debugging purposes */
ZEND_FUNCTION(zend_leak_bytes)147 static ZEND_FUNCTION(zend_leak_bytes)
148 {
149 zend_long leakbytes = 3;
150
151 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &leakbytes) == FAILURE) {
152 RETURN_THROWS();
153 }
154
155 emalloc(leakbytes);
156 }
157
158 /* Leak a refcounted variable */
ZEND_FUNCTION(zend_leak_variable)159 static ZEND_FUNCTION(zend_leak_variable)
160 {
161 zval *zv;
162
163 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zv) == FAILURE) {
164 RETURN_THROWS();
165 }
166
167 if (!Z_REFCOUNTED_P(zv)) {
168 zend_error(E_WARNING, "Cannot leak variable that is not refcounted");
169 return;
170 }
171
172 Z_ADDREF_P(zv);
173 }
174
175 /* Tests Z_PARAM_OBJ_OR_STR */
ZEND_FUNCTION(zend_string_or_object)176 static ZEND_FUNCTION(zend_string_or_object)
177 {
178 zend_string *str;
179 zend_object *object;
180
181 ZEND_PARSE_PARAMETERS_START(1, 1)
182 Z_PARAM_OBJ_OR_STR(object, str)
183 ZEND_PARSE_PARAMETERS_END();
184
185 if (str) {
186 RETURN_STR_COPY(str);
187 } else {
188 RETURN_OBJ_COPY(object);
189 }
190 }
191
192 /* Tests Z_PARAM_OBJ_OR_STR_OR_NULL */
ZEND_FUNCTION(zend_string_or_object_or_null)193 static ZEND_FUNCTION(zend_string_or_object_or_null)
194 {
195 zend_string *str;
196 zend_object *object;
197
198 ZEND_PARSE_PARAMETERS_START(1, 1)
199 Z_PARAM_OBJ_OR_STR_OR_NULL(object, str)
200 ZEND_PARSE_PARAMETERS_END();
201
202 if (str) {
203 RETURN_STR_COPY(str);
204 } else if (object) {
205 RETURN_OBJ_COPY(object);
206 } else {
207 RETURN_NULL();
208 }
209 }
210
211 /* Tests Z_PARAM_OBJ_OF_CLASS_OR_STR */
ZEND_FUNCTION(zend_string_or_stdclass)212 static ZEND_FUNCTION(zend_string_or_stdclass)
213 {
214 zend_string *str;
215 zend_object *object;
216
217 ZEND_PARSE_PARAMETERS_START(1, 1)
218 Z_PARAM_OBJ_OF_CLASS_OR_STR(object, zend_standard_class_def, str)
219 ZEND_PARSE_PARAMETERS_END();
220
221 if (str) {
222 RETURN_STR_COPY(str);
223 } else {
224 RETURN_OBJ_COPY(object);
225 }
226 }
227
ZEND_FUNCTION(zend_test_compile_string)228 static ZEND_FUNCTION(zend_test_compile_string)
229 {
230 zend_string *source_string = NULL;
231 zend_string *filename = NULL;
232 zend_long position = ZEND_COMPILE_POSITION_AT_OPEN_TAG;
233
234 ZEND_PARSE_PARAMETERS_START(3, 3)
235 Z_PARAM_STR(source_string)
236 Z_PARAM_STR(filename)
237 Z_PARAM_LONG(position)
238 ZEND_PARSE_PARAMETERS_END();
239
240 zend_op_array *op_array = NULL;
241
242 op_array = compile_string(source_string, ZSTR_VAL(filename), position);
243
244 if (op_array) {
245 zval retval;
246
247 zend_try {
248 ZVAL_UNDEF(&retval);
249 zend_execute(op_array, &retval);
250 } zend_catch {
251 destroy_op_array(op_array);
252 efree_size(op_array, sizeof(zend_op_array));
253 zend_bailout();
254 } zend_end_try();
255
256 destroy_op_array(op_array);
257 efree_size(op_array, sizeof(zend_op_array));
258 }
259
260 return;
261 }
262
263 /* Tests Z_PARAM_OBJ_OF_CLASS_OR_STR_OR_NULL */
ZEND_FUNCTION(zend_string_or_stdclass_or_null)264 static ZEND_FUNCTION(zend_string_or_stdclass_or_null)
265 {
266 zend_string *str;
267 zend_object *object;
268
269 ZEND_PARSE_PARAMETERS_START(1, 1)
270 Z_PARAM_OBJ_OF_CLASS_OR_STR_OR_NULL(object, zend_standard_class_def, str)
271 ZEND_PARSE_PARAMETERS_END();
272
273 if (str) {
274 RETURN_STR_COPY(str);
275 } else if (object) {
276 RETURN_OBJ_COPY(object);
277 } else {
278 RETURN_NULL();
279 }
280 }
281
ZEND_FUNCTION(zend_weakmap_attach)282 static ZEND_FUNCTION(zend_weakmap_attach)
283 {
284 zval *value;
285 zend_object *obj;
286
287 ZEND_PARSE_PARAMETERS_START(2, 2)
288 Z_PARAM_OBJ(obj)
289 Z_PARAM_ZVAL(value)
290 ZEND_PARSE_PARAMETERS_END();
291
292 if (zend_weakrefs_hash_add(&ZT_G(global_weakmap), obj, value)) {
293 Z_TRY_ADDREF_P(value);
294 RETURN_TRUE;
295 }
296 RETURN_FALSE;
297 }
298
ZEND_FUNCTION(zend_weakmap_remove)299 static ZEND_FUNCTION(zend_weakmap_remove)
300 {
301 zend_object *obj;
302
303 ZEND_PARSE_PARAMETERS_START(1, 1)
304 Z_PARAM_OBJ(obj)
305 ZEND_PARSE_PARAMETERS_END();
306
307 RETURN_BOOL(zend_weakrefs_hash_del(&ZT_G(global_weakmap), obj) == SUCCESS);
308 }
309
ZEND_FUNCTION(zend_weakmap_dump)310 static ZEND_FUNCTION(zend_weakmap_dump)
311 {
312 ZEND_PARSE_PARAMETERS_NONE();
313 RETURN_ARR(zend_array_dup(&ZT_G(global_weakmap)));
314 }
315
ZEND_FUNCTION(zend_get_current_func_name)316 static ZEND_FUNCTION(zend_get_current_func_name)
317 {
318 ZEND_PARSE_PARAMETERS_NONE();
319
320 zend_string *function_name = get_function_or_method_name(EG(current_execute_data)->prev_execute_data->func);
321
322 RETURN_STR(function_name);
323 }
324
325 #if defined(HAVE_LIBXML) && !defined(PHP_WIN32)
ZEND_FUNCTION(zend_test_override_libxml_global_state)326 static ZEND_FUNCTION(zend_test_override_libxml_global_state)
327 {
328 ZEND_PARSE_PARAMETERS_NONE();
329
330 PHP_LIBXML_IGNORE_DEPRECATIONS_START
331 xmlLoadExtDtdDefaultValue = 1;
332 xmlDoValidityCheckingDefaultValue = 1;
333 (void) xmlPedanticParserDefault(1);
334 (void) xmlSubstituteEntitiesDefault(1);
335 (void) xmlLineNumbersDefault(1);
336 (void) xmlKeepBlanksDefault(0);
337 PHP_LIBXML_IGNORE_DEPRECATIONS_END
338 }
339 #endif
340
341 /* TESTS Z_PARAM_ITERABLE and Z_PARAM_ITERABLE_OR_NULL */
ZEND_FUNCTION(zend_iterable)342 static ZEND_FUNCTION(zend_iterable)
343 {
344 zval *arg1, *arg2;
345
346 ZEND_PARSE_PARAMETERS_START(1, 2)
347 Z_PARAM_ITERABLE(arg1)
348 Z_PARAM_OPTIONAL
349 Z_PARAM_ITERABLE_OR_NULL(arg2)
350 ZEND_PARSE_PARAMETERS_END();
351 }
352
ZEND_FUNCTION(zend_iterable_legacy)353 static ZEND_FUNCTION(zend_iterable_legacy)
354 {
355 zval *arg1, *arg2;
356
357 ZEND_PARSE_PARAMETERS_START(1, 2)
358 Z_PARAM_ITERABLE(arg1)
359 Z_PARAM_OPTIONAL
360 Z_PARAM_ITERABLE_OR_NULL(arg2)
361 ZEND_PARSE_PARAMETERS_END();
362
363 RETURN_COPY(arg1);
364 }
365
366 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_iterable_legacy, 0, 1, IS_ITERABLE, 0)
367 ZEND_ARG_TYPE_INFO(0, arg1, IS_ITERABLE, 0)
368 ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg2, IS_ITERABLE, 1, "null")
369 ZEND_END_ARG_INFO()
370
371 static const zend_function_entry ext_function_legacy[] = {
372 ZEND_FE(zend_iterable_legacy, arginfo_zend_iterable_legacy)
373 ZEND_FE_END
374 };
375
376 /* Call a method on a class or object using zend_call_method() */
ZEND_FUNCTION(zend_call_method)377 static ZEND_FUNCTION(zend_call_method)
378 {
379 zend_string *method_name;
380 zval *class_or_object, *arg1 = NULL, *arg2 = NULL;
381 zend_object *obj = NULL;
382 zend_class_entry *ce = NULL;
383 int argc = ZEND_NUM_ARGS();
384
385 ZEND_PARSE_PARAMETERS_START(2, 4)
386 Z_PARAM_ZVAL(class_or_object)
387 Z_PARAM_STR(method_name)
388 Z_PARAM_OPTIONAL
389 Z_PARAM_ZVAL(arg1)
390 Z_PARAM_ZVAL(arg2)
391 ZEND_PARSE_PARAMETERS_END();
392
393 if (Z_TYPE_P(class_or_object) == IS_OBJECT) {
394 obj = Z_OBJ_P(class_or_object);
395 ce = obj->ce;
396 } else if (Z_TYPE_P(class_or_object) == IS_STRING) {
397 ce = zend_lookup_class(Z_STR_P(class_or_object));
398 if (!ce) {
399 zend_error(E_ERROR, "Unknown class '%s'", Z_STRVAL_P(class_or_object));
400 return;
401 }
402 } else {
403 zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_type_name(class_or_object));
404 return;
405 }
406
407 ZEND_ASSERT((argc >= 2) && (argc <= 4));
408 zend_call_method(obj, ce, NULL, ZSTR_VAL(method_name), ZSTR_LEN(method_name), return_value, argc - 2, arg1, arg2);
409 }
410
ZEND_FUNCTION(zend_get_unit_enum)411 static ZEND_FUNCTION(zend_get_unit_enum)
412 {
413 ZEND_PARSE_PARAMETERS_NONE();
414
415 RETURN_OBJ_COPY(zend_enum_get_case_cstr(zend_test_unit_enum, "Foo"));
416 }
417
ZEND_FUNCTION(zend_test_zend_ini_parse_quantity)418 static ZEND_FUNCTION(zend_test_zend_ini_parse_quantity)
419 {
420 zend_string *str;
421 zend_string *errstr;
422
423 ZEND_PARSE_PARAMETERS_START(1, 1)
424 Z_PARAM_STR(str)
425 ZEND_PARSE_PARAMETERS_END();
426
427 RETVAL_LONG(zend_ini_parse_quantity(str, &errstr));
428
429 if (errstr) {
430 zend_error(E_WARNING, "%s", ZSTR_VAL(errstr));
431 zend_string_release(errstr);
432 }
433 }
434
ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity)435 static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity)
436 {
437 zend_string *str;
438 zend_string *errstr;
439
440 ZEND_PARSE_PARAMETERS_START(1, 1)
441 Z_PARAM_STR(str)
442 ZEND_PARSE_PARAMETERS_END();
443
444 RETVAL_LONG((zend_long)zend_ini_parse_uquantity(str, &errstr));
445
446 if (errstr) {
447 zend_error(E_WARNING, "%s", ZSTR_VAL(errstr));
448 zend_string_release(errstr);
449 }
450 }
451
ZEND_FUNCTION(zend_test_zend_ini_str)452 static ZEND_FUNCTION(zend_test_zend_ini_str)
453 {
454 ZEND_PARSE_PARAMETERS_NONE();
455
456 RETURN_STR(ZT_G(str_test));
457 }
458
ZEND_FUNCTION(ZendTestNS2_namespaced_func)459 static ZEND_FUNCTION(ZendTestNS2_namespaced_func)
460 {
461 ZEND_PARSE_PARAMETERS_NONE();
462 RETURN_TRUE;
463 }
464
ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func)465 static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func)
466 {
467 ZEND_PARSE_PARAMETERS_NONE();
468 }
469
ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func)470 static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func)
471 {
472 ZEND_PARSE_PARAMETERS_NONE();
473 RETURN_TRUE;
474 }
475
ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_deprecated_func)476 static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_deprecated_func)
477 {
478 ZEND_PARSE_PARAMETERS_NONE();
479 }
480
ZEND_FUNCTION(zend_test_parameter_with_attribute)481 static ZEND_FUNCTION(zend_test_parameter_with_attribute)
482 {
483 zend_string *parameter;
484
485 ZEND_PARSE_PARAMETERS_START(1, 1)
486 Z_PARAM_STR(parameter)
487 ZEND_PARSE_PARAMETERS_END();
488
489 RETURN_LONG(1);
490 }
491
ZEND_FUNCTION(zend_get_map_ptr_last)492 static ZEND_FUNCTION(zend_get_map_ptr_last)
493 {
494 ZEND_PARSE_PARAMETERS_NONE();
495 RETURN_LONG(CG(map_ptr_last));
496 }
497
ZEND_FUNCTION(zend_test_crash)498 static ZEND_FUNCTION(zend_test_crash)
499 {
500 zend_string *message = NULL;
501
502 ZEND_PARSE_PARAMETERS_START(0, 1)
503 Z_PARAM_OPTIONAL
504 Z_PARAM_STR_OR_NULL(message)
505 ZEND_PARSE_PARAMETERS_END();
506
507 if (message) {
508 php_printf("%s", ZSTR_VAL(message));
509 }
510
511 char *invalid = (char *) 1;
512 php_printf("%s", invalid);
513 }
514
has_opline(zend_execute_data * execute_data)515 static bool has_opline(zend_execute_data *execute_data)
516 {
517 return execute_data
518 && execute_data->func
519 && ZEND_USER_CODE(execute_data->func->type)
520 && execute_data->opline
521 ;
522 }
523
zend_test_custom_malloc(size_t len)524 void * zend_test_custom_malloc(size_t len)
525 {
526 if (has_opline(EG(current_execute_data))) {
527 assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
528 }
529 return _zend_mm_alloc(ZT_G(zend_orig_heap), len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
530 }
531
zend_test_custom_free(void * ptr)532 void zend_test_custom_free(void *ptr)
533 {
534 if (has_opline(EG(current_execute_data))) {
535 assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
536 }
537 _zend_mm_free(ZT_G(zend_orig_heap), ptr ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
538 }
539
zend_test_custom_realloc(void * ptr,size_t len)540 void * zend_test_custom_realloc(void * ptr, size_t len)
541 {
542 if (has_opline(EG(current_execute_data))) {
543 assert(EG(current_execute_data)->opline->lineno != (uint32_t)-1);
544 }
545 return _zend_mm_realloc(ZT_G(zend_orig_heap), ptr, len ZEND_FILE_LINE_EMPTY_CC ZEND_FILE_LINE_EMPTY_CC);
546 }
547
PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)548 static PHP_INI_MH(OnUpdateZendTestObserveOplineInZendMM)
549 {
550 if (new_value == NULL) {
551 return FAILURE;
552 }
553
554 int int_value = zend_ini_parse_bool(new_value);
555
556 if (int_value == 1) {
557 // `zend_mm_heap` is a private struct, so we have not way to find the
558 // actual size, but 4096 bytes should be enough
559 ZT_G(zend_test_heap) = malloc(4096);
560 memset(ZT_G(zend_test_heap), 0, 4096);
561 zend_mm_set_custom_handlers(
562 ZT_G(zend_test_heap),
563 zend_test_custom_malloc,
564 zend_test_custom_free,
565 zend_test_custom_realloc
566 );
567 ZT_G(zend_orig_heap) = zend_mm_get_heap();
568 zend_mm_set_heap(ZT_G(zend_test_heap));
569 } else if (ZT_G(zend_test_heap)) {
570 free(ZT_G(zend_test_heap));
571 ZT_G(zend_test_heap) = NULL;
572 zend_mm_set_heap(ZT_G(zend_orig_heap));
573 }
574 return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
575 }
576
ZEND_FUNCTION(zend_test_is_pcre_bundled)577 static ZEND_FUNCTION(zend_test_is_pcre_bundled)
578 {
579 ZEND_PARSE_PARAMETERS_NONE();
580 #if HAVE_BUNDLED_PCRE
581 RETURN_TRUE;
582 #else
583 RETURN_FALSE;
584 #endif
585 }
586
587 #ifdef PHP_WIN32
ZEND_FUNCTION(zend_test_set_fmode)588 static ZEND_FUNCTION(zend_test_set_fmode)
589 {
590 bool binary;
591 ZEND_PARSE_PARAMETERS_START(1, 1)
592 Z_PARAM_BOOL(binary)
593 ZEND_PARSE_PARAMETERS_END();
594
595 _fmode = binary ? _O_BINARY : _O_TEXT;
596 }
597 #endif
598
ZEND_FUNCTION(zend_test_cast_fread)599 static ZEND_FUNCTION(zend_test_cast_fread)
600 {
601 zval *stream_zv;
602 php_stream *stream;
603 FILE *fp;
604
605 ZEND_PARSE_PARAMETERS_START(1, 1)
606 Z_PARAM_RESOURCE(stream_zv);
607 ZEND_PARSE_PARAMETERS_END();
608
609 php_stream_from_zval(stream, stream_zv);
610
611 if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS) == FAILURE) {
612 return;
613 }
614
615 size_t size = 10240; /* Must be large enough to trigger the issue */
616 char *buf = malloc(size);
617 bool bail = false;
618 zend_try {
619 (void) !fread(buf, 1, size, fp);
620 } zend_catch {
621 bail = true;
622 } zend_end_try();
623
624 free(buf);
625
626 if (bail) {
627 zend_bailout();
628 }
629 }
630
ZEND_FUNCTION(zend_test_is_zend_ptr)631 static ZEND_FUNCTION(zend_test_is_zend_ptr)
632 {
633 zend_long addr;
634
635 ZEND_PARSE_PARAMETERS_START(1, 1)
636 Z_PARAM_LONG(addr);
637 ZEND_PARSE_PARAMETERS_END();
638
639 RETURN_BOOL(is_zend_ptr((void*)addr));
640 }
641
ZEND_FUNCTION(zend_test_log_err_debug)642 static ZEND_FUNCTION(zend_test_log_err_debug)
643 {
644 zend_string *str;
645
646 ZEND_PARSE_PARAMETERS_START(1, 1)
647 Z_PARAM_STR(str);
648 ZEND_PARSE_PARAMETERS_END();
649
650 php_log_err_with_severity(ZSTR_VAL(str), LOG_DEBUG);
651 }
652
zend_test_class_new(zend_class_entry * class_type)653 static zend_object *zend_test_class_new(zend_class_entry *class_type)
654 {
655 zend_object *obj = zend_objects_new(class_type);
656 object_properties_init(obj, class_type);
657 obj->handlers = &zend_test_class_handlers;
658 return obj;
659 }
660
zend_test_class_method_get(zend_object ** object,zend_string * name,const zval * key)661 static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key)
662 {
663 if (zend_string_equals_literal_ci(name, "test")) {
664 zend_internal_function *fptr;
665
666 if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
667 fptr = (zend_internal_function *) &EG(trampoline);
668 } else {
669 fptr = emalloc(sizeof(zend_internal_function));
670 }
671 memset(fptr, 0, sizeof(zend_internal_function));
672 fptr->type = ZEND_INTERNAL_FUNCTION;
673 fptr->num_args = 0;
674 fptr->scope = (*object)->ce;
675 fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
676 fptr->function_name = zend_string_copy(name);
677 fptr->handler = ZEND_FN(zend_test_func);
678
679 return (zend_function*)fptr;
680 }
681 return zend_std_get_method(object, name, key);
682 }
683
zend_test_class_static_method_get(zend_class_entry * ce,zend_string * name)684 static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name)
685 {
686 if (zend_string_equals_literal_ci(name, "test")) {
687 zend_internal_function *fptr;
688
689 if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
690 fptr = (zend_internal_function *) &EG(trampoline);
691 } else {
692 fptr = emalloc(sizeof(zend_internal_function));
693 }
694 memset(fptr, 0, sizeof(zend_internal_function));
695 fptr->type = ZEND_INTERNAL_FUNCTION;
696 fptr->num_args = 0;
697 fptr->scope = ce;
698 fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC;
699 fptr->function_name = zend_string_copy(name);
700 fptr->handler = ZEND_FN(zend_test_func);
701
702 return (zend_function*)fptr;
703 }
704 return zend_std_get_static_method(ce, name, NULL);
705 }
706
zend_attribute_validate_zendtestattribute(zend_attribute * attr,uint32_t target,zend_class_entry * scope)707 void zend_attribute_validate_zendtestattribute(zend_attribute *attr, uint32_t target, zend_class_entry *scope)
708 {
709 if (target != ZEND_ATTRIBUTE_TARGET_CLASS) {
710 zend_error(E_COMPILE_ERROR, "Only classes can be marked with #[ZendTestAttribute]");
711 }
712 }
713
ZEND_METHOD(_ZendTestClass,__toString)714 static ZEND_METHOD(_ZendTestClass, __toString)
715 {
716 ZEND_PARSE_PARAMETERS_NONE();
717 RETURN_EMPTY_STRING();
718 }
719
720 /* Internal function returns bool, we return int. */
ZEND_METHOD(_ZendTestClass,is_object)721 static ZEND_METHOD(_ZendTestClass, is_object)
722 {
723 ZEND_PARSE_PARAMETERS_NONE();
724 RETURN_LONG(42);
725 }
726
ZEND_METHOD(_ZendTestClass,returnsStatic)727 static ZEND_METHOD(_ZendTestClass, returnsStatic) {
728 ZEND_PARSE_PARAMETERS_NONE();
729 object_init_ex(return_value, zend_get_called_scope(execute_data));
730 }
731
ZEND_METHOD(_ZendTestClass,returnsThrowable)732 static ZEND_METHOD(_ZendTestClass, returnsThrowable)
733 {
734 ZEND_PARSE_PARAMETERS_NONE();
735 zend_throw_error(NULL, "Dummy");
736 }
737
ZEND_METHOD(_ZendTestClass,variadicTest)738 static ZEND_METHOD(_ZendTestClass, variadicTest) {
739 int argc, i;
740 zval *args = NULL;
741
742 ZEND_PARSE_PARAMETERS_START(0, -1)
743 Z_PARAM_VARIADIC('*', args, argc)
744 ZEND_PARSE_PARAMETERS_END();
745
746 for (i = 0; i < argc; i++) {
747 zval *arg = args + i;
748
749 if (Z_TYPE_P(arg) == IS_STRING) {
750 continue;
751 }
752 if (Z_TYPE_P(arg) == IS_OBJECT && instanceof_function(Z_OBJ_P(arg)->ce, zend_ce_iterator)) {
753 continue;
754 }
755
756 zend_argument_type_error(i + 1, "must be of class Iterator or a string, %s given", zend_zval_type_name(arg));
757 RETURN_THROWS();
758 }
759
760 object_init_ex(return_value, zend_get_called_scope(execute_data));
761 }
762
ZEND_METHOD(_ZendTestChildClass,returnsThrowable)763 static ZEND_METHOD(_ZendTestChildClass, returnsThrowable)
764 {
765 ZEND_PARSE_PARAMETERS_NONE();
766 zend_throw_error(NULL, "Dummy");
767 }
768
ZEND_METHOD(_ZendTestTrait,testMethod)769 static ZEND_METHOD(_ZendTestTrait, testMethod)
770 {
771 ZEND_PARSE_PARAMETERS_NONE();
772 RETURN_TRUE;
773 }
774
ZEND_METHOD(ZendTestNS_Foo,method)775 static ZEND_METHOD(ZendTestNS_Foo, method)
776 {
777 ZEND_PARSE_PARAMETERS_NONE();
778
779 RETURN_LONG(0);
780 }
781
ZEND_METHOD(ZendTestNS_UnlikelyCompileError,method)782 static ZEND_METHOD(ZendTestNS_UnlikelyCompileError, method)
783 {
784 ZEND_PARSE_PARAMETERS_NONE();
785
786 RETURN_NULL();
787 }
788
ZEND_METHOD(ZendTestNS_NotUnlikelyCompileError,method)789 static ZEND_METHOD(ZendTestNS_NotUnlikelyCompileError, method)
790 {
791 ZEND_PARSE_PARAMETERS_NONE();
792
793 RETURN_NULL();
794 }
795
ZEND_METHOD(ZendTestNS2_Foo,method)796 static ZEND_METHOD(ZendTestNS2_Foo, method)
797 {
798 ZEND_PARSE_PARAMETERS_NONE();
799 }
800
ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo,method)801 static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method)
802 {
803 ZEND_PARSE_PARAMETERS_NONE();
804 }
805
ZEND_METHOD(ZendTestParameterAttribute,__construct)806 static ZEND_METHOD(ZendTestParameterAttribute, __construct)
807 {
808 zend_string *parameter;
809
810 ZEND_PARSE_PARAMETERS_START(1, 1)
811 Z_PARAM_STR(parameter)
812 ZEND_PARSE_PARAMETERS_END();
813
814 ZVAL_STR_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), parameter);
815 }
816
ZEND_METHOD(ZendTestPropertyAttribute,__construct)817 static ZEND_METHOD(ZendTestPropertyAttribute, __construct)
818 {
819 zend_string *parameter;
820
821 ZEND_PARSE_PARAMETERS_START(1, 1)
822 Z_PARAM_STR(parameter)
823 ZEND_PARSE_PARAMETERS_END();
824
825 ZVAL_STR_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), parameter);
826 }
827
ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute,no_override)828 static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override)
829 {
830 zend_string *parameter;
831
832 ZEND_PARSE_PARAMETERS_START(1, 1)
833 Z_PARAM_STR(parameter)
834 ZEND_PARSE_PARAMETERS_END();
835
836 RETURN_LONG(2);
837 }
838
ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute,override)839 static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override)
840 {
841 zend_string *parameter;
842
843 ZEND_PARSE_PARAMETERS_START(1, 1)
844 Z_PARAM_STR(parameter)
845 ZEND_PARSE_PARAMETERS_END();
846
847 RETURN_LONG(3);
848 }
849
ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute,override)850 static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override)
851 {
852 zend_string *parameter;
853
854 ZEND_PARSE_PARAMETERS_START(1, 1)
855 Z_PARAM_STR(parameter)
856 ZEND_PARSE_PARAMETERS_END();
857
858 RETURN_LONG(4);
859 }
860
ZEND_METHOD(ZendTestForbidDynamicCall,call)861 static ZEND_METHOD(ZendTestForbidDynamicCall, call)
862 {
863 ZEND_PARSE_PARAMETERS_NONE();
864
865 zend_forbid_dynamic_call();
866 }
867
ZEND_METHOD(ZendTestForbidDynamicCall,callStatic)868 static ZEND_METHOD(ZendTestForbidDynamicCall, callStatic)
869 {
870 ZEND_PARSE_PARAMETERS_NONE();
871
872 zend_forbid_dynamic_call();
873 }
874
ZEND_METHOD(_ZendTestMagicCall,__call)875 static ZEND_METHOD(_ZendTestMagicCall, __call)
876 {
877 zend_string *name;
878 zval *arguments;
879
880 ZEND_PARSE_PARAMETERS_START(2, 2)
881 Z_PARAM_STR(name)
882 Z_PARAM_ARRAY(arguments)
883 ZEND_PARSE_PARAMETERS_END();
884
885 zval name_zv;
886 ZVAL_STR(&name_zv, name);
887
888 zend_string_addref(name);
889 Z_TRY_ADDREF_P(arguments);
890 RETURN_ARR(zend_new_pair(&name_zv, arguments));
891 }
892
ZEND_METHOD(_ZendTestMagicCallForward,__call)893 static ZEND_METHOD(_ZendTestMagicCallForward, __call)
894 {
895 zend_string *name;
896 zval *arguments;
897
898 ZEND_PARSE_PARAMETERS_START(2, 2)
899 Z_PARAM_STR(name)
900 Z_PARAM_ARRAY(arguments)
901 ZEND_PARSE_PARAMETERS_END();
902
903 ZEND_IGNORE_VALUE(arguments);
904
905 zval func;
906 ZVAL_STR(&func, name);
907 call_user_function(NULL, NULL, &func, return_value, 0, NULL);
908 }
909
910 PHP_INI_BEGIN()
911 STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
912 STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
913 STD_PHP_INI_BOOLEAN("zend_test.print_stderr_mshutdown", "0", PHP_INI_SYSTEM, OnUpdateBool, print_stderr_mshutdown, zend_zend_test_globals, zend_test_globals)
914 #ifdef HAVE_COPY_FILE_RANGE
915 STD_PHP_INI_ENTRY("zend_test.limit_copy_file_range", "-1", PHP_INI_ALL, OnUpdateLong, limit_copy_file_range, zend_zend_test_globals, zend_test_globals)
916 #endif
917 STD_PHP_INI_ENTRY("zend_test.quantity_value", "0", PHP_INI_ALL, OnUpdateLong, quantity_value, zend_zend_test_globals, zend_test_globals)
918 STD_PHP_INI_ENTRY("zend_test.str_test", "", PHP_INI_ALL, OnUpdateStr, str_test, zend_zend_test_globals, zend_test_globals)
919 STD_PHP_INI_ENTRY("zend_test.not_empty_str_test", "val", PHP_INI_ALL, OnUpdateStrNotEmpty, not_empty_str_test, zend_zend_test_globals, zend_test_globals)
920 STD_PHP_INI_BOOLEAN("zend_test.observe_opline_in_zendmm", "0", PHP_INI_ALL, OnUpdateZendTestObserveOplineInZendMM, observe_opline_in_zendmm, zend_zend_test_globals, zend_test_globals)
921 PHP_INI_END()
922
923 void (*old_zend_execute_ex)(zend_execute_data *execute_data);
custom_zend_execute_ex(zend_execute_data * execute_data)924 static void custom_zend_execute_ex(zend_execute_data *execute_data)
925 {
926 old_zend_execute_ex(execute_data);
927 }
928
PHP_MINIT_FUNCTION(zend_test)929 PHP_MINIT_FUNCTION(zend_test)
930 {
931 zend_test_interface = register_class__ZendTestInterface();
932
933 zend_test_class = register_class__ZendTestClass(zend_test_interface);
934 zend_test_class->create_object = zend_test_class_new;
935 zend_test_class->get_static_method = zend_test_class_static_method_get;
936
937 zend_test_child_class = register_class__ZendTestChildClass(zend_test_class);
938
939 memcpy(&zend_test_class_handlers, &std_object_handlers, sizeof(zend_object_handlers));
940 zend_test_class_handlers.get_method = zend_test_class_method_get;
941
942 zend_test_trait = register_class__ZendTestTrait();
943
944 register_test_symbols(module_number);
945
946 zend_test_attribute = register_class_ZendTestAttribute();
947 {
948 zend_internal_attribute *attr = zend_mark_internal_attribute(zend_test_attribute);
949 attr->validator = zend_attribute_validate_zendtestattribute;
950 }
951
952 zend_test_parameter_attribute = register_class_ZendTestParameterAttribute();
953 zend_mark_internal_attribute(zend_test_parameter_attribute);
954
955 {
956 zend_attribute *attr;
957
958 attr = zend_add_parameter_attribute(
959 zend_hash_str_find_ptr(CG(function_table), "zend_test_parameter_with_attribute", sizeof("zend_test_parameter_with_attribute") - 1),
960 0,
961 zend_test_parameter_attribute->name,
962 1
963 );
964
965 ZVAL_PSTRING(&attr->args[0].value, "value1");
966 }
967
968 zend_test_property_attribute = register_class_ZendTestPropertyAttribute();
969 zend_mark_internal_attribute(zend_test_property_attribute);
970
971 zend_test_class_with_method_with_parameter_attribute = register_class_ZendTestClassWithMethodWithParameterAttribute();
972
973 {
974 zend_attribute *attr;
975
976 attr = zend_add_parameter_attribute(
977 zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "no_override", sizeof("no_override") - 1),
978 0,
979 zend_test_parameter_attribute->name,
980 1
981 );
982
983 ZVAL_PSTRING(&attr->args[0].value, "value2");
984
985 attr = zend_add_parameter_attribute(
986 zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
987 0,
988 zend_test_parameter_attribute->name,
989 1
990 );
991
992 ZVAL_PSTRING(&attr->args[0].value, "value3");
993 }
994
995 zend_test_child_class_with_method_with_parameter_attribute = register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_test_class_with_method_with_parameter_attribute);
996
997 {
998 zend_attribute *attr;
999
1000 attr = zend_add_parameter_attribute(
1001 zend_hash_str_find_ptr(&zend_test_child_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
1002 0,
1003 zend_test_parameter_attribute->name,
1004 1
1005 );
1006
1007 ZVAL_PSTRING(&attr->args[0].value, "value4");
1008 }
1009
1010 zend_test_forbid_dynamic_call = register_class_ZendTestForbidDynamicCall();
1011
1012 zend_test_ns_foo_class = register_class_ZendTestNS_Foo();
1013 zend_test_ns_unlikely_compile_error_class = register_class_ZendTestNS_UnlikelyCompileError();
1014 zend_test_ns_not_unlikely_compile_error_class = register_class_ZendTestNS_NotUnlikelyCompileError();
1015 zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo();
1016 zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo();
1017
1018 zend_test_unit_enum = register_class_ZendTestUnitEnum();
1019 zend_test_string_enum = register_class_ZendTestStringEnum();
1020 zend_test_int_enum = register_class_ZendTestIntEnum();
1021
1022 zend_test_magic_call = register_class__ZendTestMagicCall();
1023
1024 register_class__ZendTestMagicCallForward();
1025
1026 zend_register_functions(NULL, ext_function_legacy, NULL, EG(current_module)->type);
1027
1028 // Loading via dl() not supported with the observer API
1029 if (type != MODULE_TEMPORARY) {
1030 REGISTER_INI_ENTRIES();
1031 } else {
1032 (void)ini_entries;
1033 }
1034
1035 if (ZT_G(replace_zend_execute_ex)) {
1036 old_zend_execute_ex = zend_execute_ex;
1037 zend_execute_ex = custom_zend_execute_ex;
1038 }
1039
1040 if (ZT_G(register_passes)) {
1041 zend_optimizer_register_pass(pass1);
1042 zend_optimizer_register_pass(pass2);
1043 }
1044
1045 zend_test_observer_init(INIT_FUNC_ARGS_PASSTHRU);
1046 zend_test_fiber_init();
1047 zend_test_iterators_init();
1048
1049 return SUCCESS;
1050 }
1051
PHP_MSHUTDOWN_FUNCTION(zend_test)1052 PHP_MSHUTDOWN_FUNCTION(zend_test)
1053 {
1054 if (type != MODULE_TEMPORARY) {
1055 UNREGISTER_INI_ENTRIES();
1056 }
1057
1058 zend_test_observer_shutdown(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1059
1060 if (ZT_G(print_stderr_mshutdown)) {
1061 fprintf(stderr, "[zend-test] MSHUTDOWN\n");
1062 }
1063
1064 return SUCCESS;
1065 }
1066
PHP_RINIT_FUNCTION(zend_test)1067 PHP_RINIT_FUNCTION(zend_test)
1068 {
1069 zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
1070 ZT_G(observer_nesting_depth) = 0;
1071 return SUCCESS;
1072 }
1073
PHP_RSHUTDOWN_FUNCTION(zend_test)1074 PHP_RSHUTDOWN_FUNCTION(zend_test)
1075 {
1076 zend_ulong obj_key;
1077 ZEND_HASH_FOREACH_NUM_KEY(&ZT_G(global_weakmap), obj_key) {
1078 zend_weakrefs_hash_del(&ZT_G(global_weakmap), zend_weakref_key_to_object(obj_key));
1079 } ZEND_HASH_FOREACH_END();
1080 zend_hash_destroy(&ZT_G(global_weakmap));
1081
1082 if (ZT_G(zend_test_heap)) {
1083 free(ZT_G(zend_test_heap));
1084 ZT_G(zend_test_heap) = NULL;
1085 zend_mm_set_heap(ZT_G(zend_orig_heap));
1086 }
1087
1088 return SUCCESS;
1089 }
1090
PHP_GINIT_FUNCTION(zend_test)1091 static PHP_GINIT_FUNCTION(zend_test)
1092 {
1093 #if defined(COMPILE_DL_ZEND_TEST) && defined(ZTS)
1094 ZEND_TSRMLS_CACHE_UPDATE();
1095 #endif
1096 memset(zend_test_globals, 0, sizeof(*zend_test_globals));
1097
1098 zend_test_observer_ginit(zend_test_globals);
1099 }
1100
PHP_GSHUTDOWN_FUNCTION(zend_test)1101 static PHP_GSHUTDOWN_FUNCTION(zend_test)
1102 {
1103 zend_test_observer_gshutdown(zend_test_globals);
1104 }
1105
PHP_MINFO_FUNCTION(zend_test)1106 PHP_MINFO_FUNCTION(zend_test)
1107 {
1108 php_info_print_table_start();
1109 php_info_print_table_header(2, "zend_test extension", "enabled");
1110 php_info_print_table_end();
1111
1112 DISPLAY_INI_ENTRIES();
1113 }
1114
1115 zend_module_entry zend_test_module_entry = {
1116 STANDARD_MODULE_HEADER,
1117 "zend_test",
1118 ext_functions,
1119 PHP_MINIT(zend_test),
1120 PHP_MSHUTDOWN(zend_test),
1121 PHP_RINIT(zend_test),
1122 PHP_RSHUTDOWN(zend_test),
1123 PHP_MINFO(zend_test),
1124 PHP_ZEND_TEST_VERSION,
1125 PHP_MODULE_GLOBALS(zend_test),
1126 PHP_GINIT(zend_test),
1127 PHP_GSHUTDOWN(zend_test),
1128 NULL,
1129 STANDARD_MODULE_PROPERTIES_EX
1130 };
1131
1132 #ifdef COMPILE_DL_ZEND_TEST
1133 # ifdef ZTS
1134 ZEND_TSRMLS_CACHE_DEFINE()
1135 # endif
ZEND_GET_MODULE(zend_test)1136 ZEND_GET_MODULE(zend_test)
1137 #endif
1138
1139 /* The important part here is the ZEND_FASTCALL. */
1140 PHP_ZEND_TEST_API int ZEND_FASTCALL bug78270(const char *str, size_t str_len)
1141 {
1142 char * copy = zend_strndup(str, str_len);
1143 int r = (int) ZEND_ATOL(copy);
1144 free(copy);
1145 return r;
1146 }
1147
bug79096(void)1148 PHP_ZEND_TEST_API struct bug79096 bug79096(void)
1149 {
1150 struct bug79096 b;
1151
1152 b.a = 1;
1153 b.b = 1;
1154 return b;
1155 }
1156
bug79532(off_t * array,size_t elems)1157 PHP_ZEND_TEST_API void bug79532(off_t *array, size_t elems)
1158 {
1159 int i;
1160 for (i = 0; i < elems; i++) {
1161 array[i] = i;
1162 }
1163 }
1164
1165 PHP_ZEND_TEST_API int *(*bug79177_cb)(void);
bug79177(void)1166 void bug79177(void)
1167 {
1168 bug79177_cb();
1169 }
1170
1171 typedef struct bug80847_01 {
1172 uint64_t b;
1173 double c;
1174 } bug80847_01;
1175 typedef struct bug80847_02 {
1176 bug80847_01 a;
1177 } bug80847_02;
1178
ffi_bug80847(bug80847_02 s)1179 PHP_ZEND_TEST_API bug80847_02 ffi_bug80847(bug80847_02 s) {
1180 s.a.b += 10;
1181 s.a.c -= 10.0;
1182 return s;
1183 }
1184
1185 PHP_ZEND_TEST_API void (*bug_gh9090_void_none_ptr)(void) = NULL;
1186 PHP_ZEND_TEST_API void (*bug_gh9090_void_int_char_ptr)(int, char *) = NULL;
1187 PHP_ZEND_TEST_API void (*bug_gh9090_void_int_char_var_ptr)(int, char *, ...) = NULL;
1188 PHP_ZEND_TEST_API void (*bug_gh9090_void_char_int_ptr)(char *, int) = NULL;
1189 PHP_ZEND_TEST_API int (*bug_gh9090_int_int_char_ptr)(int, char *) = NULL;
1190
bug_gh9090_void_none(void)1191 PHP_ZEND_TEST_API void bug_gh9090_void_none(void) {
1192 php_printf("bug_gh9090_none\n");
1193 }
1194
bug_gh9090_void_int_char(int i,char * s)1195 PHP_ZEND_TEST_API void bug_gh9090_void_int_char(int i, char *s) {
1196 php_printf("bug_gh9090_int_char %d %s\n", i, s);
1197 }
1198
bug_gh9090_void_int_char_var(int i,char * fmt,...)1199 PHP_ZEND_TEST_API void bug_gh9090_void_int_char_var(int i, char *fmt, ...) {
1200 va_list args;
1201 char *buffer;
1202
1203 va_start(args, fmt);
1204
1205 zend_vspprintf(&buffer, 0, fmt, args);
1206 php_printf("bug_gh9090_void_int_char_var %s\n", buffer);
1207 efree(buffer);
1208
1209 va_end(args);
1210 }
1211
1212 #ifdef HAVE_COPY_FILE_RANGE
1213 /**
1214 * This function allows us to simulate early return of copy_file_range by setting the limit_copy_file_range ini setting.
1215 */
1216 #ifdef __MUSL__
1217 typedef off_t off64_t;
1218 #endif
copy_file_range(int fd_in,off64_t * off_in,int fd_out,off64_t * off_out,size_t len,unsigned int flags)1219 PHP_ZEND_TEST_API ssize_t copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, size_t len, unsigned int flags)
1220 {
1221 ssize_t (*original_copy_file_range)(int, off64_t *, int, off64_t *, size_t, unsigned int) = dlsym(RTLD_NEXT, "copy_file_range");
1222 if (ZT_G(limit_copy_file_range) >= Z_L(0)) {
1223 len = ZT_G(limit_copy_file_range);
1224 }
1225 return original_copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
1226 }
1227 #endif
1228