xref: /PHP-8.2/ext/zend_test/test.c (revision 1ff277de)
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_test_class_new(zend_class_entry * class_type)642 static zend_object *zend_test_class_new(zend_class_entry *class_type)
643 {
644 	zend_object *obj = zend_objects_new(class_type);
645 	object_properties_init(obj, class_type);
646 	obj->handlers = &zend_test_class_handlers;
647 	return obj;
648 }
649 
zend_test_class_method_get(zend_object ** object,zend_string * name,const zval * key)650 static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key)
651 {
652 	if (zend_string_equals_literal_ci(name, "test")) {
653 	    zend_internal_function *fptr;
654 
655 	    if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
656 		    fptr = (zend_internal_function *) &EG(trampoline);
657 	    } else {
658 		    fptr = emalloc(sizeof(zend_internal_function));
659 	    }
660 	    memset(fptr, 0, sizeof(zend_internal_function));
661 	    fptr->type = ZEND_INTERNAL_FUNCTION;
662 	    fptr->num_args = 1;
663 	    fptr->scope = (*object)->ce;
664 	    fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
665 	    fptr->function_name = zend_string_copy(name);
666 	    fptr->handler = ZEND_FN(zend_test_func);
667 
668 	    return (zend_function*)fptr;
669 	}
670 	return zend_std_get_method(object, name, key);
671 }
672 
zend_test_class_static_method_get(zend_class_entry * ce,zend_string * name)673 static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name)
674 {
675 	if (zend_string_equals_literal_ci(name, "test")) {
676 		zend_internal_function *fptr;
677 
678 		if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
679 			fptr = (zend_internal_function *) &EG(trampoline);
680 		} else {
681 			fptr = emalloc(sizeof(zend_internal_function));
682 		}
683 		memset(fptr, 0, sizeof(zend_internal_function));
684 		fptr->type = ZEND_INTERNAL_FUNCTION;
685 		fptr->num_args = 1;
686 		fptr->scope = ce;
687 		fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC;
688 		fptr->function_name = zend_string_copy(name);
689 		fptr->handler = ZEND_FN(zend_test_func);
690 
691 		return (zend_function*)fptr;
692 	}
693 	return zend_std_get_static_method(ce, name, NULL);
694 }
695 
zend_attribute_validate_zendtestattribute(zend_attribute * attr,uint32_t target,zend_class_entry * scope)696 void zend_attribute_validate_zendtestattribute(zend_attribute *attr, uint32_t target, zend_class_entry *scope)
697 {
698 	if (target != ZEND_ATTRIBUTE_TARGET_CLASS) {
699 		zend_error(E_COMPILE_ERROR, "Only classes can be marked with #[ZendTestAttribute]");
700 	}
701 }
702 
ZEND_METHOD(_ZendTestClass,__toString)703 static ZEND_METHOD(_ZendTestClass, __toString)
704 {
705 	ZEND_PARSE_PARAMETERS_NONE();
706 	RETURN_EMPTY_STRING();
707 }
708 
709 /* Internal function returns bool, we return int. */
ZEND_METHOD(_ZendTestClass,is_object)710 static ZEND_METHOD(_ZendTestClass, is_object)
711 {
712 	ZEND_PARSE_PARAMETERS_NONE();
713 	RETURN_LONG(42);
714 }
715 
ZEND_METHOD(_ZendTestClass,returnsStatic)716 static ZEND_METHOD(_ZendTestClass, returnsStatic) {
717 	ZEND_PARSE_PARAMETERS_NONE();
718 	object_init_ex(return_value, zend_get_called_scope(execute_data));
719 }
720 
ZEND_METHOD(_ZendTestClass,returnsThrowable)721 static ZEND_METHOD(_ZendTestClass, returnsThrowable)
722 {
723 	ZEND_PARSE_PARAMETERS_NONE();
724 	zend_throw_error(NULL, "Dummy");
725 }
726 
ZEND_METHOD(_ZendTestClass,variadicTest)727 static ZEND_METHOD(_ZendTestClass, variadicTest) {
728 	int      argc, i;
729 	zval    *args = NULL;
730 
731 	ZEND_PARSE_PARAMETERS_START(0, -1)
732 		Z_PARAM_VARIADIC('*', args, argc)
733 	ZEND_PARSE_PARAMETERS_END();
734 
735 	for (i = 0; i < argc; i++) {
736 		zval *arg = args + i;
737 
738 		if (Z_TYPE_P(arg) == IS_STRING) {
739 			continue;
740 		}
741 		if (Z_TYPE_P(arg) == IS_OBJECT && instanceof_function(Z_OBJ_P(arg)->ce, zend_ce_iterator)) {
742 			continue;
743 		}
744 
745 		zend_argument_type_error(i + 1, "must be of class Iterator or a string, %s given", zend_zval_type_name(arg));
746 		RETURN_THROWS();
747 	}
748 
749 	object_init_ex(return_value, zend_get_called_scope(execute_data));
750 }
751 
ZEND_METHOD(_ZendTestChildClass,returnsThrowable)752 static ZEND_METHOD(_ZendTestChildClass, returnsThrowable)
753 {
754 	ZEND_PARSE_PARAMETERS_NONE();
755 	zend_throw_error(NULL, "Dummy");
756 }
757 
ZEND_METHOD(_ZendTestTrait,testMethod)758 static ZEND_METHOD(_ZendTestTrait, testMethod)
759 {
760 	ZEND_PARSE_PARAMETERS_NONE();
761 	RETURN_TRUE;
762 }
763 
ZEND_METHOD(ZendTestNS_Foo,method)764 static ZEND_METHOD(ZendTestNS_Foo, method)
765 {
766 	ZEND_PARSE_PARAMETERS_NONE();
767 
768 	RETURN_LONG(0);
769 }
770 
ZEND_METHOD(ZendTestNS_UnlikelyCompileError,method)771 static ZEND_METHOD(ZendTestNS_UnlikelyCompileError, method)
772 {
773 	ZEND_PARSE_PARAMETERS_NONE();
774 
775 	RETURN_NULL();
776 }
777 
ZEND_METHOD(ZendTestNS_NotUnlikelyCompileError,method)778 static ZEND_METHOD(ZendTestNS_NotUnlikelyCompileError, method)
779 {
780 	ZEND_PARSE_PARAMETERS_NONE();
781 
782 	RETURN_NULL();
783 }
784 
ZEND_METHOD(ZendTestNS2_Foo,method)785 static ZEND_METHOD(ZendTestNS2_Foo, method)
786 {
787 	ZEND_PARSE_PARAMETERS_NONE();
788 }
789 
ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo,method)790 static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method)
791 {
792 	ZEND_PARSE_PARAMETERS_NONE();
793 }
794 
ZEND_METHOD(ZendTestParameterAttribute,__construct)795 static ZEND_METHOD(ZendTestParameterAttribute, __construct)
796 {
797 	zend_string *parameter;
798 
799 	ZEND_PARSE_PARAMETERS_START(1, 1)
800 		Z_PARAM_STR(parameter)
801 	ZEND_PARSE_PARAMETERS_END();
802 
803 	ZVAL_STR_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), parameter);
804 }
805 
ZEND_METHOD(ZendTestPropertyAttribute,__construct)806 static ZEND_METHOD(ZendTestPropertyAttribute, __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(ZendTestClassWithMethodWithParameterAttribute,no_override)817 static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override)
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 	RETURN_LONG(2);
826 }
827 
ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute,override)828 static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, 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(3);
837 }
838 
ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute,override)839 static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, 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(4);
848 }
849 
ZEND_METHOD(ZendTestForbidDynamicCall,call)850 static ZEND_METHOD(ZendTestForbidDynamicCall, call)
851 {
852 	ZEND_PARSE_PARAMETERS_NONE();
853 
854 	zend_forbid_dynamic_call();
855 }
856 
ZEND_METHOD(ZendTestForbidDynamicCall,callStatic)857 static ZEND_METHOD(ZendTestForbidDynamicCall, callStatic)
858 {
859 	ZEND_PARSE_PARAMETERS_NONE();
860 
861 	zend_forbid_dynamic_call();
862 }
863 
ZEND_METHOD(_ZendTestMagicCall,__call)864 static ZEND_METHOD(_ZendTestMagicCall, __call)
865 {
866 	zend_string *name;
867 	zval *arguments;
868 
869 	ZEND_PARSE_PARAMETERS_START(2, 2)
870 		Z_PARAM_STR(name)
871 		Z_PARAM_ARRAY(arguments)
872 	ZEND_PARSE_PARAMETERS_END();
873 
874 	zval name_zv;
875 	ZVAL_STR(&name_zv, name);
876 
877 	zend_string_addref(name);
878 	Z_TRY_ADDREF_P(arguments);
879 	RETURN_ARR(zend_new_pair(&name_zv, arguments));
880 }
881 
882 PHP_INI_BEGIN()
883 	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)
884 	STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
885 	STD_PHP_INI_BOOLEAN("zend_test.print_stderr_mshutdown", "0", PHP_INI_SYSTEM, OnUpdateBool, print_stderr_mshutdown, zend_zend_test_globals, zend_test_globals)
886 #ifdef HAVE_COPY_FILE_RANGE
887 	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)
888 #endif
889 	STD_PHP_INI_ENTRY("zend_test.quantity_value", "0", PHP_INI_ALL, OnUpdateLong, quantity_value, zend_zend_test_globals, zend_test_globals)
890 	STD_PHP_INI_ENTRY("zend_test.str_test", "", PHP_INI_ALL, OnUpdateStr, str_test, zend_zend_test_globals, zend_test_globals)
891 	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)
892 	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)
893 PHP_INI_END()
894 
895 void (*old_zend_execute_ex)(zend_execute_data *execute_data);
custom_zend_execute_ex(zend_execute_data * execute_data)896 static void custom_zend_execute_ex(zend_execute_data *execute_data)
897 {
898 	old_zend_execute_ex(execute_data);
899 }
900 
PHP_MINIT_FUNCTION(zend_test)901 PHP_MINIT_FUNCTION(zend_test)
902 {
903 	zend_test_interface = register_class__ZendTestInterface();
904 
905 	zend_test_class = register_class__ZendTestClass(zend_test_interface);
906 	zend_test_class->create_object = zend_test_class_new;
907 	zend_test_class->get_static_method = zend_test_class_static_method_get;
908 
909 	zend_test_child_class = register_class__ZendTestChildClass(zend_test_class);
910 
911 	memcpy(&zend_test_class_handlers, &std_object_handlers, sizeof(zend_object_handlers));
912 	zend_test_class_handlers.get_method = zend_test_class_method_get;
913 
914 	zend_test_trait = register_class__ZendTestTrait();
915 
916 	register_test_symbols(module_number);
917 
918 	zend_test_attribute = register_class_ZendTestAttribute();
919 	{
920 		zend_internal_attribute *attr = zend_mark_internal_attribute(zend_test_attribute);
921 		attr->validator = zend_attribute_validate_zendtestattribute;
922 	}
923 
924 	zend_test_parameter_attribute = register_class_ZendTestParameterAttribute();
925 	zend_mark_internal_attribute(zend_test_parameter_attribute);
926 
927 	{
928 		zend_attribute *attr;
929 
930 		attr = zend_add_parameter_attribute(
931 			zend_hash_str_find_ptr(CG(function_table), "zend_test_parameter_with_attribute", sizeof("zend_test_parameter_with_attribute") - 1),
932 			0,
933 			zend_test_parameter_attribute->name,
934 			1
935 		);
936 
937 		ZVAL_PSTRING(&attr->args[0].value, "value1");
938 	}
939 
940 	zend_test_property_attribute = register_class_ZendTestPropertyAttribute();
941 	zend_mark_internal_attribute(zend_test_property_attribute);
942 
943 	zend_test_class_with_method_with_parameter_attribute = register_class_ZendTestClassWithMethodWithParameterAttribute();
944 
945 	{
946 		zend_attribute *attr;
947 
948 		attr = zend_add_parameter_attribute(
949 			zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "no_override", sizeof("no_override") - 1),
950 			0,
951 			zend_test_parameter_attribute->name,
952 			1
953 		);
954 
955 		ZVAL_PSTRING(&attr->args[0].value, "value2");
956 
957 		attr = zend_add_parameter_attribute(
958 			zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
959 			0,
960 			zend_test_parameter_attribute->name,
961 			1
962 		);
963 
964 		ZVAL_PSTRING(&attr->args[0].value, "value3");
965 	}
966 
967 	zend_test_child_class_with_method_with_parameter_attribute = register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_test_class_with_method_with_parameter_attribute);
968 
969 	{
970 		zend_attribute *attr;
971 
972 		attr = zend_add_parameter_attribute(
973 			zend_hash_str_find_ptr(&zend_test_child_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
974 			0,
975 			zend_test_parameter_attribute->name,
976 			1
977 		);
978 
979 		ZVAL_PSTRING(&attr->args[0].value, "value4");
980 	}
981 
982 	zend_test_forbid_dynamic_call = register_class_ZendTestForbidDynamicCall();
983 
984 	zend_test_ns_foo_class = register_class_ZendTestNS_Foo();
985 	zend_test_ns_unlikely_compile_error_class = register_class_ZendTestNS_UnlikelyCompileError();
986 	zend_test_ns_not_unlikely_compile_error_class = register_class_ZendTestNS_NotUnlikelyCompileError();
987 	zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo();
988 	zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo();
989 
990 	zend_test_unit_enum = register_class_ZendTestUnitEnum();
991 	zend_test_string_enum = register_class_ZendTestStringEnum();
992 	zend_test_int_enum = register_class_ZendTestIntEnum();
993 
994 	zend_test_magic_call = register_class__ZendTestMagicCall();
995 
996 	zend_register_functions(NULL, ext_function_legacy, NULL, EG(current_module)->type);
997 
998 	// Loading via dl() not supported with the observer API
999 	if (type != MODULE_TEMPORARY) {
1000 		REGISTER_INI_ENTRIES();
1001 	} else {
1002 		(void)ini_entries;
1003 	}
1004 
1005 	if (ZT_G(replace_zend_execute_ex)) {
1006 		old_zend_execute_ex = zend_execute_ex;
1007 		zend_execute_ex = custom_zend_execute_ex;
1008 	}
1009 
1010 	if (ZT_G(register_passes)) {
1011 		zend_optimizer_register_pass(pass1);
1012 		zend_optimizer_register_pass(pass2);
1013 	}
1014 
1015 	zend_test_observer_init(INIT_FUNC_ARGS_PASSTHRU);
1016 	zend_test_fiber_init();
1017 	zend_test_iterators_init();
1018 
1019 	return SUCCESS;
1020 }
1021 
PHP_MSHUTDOWN_FUNCTION(zend_test)1022 PHP_MSHUTDOWN_FUNCTION(zend_test)
1023 {
1024 	if (type != MODULE_TEMPORARY) {
1025 		UNREGISTER_INI_ENTRIES();
1026 	}
1027 
1028 	zend_test_observer_shutdown(SHUTDOWN_FUNC_ARGS_PASSTHRU);
1029 
1030 	if (ZT_G(print_stderr_mshutdown)) {
1031 		fprintf(stderr, "[zend-test] MSHUTDOWN\n");
1032 	}
1033 
1034 	return SUCCESS;
1035 }
1036 
PHP_RINIT_FUNCTION(zend_test)1037 PHP_RINIT_FUNCTION(zend_test)
1038 {
1039 	zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
1040 	ZT_G(observer_nesting_depth) = 0;
1041 	return SUCCESS;
1042 }
1043 
PHP_RSHUTDOWN_FUNCTION(zend_test)1044 PHP_RSHUTDOWN_FUNCTION(zend_test)
1045 {
1046 	zend_ulong obj_key;
1047 	ZEND_HASH_FOREACH_NUM_KEY(&ZT_G(global_weakmap), obj_key) {
1048 		zend_weakrefs_hash_del(&ZT_G(global_weakmap), zend_weakref_key_to_object(obj_key));
1049 	} ZEND_HASH_FOREACH_END();
1050 	zend_hash_destroy(&ZT_G(global_weakmap));
1051 
1052 	if (ZT_G(zend_test_heap))  {
1053 		free(ZT_G(zend_test_heap));
1054 		ZT_G(zend_test_heap) = NULL;
1055 		zend_mm_set_heap(ZT_G(zend_orig_heap));
1056 	}
1057 
1058 	return SUCCESS;
1059 }
1060 
PHP_GINIT_FUNCTION(zend_test)1061 static PHP_GINIT_FUNCTION(zend_test)
1062 {
1063 #if defined(COMPILE_DL_ZEND_TEST) && defined(ZTS)
1064 	ZEND_TSRMLS_CACHE_UPDATE();
1065 #endif
1066 	memset(zend_test_globals, 0, sizeof(*zend_test_globals));
1067 
1068 	zend_test_observer_ginit(zend_test_globals);
1069 }
1070 
PHP_GSHUTDOWN_FUNCTION(zend_test)1071 static PHP_GSHUTDOWN_FUNCTION(zend_test)
1072 {
1073 	zend_test_observer_gshutdown(zend_test_globals);
1074 }
1075 
PHP_MINFO_FUNCTION(zend_test)1076 PHP_MINFO_FUNCTION(zend_test)
1077 {
1078 	php_info_print_table_start();
1079 	php_info_print_table_header(2, "zend_test extension", "enabled");
1080 	php_info_print_table_end();
1081 
1082 	DISPLAY_INI_ENTRIES();
1083 }
1084 
1085 zend_module_entry zend_test_module_entry = {
1086 	STANDARD_MODULE_HEADER,
1087 	"zend_test",
1088 	ext_functions,
1089 	PHP_MINIT(zend_test),
1090 	PHP_MSHUTDOWN(zend_test),
1091 	PHP_RINIT(zend_test),
1092 	PHP_RSHUTDOWN(zend_test),
1093 	PHP_MINFO(zend_test),
1094 	PHP_ZEND_TEST_VERSION,
1095 	PHP_MODULE_GLOBALS(zend_test),
1096 	PHP_GINIT(zend_test),
1097 	PHP_GSHUTDOWN(zend_test),
1098 	NULL,
1099 	STANDARD_MODULE_PROPERTIES_EX
1100 };
1101 
1102 #ifdef COMPILE_DL_ZEND_TEST
1103 # ifdef ZTS
1104 ZEND_TSRMLS_CACHE_DEFINE()
1105 # endif
ZEND_GET_MODULE(zend_test)1106 ZEND_GET_MODULE(zend_test)
1107 #endif
1108 
1109 /* The important part here is the ZEND_FASTCALL. */
1110 PHP_ZEND_TEST_API int ZEND_FASTCALL bug78270(const char *str, size_t str_len)
1111 {
1112 	char * copy = zend_strndup(str, str_len);
1113 	int r = (int) ZEND_ATOL(copy);
1114 	free(copy);
1115 	return r;
1116 }
1117 
bug79096(void)1118 PHP_ZEND_TEST_API struct bug79096 bug79096(void)
1119 {
1120 	struct bug79096 b;
1121 
1122 	b.a = 1;
1123 	b.b = 1;
1124 	return b;
1125 }
1126 
bug79532(off_t * array,size_t elems)1127 PHP_ZEND_TEST_API void bug79532(off_t *array, size_t elems)
1128 {
1129 	int i;
1130 	for (i = 0; i < elems; i++) {
1131 		array[i] = i;
1132 	}
1133 }
1134 
1135 PHP_ZEND_TEST_API int *(*bug79177_cb)(void);
bug79177(void)1136 void bug79177(void)
1137 {
1138 	bug79177_cb();
1139 }
1140 
1141 typedef struct bug80847_01 {
1142 	uint64_t b;
1143 	double c;
1144 } bug80847_01;
1145 typedef struct bug80847_02 {
1146 	bug80847_01 a;
1147 } bug80847_02;
1148 
ffi_bug80847(bug80847_02 s)1149 PHP_ZEND_TEST_API bug80847_02 ffi_bug80847(bug80847_02 s) {
1150 	s.a.b += 10;
1151 	s.a.c -= 10.0;
1152 	return s;
1153 }
1154 
1155 PHP_ZEND_TEST_API void (*bug_gh9090_void_none_ptr)(void) = NULL;
1156 PHP_ZEND_TEST_API void (*bug_gh9090_void_int_char_ptr)(int, char *) = NULL;
1157 PHP_ZEND_TEST_API void (*bug_gh9090_void_int_char_var_ptr)(int, char *, ...) = NULL;
1158 PHP_ZEND_TEST_API void (*bug_gh9090_void_char_int_ptr)(char *, int) = NULL;
1159 PHP_ZEND_TEST_API int (*bug_gh9090_int_int_char_ptr)(int, char *) = NULL;
1160 
bug_gh9090_void_none(void)1161 PHP_ZEND_TEST_API void bug_gh9090_void_none(void) {
1162     php_printf("bug_gh9090_none\n");
1163 }
1164 
bug_gh9090_void_int_char(int i,char * s)1165 PHP_ZEND_TEST_API void bug_gh9090_void_int_char(int i, char *s) {
1166     php_printf("bug_gh9090_int_char %d %s\n", i, s);
1167 }
1168 
bug_gh9090_void_int_char_var(int i,char * fmt,...)1169 PHP_ZEND_TEST_API void bug_gh9090_void_int_char_var(int i, char *fmt, ...) {
1170     va_list args;
1171     char *buffer;
1172 
1173     va_start(args, fmt);
1174 
1175     zend_vspprintf(&buffer, 0, fmt, args);
1176     php_printf("bug_gh9090_void_int_char_var %s\n", buffer);
1177     efree(buffer);
1178 
1179     va_end(args);
1180 }
1181 
1182 #ifdef HAVE_COPY_FILE_RANGE
1183 /**
1184  * This function allows us to simulate early return of copy_file_range by setting the limit_copy_file_range ini setting.
1185  */
1186 #ifdef __MUSL__
1187 typedef off_t off64_t;
1188 #endif
copy_file_range(int fd_in,off64_t * off_in,int fd_out,off64_t * off_out,size_t len,unsigned int flags)1189 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)
1190 {
1191 	ssize_t (*original_copy_file_range)(int, off64_t *, int, off64_t *, size_t, unsigned int) = dlsym(RTLD_NEXT, "copy_file_range");
1192 	if (ZT_G(limit_copy_file_range) >= Z_L(0)) {
1193 		len = ZT_G(limit_copy_file_range);
1194 	}
1195 	return original_copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
1196 }
1197 #endif
1198