diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2017-03-11 00:33:32 +0100 |
---|---|---|
committer | Joe Watkins <krakjoe@php.net> | 2017-03-12 18:58:50 +0000 |
commit | b3ca0c25003e5e9279159aa2e6460b25908332c4 (patch) | |
tree | b47666ad94b030fe31820d3e4f325788f5ae1a5f | |
parent | ea91c082328c6f93f20a078896c16c2051061f47 (diff) | |
download | php-git-b3ca0c25003e5e9279159aa2e6460b25908332c4.tar.gz |
zend-test extension to house code that is required for testing internal APIs, but that we would not want to expose for regular builds
-rw-r--r-- | Zend/tests/return_types/internal_functions001.phpt | 13 | ||||
-rw-r--r-- | Zend/tests/return_types/internal_functions002.phpt | 12 | ||||
-rw-r--r-- | Zend/zend_builtin_functions.c | 199 | ||||
-rw-r--r-- | appveyor/build_task.bat | 1 | ||||
-rw-r--r-- | ext/sockets/tests/socket_export_stream-5.phpt | 6 | ||||
-rw-r--r-- | ext/sockets/tests/socket_import_stream-5.phpt | 6 | ||||
-rw-r--r-- | ext/standard/tests/file/bug52820.phpt | 6 | ||||
-rw-r--r-- | ext/standard/tests/file/stream_enclosed.phpt | 6 | ||||
-rw-r--r-- | ext/standard/tests/url/parse_url_unterminated.phpt | 887 | ||||
-rw-r--r-- | ext/zend_test/config.m4 | 6 | ||||
-rw-r--r-- | ext/zend_test/config.w32 | 8 | ||||
-rw-r--r-- | ext/zend_test/php_test.h | 47 | ||||
-rw-r--r-- | ext/zend_test/test.c | 260 | ||||
-rwxr-xr-x | travis/compile.sh | 3 |
14 files changed, 1236 insertions, 224 deletions
diff --git a/Zend/tests/return_types/internal_functions001.phpt b/Zend/tests/return_types/internal_functions001.phpt index fffaf54574..5dfd2784da 100644 --- a/Zend/tests/return_types/internal_functions001.phpt +++ b/Zend/tests/return_types/internal_functions001.phpt @@ -1,15 +1,14 @@ --TEST-- Return type for internal functions - --SKIPIF-- <?php -if (!function_exists('zend_test_func')) { - print 'skip'; -} - +if (!function_exists('zend_test_array_return')) die('skip'); +// Internal function return types are only checked in debug builds +if (!PHP_DEBUG) die('skip requires debug build'); +?> --FILE-- <?php -zend_test_func(); +zend_test_array_return(); ?> --EXPECTF-- -Fatal error: Return value of zend_test_func() must be of the type array, null returned in %s on line %d +Fatal error: Return value of zend_test_array_return() must be of the type array, null returned in %s on line %d diff --git a/Zend/tests/return_types/internal_functions002.phpt b/Zend/tests/return_types/internal_functions002.phpt index 7cdb2b884a..0daf3481c8 100644 --- a/Zend/tests/return_types/internal_functions002.phpt +++ b/Zend/tests/return_types/internal_functions002.phpt @@ -1,16 +1,12 @@ --TEST-- Return type for internal functions 2 - --SKIPIF-- <?php -if (!function_exists('zend_test_func2')) { - print 'skip'; -} - +if (!function_exists('zend_test_nullable_array_return')) die('skip'); --FILE-- <?php -zend_test_func2(); -echo "==DONE==\n" +zend_test_nullable_array_return(); ?> ---EXPECTF-- +==DONE== +--EXPECT-- ==DONE== diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 55d1209ae0..7f6e46b736 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -29,15 +29,6 @@ #include "zend_closures.h" #include "zend_generators.h" -#undef ZEND_TEST_EXCEPTIONS - -#if ZEND_DEBUG -static zend_class_entry *zend_test_interface; -static zend_class_entry *zend_test_class; -static zend_class_entry *zend_test_trait; -static zend_object_handlers zend_test_class_handlers; -#endif - static ZEND_FUNCTION(zend_version); static ZEND_FUNCTION(func_num_args); static ZEND_FUNCTION(func_get_arg); @@ -61,13 +52,6 @@ static ZEND_FUNCTION(interface_exists); static ZEND_FUNCTION(trait_exists); static ZEND_FUNCTION(function_exists); static ZEND_FUNCTION(class_alias); -#if ZEND_DEBUG -static ZEND_FUNCTION(leak); -static ZEND_FUNCTION(leak_variable); -#ifdef ZEND_TEST_EXCEPTIONS -static ZEND_FUNCTION(crash); -#endif -#endif static ZEND_FUNCTION(get_included_files); static ZEND_FUNCTION(is_subclass_of); static ZEND_FUNCTION(is_a); @@ -93,13 +77,9 @@ static ZEND_FUNCTION(get_extension_funcs); static ZEND_FUNCTION(get_defined_constants); static ZEND_FUNCTION(debug_backtrace); static ZEND_FUNCTION(debug_print_backtrace); -#if ZEND_DEBUG -static ZEND_FUNCTION(zend_test_func); -static ZEND_FUNCTION(zend_test_func2); -#ifdef ZTS +#if ZEND_DEBUG && defined(ZTS) static ZEND_FUNCTION(zend_thread_id); #endif -#endif static ZEND_FUNCTION(gc_mem_caches); static ZEND_FUNCTION(gc_collect_cycles); static ZEND_FUNCTION(gc_enabled); @@ -199,13 +179,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2) ZEND_ARG_INFO(0, autoload) ZEND_END_ARG_INFO() -#if ZEND_DEBUG -ZEND_BEGIN_ARG_INFO_EX(arginfo_leak_variable, 0, 0, 1) - ZEND_ARG_INFO(0, variable) - ZEND_ARG_INFO(0, leak_data) -ZEND_END_ARG_INFO() -#endif - ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1) ZEND_ARG_INFO(0, message) ZEND_ARG_INFO(0, error_type) @@ -255,70 +228,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1) ZEND_ARG_INFO(0, extension_name) ZEND_END_ARG_INFO() -#if ZEND_DEBUG -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func, IS_ARRAY, 0) -ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_func2, IS_ARRAY, 1) -ZEND_END_ARG_INFO() -#endif - -/* }}} */ - -#if ZEND_DEBUG -static zend_object *zend_test_class_new(zend_class_entry *class_type) /* {{{ */ { - zend_object *obj = zend_objects_new(class_type); - obj->handlers = &zend_test_class_handlers; - return obj; -} -/* }}} */ - -static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) /* {{{ */ { - zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); - fptr->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY; - fptr->num_args = 1; - fptr->arg_info = NULL; - fptr->scope = (*object)->ce; - fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; - fptr->function_name = zend_string_copy(name); - fptr->handler = ZEND_FN(zend_test_func); - zend_set_function_arg_flags((zend_function*)fptr); - - return (zend_function*)fptr; -} -/* }}} */ - -static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name) /* {{{ */ { - zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); - fptr->type = ZEND_OVERLOADED_FUNCTION; - fptr->num_args = 1; - fptr->arg_info = NULL; - fptr->scope = ce; - fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC; - fptr->function_name = name; - fptr->handler = ZEND_FN(zend_test_func); - zend_set_function_arg_flags((zend_function*)fptr); - - return (zend_function*)fptr; -} -/* }}} */ - -static int zend_test_class_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { - RETVAL_STR(zend_string_copy(method)); - return 0; -} -/* }}} */ - -static ZEND_METHOD(_ZendTestTrait, testMethod) /* {{{ */ { - RETURN_TRUE; -} /* }}} */ -static zend_function_entry zend_test_trait_methods[] = { - ZEND_ME(_ZendTestTrait, testMethod, arginfo_zend__void, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; -#endif - static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(zend_version, arginfo_zend__void) ZEND_FE(func_num_args, arginfo_zend__void) @@ -343,13 +254,6 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(trait_exists, arginfo_trait_exists) ZEND_FE(function_exists, arginfo_function_exists) ZEND_FE(class_alias, arginfo_class_alias) -#if ZEND_DEBUG - ZEND_FE(leak, NULL) - ZEND_FE(leak_variable, arginfo_leak_variable) -#ifdef ZEND_TEST_EXCEPTIONS - ZEND_FE(crash, NULL) -#endif -#endif ZEND_FE(get_included_files, arginfo_zend__void) ZEND_FALIAS(get_required_files, get_included_files, arginfo_zend__void) ZEND_FE(is_subclass_of, arginfo_is_subclass_of) @@ -377,13 +281,9 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(get_defined_constants, arginfo_get_defined_constants) ZEND_FE(debug_backtrace, arginfo_debug_backtrace) ZEND_FE(debug_print_backtrace, arginfo_debug_print_backtrace) -#if ZEND_DEBUG - ZEND_FE(zend_test_func, arginfo_zend_test_func) - ZEND_FE(zend_test_func2, arginfo_zend_test_func2) -#ifdef ZTS +#if ZEND_DEBUG && defined(ZTS) ZEND_FE(zend_thread_id, NULL) #endif -#endif ZEND_FE(gc_mem_caches, arginfo_zend__void) ZEND_FE(gc_collect_cycles, arginfo_zend__void) ZEND_FE(gc_enabled, arginfo_zend__void) @@ -401,26 +301,6 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */ zend_register_default_classes(); -#if ZEND_DEBUG - INIT_CLASS_ENTRY(class_entry, "_ZendTestInterface", NULL); - zend_test_interface = zend_register_internal_interface(&class_entry); - zend_declare_class_constant_long(zend_test_interface, ZEND_STRL("DUMMY"), 0); - INIT_CLASS_ENTRY(class_entry, "_ZendTestClass", NULL); - zend_test_class = zend_register_internal_class_ex(&class_entry, NULL); - zend_class_implements(zend_test_class, 1, zend_test_interface); - zend_test_class->create_object = zend_test_class_new; - zend_test_class->get_static_method = zend_test_class_static_method_get; - - memcpy(&zend_test_class_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - zend_test_class_handlers.get_method = zend_test_class_method_get; - zend_test_class_handlers.call_method = zend_test_class_call_method; - - INIT_CLASS_ENTRY(class_entry, "_ZendTestTrait", zend_test_trait_methods); - zend_test_trait = zend_register_internal_class(&class_entry); - zend_test_trait->ce_flags |= ZEND_ACC_TRAIT; - zend_declare_property_null(zend_test_trait, "testProp", sizeof("testProp")-1, ZEND_ACC_PUBLIC); -#endif - return SUCCESS; } /* }}} */ @@ -1653,63 +1533,6 @@ ZEND_FUNCTION(class_alias) } /* }}} */ -#if ZEND_DEBUG -/* {{{ proto void leak([int num_bytes]) - Cause an intentional memory leak, for testing/debugging purposes */ -ZEND_FUNCTION(leak) -{ - zend_long leakbytes = 3; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &leakbytes) == FAILURE) { - return; - } - - emalloc(leakbytes); -} -/* }}} */ - -/* {{{ proto void leak_variable(mixed variable [, bool leak_data]) - Leak a variable that is a resource or an object */ -ZEND_FUNCTION(leak_variable) -{ - zval *zv; - zend_bool leak_data = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &zv, &leak_data) == FAILURE) { - return; - } - - if (!leak_data) { - Z_ADDREF_P(zv); - } else if (Z_TYPE_P(zv) == IS_RESOURCE) { - Z_ADDREF_P(zv); - } else if (Z_TYPE_P(zv) == IS_OBJECT) { - Z_ADDREF_P(zv); - } else { - zend_error(E_WARNING, "Leaking non-zval data is only applicable to resources and objects"); - } -} -/* }}} */ - - -#ifdef ZEND_TEST_EXCEPTIONS -/* {{{ proto void crash(void) - Crash the script */ -ZEND_FUNCTION(crash) -{ - char *nowhere = NULL; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - memcpy(nowhere, "something", sizeof("something")); -} -/* }}} */ -#endif - -#endif /* ZEND_DEBUG */ - /* {{{ proto array get_included_files(void) Returns an array with the file names that were include_once()'d */ ZEND_FUNCTION(get_included_files) @@ -2095,28 +1918,12 @@ ZEND_FUNCTION(create_function) } /* }}} */ -#if ZEND_DEBUG -ZEND_FUNCTION(zend_test_func) -{ - zval *arg1, *arg2; - - zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); -} - -ZEND_FUNCTION(zend_test_func2) -{ - zval *arg1, *arg2; - - zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); -} - -#ifdef ZTS +#if ZEND_DEBUG && defined(ZTS) ZEND_FUNCTION(zend_thread_id) { RETURN_LONG((zend_long)tsrm_thread_id()); } #endif -#endif /* {{{ proto string get_resource_type(resource res) Get the resource type name for a given resource */ diff --git a/appveyor/build_task.bat b/appveyor/build_task.bat index ad47854e0b..85a64e4fbd 100644 --- a/appveyor/build_task.bat +++ b/appveyor/build_task.bat @@ -39,6 +39,7 @@ call configure.bat ^ --enable-object-out-dir=%PHP_BUILD_OBJ_DIR% ^ --with-php-build=%DEPS_DIR% ^ %ADD_CONF% ^ + --enable-zend-test ^ --with-test-ini-ext-exclude=%EXT_EXCLUDE_FROM_TEST% if %errorlevel% neq 0 exit /b 3 diff --git a/ext/sockets/tests/socket_export_stream-5.phpt b/ext/sockets/tests/socket_export_stream-5.phpt index 732b2072d0..db2d018d47 100644 --- a/ext/sockets/tests/socket_export_stream-5.phpt +++ b/ext/sockets/tests/socket_export_stream-5.phpt @@ -5,7 +5,7 @@ socket_export_stream: effects of leaked handles if (!extension_loaded('sockets')) { die('SKIP sockets extension not available.'); } -if (!function_exists('leak_variable')) +if (!function_exists('zend_leak_variable')) die('SKIP only for debug builds'); --FILE-- <?php @@ -13,12 +13,12 @@ if (!function_exists('leak_variable')) $sock0 = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_bind($sock0, '0.0.0.0', 58380); $stream0 = socket_export_stream($sock0); -leak_variable($stream0, true); +zend_leak_variable($stream0); $sock1 = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_bind($sock1, '0.0.0.0', 58381); $stream1 = socket_export_stream($sock1); -leak_variable($sock1, true); +zend_leak_variable($sock1); echo "Done.\n"; --EXPECT-- diff --git a/ext/sockets/tests/socket_import_stream-5.phpt b/ext/sockets/tests/socket_import_stream-5.phpt index d48531e410..0583f2e4c2 100644 --- a/ext/sockets/tests/socket_import_stream-5.phpt +++ b/ext/sockets/tests/socket_import_stream-5.phpt @@ -5,18 +5,18 @@ socket_import_stream: effects of leaked handles if (!extension_loaded('sockets')) { die('SKIP sockets extension not available.'); } -if (!function_exists('leak_variable')) +if (!function_exists('zend_leak_variable')) die('SKIP only for debug builds'); --FILE-- <?php $stream0 = stream_socket_server("udp://0.0.0.0:58380", $errno, $errstr, STREAM_SERVER_BIND); $sock0 = socket_import_stream($stream0); -leak_variable($stream0, true); +zend_leak_variable($stream0); $stream1 = stream_socket_server("udp://0.0.0.0:58381", $errno, $errstr, STREAM_SERVER_BIND); $sock1 = socket_import_stream($stream1); -leak_variable($sock1, true); +zend_leak_variable($sock1); echo "Done.\n"; --EXPECT-- diff --git a/ext/standard/tests/file/bug52820.phpt b/ext/standard/tests/file/bug52820.phpt index a00ebf50b6..e51c27e457 100644 --- a/ext/standard/tests/file/bug52820.phpt +++ b/ext/standard/tests/file/bug52820.phpt @@ -2,7 +2,7 @@ Bug #52820 (writes to fopencookie FILE* not committed when seeking the stream) --SKIPIF-- <?php -if (!function_exists('leak_variable')) +if (!function_exists('zend_leak_variable')) die("skip only for debug builds"); /* unfortunately no standard function does a cast to FILE*, so we need * curl to test this */ @@ -33,10 +33,10 @@ echo "\nmemory stream (close after):\n"; fclose(do_stuff("php://memory")); echo "\ntemp stream (leak):\n"; -leak_variable(do_stuff("php://temp"), true); +zend_leak_variable(do_stuff("php://temp")); echo "\nmemory stream (leak):\n"; -leak_variable(do_stuff("php://memory"), true); +zend_leak_variable(do_stuff("php://memory")); echo "\nDone.\n"; --EXPECTF-- diff --git a/ext/standard/tests/file/stream_enclosed.phpt b/ext/standard/tests/file/stream_enclosed.phpt index f487ed0744..ff764c8f81 100644 --- a/ext/standard/tests/file/stream_enclosed.phpt +++ b/ext/standard/tests/file/stream_enclosed.phpt @@ -2,7 +2,7 @@ Unexposed/leaked stream encloses another stream --SKIPIF-- <?php -if (!function_exists('leak_variable')) die("skip only debug builds"); +if (!function_exists('zend_leak_variable')) die("skip only debug builds"); --FILE-- <?php $s = fopen('php://temp/maxmemory=1024','wb+'); @@ -15,6 +15,6 @@ while ($i++ < 5000) { fwrite($t, str_repeat('a',1024)); } -leak_variable($s, true); -leak_variable($t, true); +zend_leak_variable($s); +zend_leak_variable($t); --EXPECT-- diff --git a/ext/standard/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt new file mode 100644 index 0000000000..bb0e096856 --- /dev/null +++ b/ext/standard/tests/url/parse_url_unterminated.phpt @@ -0,0 +1,887 @@ +--TEST-- +Test parse_url() function: Parse unterminated string +--SKIPIF-- +<?php +if (!function_exists('zend_create_unterminated_string')) die('skip ext/test required'); +?> +--FILE-- +<?php + +/* + * This is the same as the basic001 test, but with unterminated strings. + */ + +include_once(dirname(__FILE__) . '/urls.inc'); + +foreach ($urls as $url) { + echo "\n--> $url: "; + $str = zend_create_unterminated_string($url); + var_dump(parse_url($str)); + zend_terminate_string($str); +} + +echo "Done"; +?> +--EXPECTF-- + +--> 64.246.30.37: array(1) { + ["path"]=> + string(12) "64.246.30.37" +} + +--> http://64.246.30.37: array(2) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(12) "64.246.30.37" +} + +--> http://64.246.30.37/: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(12) "64.246.30.37" + ["path"]=> + string(1) "/" +} + +--> 64.246.30.37/: array(1) { + ["path"]=> + string(13) "64.246.30.37/" +} + +--> 64.246.30.37:80/: array(3) { + ["host"]=> + string(12) "64.246.30.37" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" +} + +--> php.net: array(1) { + ["path"]=> + string(7) "php.net" +} + +--> php.net/: array(1) { + ["path"]=> + string(8) "php.net/" +} + +--> http://php.net: array(2) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(7) "php.net" +} + +--> http://php.net/: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(7) "php.net" + ["path"]=> + string(1) "/" +} + +--> www.php.net: array(1) { + ["path"]=> + string(11) "www.php.net" +} + +--> www.php.net/: array(1) { + ["path"]=> + string(12) "www.php.net/" +} + +--> http://www.php.net: array(2) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" +} + +--> http://www.php.net/: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["path"]=> + string(1) "/" +} + +--> www.php.net:80: array(2) { + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) +} + +--> http://www.php.net:80: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) +} + +--> http://www.php.net:80/: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" +} + +--> http://www.php.net/index.php: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["path"]=> + string(10) "/index.php" +} + +--> www.php.net/?: array(1) { + ["path"]=> + string(12) "www.php.net/" +} + +--> www.php.net:80/?: array(3) { + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" +} + +--> http://www.php.net/?: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["path"]=> + string(1) "/" +} + +--> http://www.php.net:80/?: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" +} + +--> http://www.php.net:80/index.php: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(10) "/index.php" +} + +--> http://www.php.net:80/foo/bar/index.php: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(18) "/foo/bar/index.php" +} + +--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/file.php: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(53) "/this/is/a/very/deep/directory/structure/and/file.php" +} + +--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/file.php?lots=1&of=2¶meters=3&too=4&here=5: array(5) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(53) "/this/is/a/very/deep/directory/structure/and/file.php" + ["query"]=> + string(37) "lots=1&of=2¶meters=3&too=4&here=5" +} + +--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(45) "/this/is/a/very/deep/directory/structure/and/" +} + +--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/file.php: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(53) "/this/is/a/very/deep/directory/structure/and/file.php" +} + +--> http://www.php.net:80/this/../a/../deep/directory: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(28) "/this/../a/../deep/directory" +} + +--> http://www.php.net:80/this/../a/../deep/directory/: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(29) "/this/../a/../deep/directory/" +} + +--> http://www.php.net:80/this/is/a/very/deep/directory/../file.php: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(42) "/this/is/a/very/deep/directory/../file.php" +} + +--> http://www.php.net:80/index.php: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(10) "/index.php" +} + +--> http://www.php.net:80/index.php?: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(10) "/index.php" +} + +--> http://www.php.net:80/#foo: array(5) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" + ["fragment"]=> + string(3) "foo" +} + +--> http://www.php.net:80/?#: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" +} + +--> http://www.php.net:80/?test=1: array(5) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" + ["query"]=> + string(6) "test=1" +} + +--> http://www.php.net/?test=1&: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["path"]=> + string(1) "/" + ["query"]=> + string(7) "test=1&" +} + +--> http://www.php.net:80/?&: array(5) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(1) "/" + ["query"]=> + string(1) "&" +} + +--> http://www.php.net:80/index.php?test=1&: array(5) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(7) "test=1&" +} + +--> http://www.php.net/index.php?&: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(1) "&" +} + +--> http://www.php.net:80/index.php?foo&: array(5) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(4) "foo&" +} + +--> http://www.php.net/index.php?&foo: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(4) "&foo" +} + +--> http://www.php.net:80/index.php?test=1&test2=char&test3=mixesCI: array(5) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" +} + +--> www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(5) { + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" + ["fragment"]=> + string(16) "some_page_ref123" +} + +--> http://secret@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["user"]=> + string(6) "secret" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" + ["fragment"]=> + string(16) "some_page_ref123" +} + +--> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["user"]=> + string(6) "secret" + ["pass"]=> + string(0) "" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" + ["fragment"]=> + string(16) "some_page_ref123" +} + +--> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(8) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["user"]=> + string(0) "" + ["pass"]=> + string(7) "hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" + ["fragment"]=> + string(16) "some_page_ref123" +} + +--> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["user"]=> + string(6) "secret" + ["pass"]=> + string(7) "hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" + ["fragment"]=> + string(16) "some_page_ref123" +} + +--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["user"]=> + string(14) "secret@hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" + ["fragment"]=> + string(16) "some_page_ref123" +} + +--> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(8) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "www.php.net" + ["port"]=> + int(80) + ["user"]=> + string(6) "secret" + ["pass"]=> + string(7) "hid:out" + ["path"]=> + string(10) "/index.php" + ["query"]=> + string(31) "test=1&test2=char&test3=mixesCI" + ["fragment"]=> + string(16) "some_page_ref123" +} + +--> nntp://news.php.net: array(2) { + ["scheme"]=> + string(4) "nntp" + ["host"]=> + string(12) "news.php.net" +} + +--> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz: array(3) { + ["scheme"]=> + string(3) "ftp" + ["host"]=> + string(11) "ftp.gnu.org" + ["path"]=> + string(22) "/gnu/glic/glibc.tar.gz" +} + +--> zlib:http://foo@bar: array(2) { + ["scheme"]=> + string(4) "zlib" + ["path"]=> + string(14) "http://foo@bar" +} + +--> zlib:filename.txt: array(2) { + ["scheme"]=> + string(4) "zlib" + ["path"]=> + string(12) "filename.txt" +} + +--> zlib:/path/to/my/file/file.txt: array(2) { + ["scheme"]=> + string(4) "zlib" + ["path"]=> + string(25) "/path/to/my/file/file.txt" +} + +--> foo://foo@bar: array(3) { + ["scheme"]=> + string(3) "foo" + ["host"]=> + string(3) "bar" + ["user"]=> + string(3) "foo" +} + +--> mailto:me@mydomain.com: array(2) { + ["scheme"]=> + string(6) "mailto" + ["path"]=> + string(15) "me@mydomain.com" +} + +--> /foo.php?a=b&c=d: array(2) { + ["path"]=> + string(8) "/foo.php" + ["query"]=> + string(7) "a=b&c=d" +} + +--> foo.php?a=b&c=d: array(2) { + ["path"]=> + string(7) "foo.php" + ["query"]=> + string(7) "a=b&c=d" +} + +--> http://user:passwd@www.example.com:8080?bar=1&boom=0: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(15) "www.example.com" + ["port"]=> + int(8080) + ["user"]=> + string(4) "user" + ["pass"]=> + string(6) "passwd" + ["query"]=> + string(12) "bar=1&boom=0" +} + +--> http://user_me-you:my_pas-word@www.example.com:8080?bar=1&boom=0: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(15) "www.example.com" + ["port"]=> + int(8080) + ["user"]=> + string(11) "user_me-you" + ["pass"]=> + string(11) "my_pas-word" + ["query"]=> + string(12) "bar=1&boom=0" +} + +--> file:///path/to/file: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(13) "/path/to/file" +} + +--> file://path/to/file: array(3) { + ["scheme"]=> + string(4) "file" + ["host"]=> + string(4) "path" + ["path"]=> + string(8) "/to/file" +} + +--> file:/path/to/file: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(13) "/path/to/file" +} + +--> http://1.2.3.4:/abc.asp?a=1&b=2: array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(7) "1.2.3.4" + ["path"]=> + string(8) "/abc.asp" + ["query"]=> + string(7) "a=1&b=2" +} + +--> http://foo.com#bar: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(7) "foo.com" + ["fragment"]=> + string(3) "bar" +} + +--> scheme:: array(1) { + ["scheme"]=> + string(6) "scheme" +} + +--> foo+bar://baz@bang/bla: array(4) { + ["scheme"]=> + string(7) "foo+bar" + ["host"]=> + string(4) "bang" + ["user"]=> + string(3) "baz" + ["path"]=> + string(4) "/bla" +} + +--> gg:9130731: array(2) { + ["scheme"]=> + string(2) "gg" + ["path"]=> + string(7) "9130731" +} + +--> http://user:@pass@host/path?argument?value#etc: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(4) "host" + ["user"]=> + string(4) "user" + ["pass"]=> + string(5) "@pass" + ["path"]=> + string(5) "/path" + ["query"]=> + string(14) "argument?value" + ["fragment"]=> + string(3) "etc" +} + +--> http://10.10.10.10/:80: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "10.10.10.10" + ["path"]=> + string(4) "/:80" +} + +--> http://x:?: array(2) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(1) "x" +} + +--> x:blah.com: array(2) { + ["scheme"]=> + string(1) "x" + ["path"]=> + string(8) "blah.com" +} + +--> x:/blah.com: array(2) { + ["scheme"]=> + string(1) "x" + ["path"]=> + string(9) "/blah.com" +} + +--> x://::abc/?: bool(false) + +--> http://::?: array(2) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(1) ":" +} + +--> http://::#: array(2) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(1) ":" +} + +--> x://::6.5: array(3) { + ["scheme"]=> + string(1) "x" + ["host"]=> + string(1) ":" + ["port"]=> + int(6) +} + +--> http://?:/: bool(false) + +--> http://@?:/: bool(false) + +--> file:///:: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(2) "/:" +} + +--> file:///a:/: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(3) "a:/" +} + +--> file:///ab:/: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(5) "/ab:/" +} + +--> file:///a:/: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(3) "a:/" +} + +--> file:///@:/: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(3) "@:/" +} + +--> file:///:80/: array(2) { + ["scheme"]=> + string(4) "file" + ["path"]=> + string(5) "/:80/" +} + +--> []: array(1) { + ["path"]=> + string(2) "[]" +} + +--> http://[x:80]/: array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(6) "[x:80]" + ["path"]=> + string(1) "/" +} + +--> : array(1) { + ["path"]=> + string(0) "" +} + +--> /: array(1) { + ["path"]=> + string(1) "/" +} + +--> /rest/Users?filter={"id":"123"}: array(2) { + ["path"]=> + string(11) "/rest/Users" + ["query"]=> + string(19) "filter={"id":"123"}" +} + +--> http:///blah.com: bool(false) + +--> http://:80: bool(false) + +--> http://user@:80: bool(false) + +--> http://user:pass@:80: bool(false) + +--> http://:: bool(false) + +--> http://@/: bool(false) + +--> http://@:/: bool(false) + +--> http://:/: bool(false) + +--> http://?: bool(false) + +--> http://#: bool(false) + +--> http://?:: bool(false) + +--> http://:?: bool(false) + +--> http://blah.com:123456: bool(false) + +--> http://blah.com:abcdef: bool(false) +Done diff --git a/ext/zend_test/config.m4 b/ext/zend_test/config.m4 new file mode 100644 index 0000000000..becefcdd7e --- /dev/null +++ b/ext/zend_test/config.m4 @@ -0,0 +1,6 @@ +PHP_ARG_ENABLE(zend-test, whether to enable zend-test extension, +[ --enable-zend-test Enable zend-test extension]) + +if test "$PHP_ZEND_TEST" != "no"; then + PHP_NEW_EXTENSION(zend_test, test.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) +fi diff --git a/ext/zend_test/config.w32 b/ext/zend_test/config.w32 new file mode 100644 index 0000000000..9b1574ef4e --- /dev/null +++ b/ext/zend_test/config.w32 @@ -0,0 +1,8 @@ +// vim:ft=javascript + +ARG_ENABLE("zend-test", "enable zend-test extension", "no"); + +if (PHP_ZEND_TEST != "no") { + EXTENSION("zend_test", "test.c", PHP_ZEND_TEST_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +} + diff --git a/ext/zend_test/php_test.h b/ext/zend_test/php_test.h new file mode 100644 index 0000000000..fe8c5e47e4 --- /dev/null +++ b/ext/zend_test/php_test.h @@ -0,0 +1,47 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2017 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_TEST_H +#define PHP_TEST_H + +extern zend_module_entry zend_test_module_entry; +#define phpext_zend_test_ptr &zend_test_module_entry + +#define PHP_ZEND_TEST_VERSION "0.1.0" + +#ifdef ZTS +#include "TSRM.h" +#endif + +#if defined(ZTS) && defined(COMPILE_DL_ZEND_TEST) +ZEND_TSRMLS_CACHE_EXTERN() +#endif + +#endif + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c new file mode 100644 index 0000000000..f203af803f --- /dev/null +++ b/ext/zend_test/test.c @@ -0,0 +1,260 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2017 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "php_test.h" + +static zend_class_entry *zend_test_interface; +static zend_class_entry *zend_test_class; +static zend_class_entry *zend_test_trait; +static zend_object_handlers zend_test_class_handlers; + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_array_return, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_zend_test_nullable_array_return, IS_ARRAY, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_terminate_string, 0, 0, 1) + ZEND_ARG_INFO(1, str) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_leak_variable, 0, 0, 1) + ZEND_ARG_INFO(0, variable) +ZEND_END_ARG_INFO() + +ZEND_FUNCTION(zend_test_func) +{ + /* dummy */ +} + +ZEND_FUNCTION(zend_test_array_return) +{ + zval *arg1, *arg2; + + zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); +} + +ZEND_FUNCTION(zend_test_nullable_array_return) +{ + zval *arg1, *arg2; + + zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); +} + +/* Create a string without terminating null byte. Must be termined with + * zend_terminate_string() before destruction, otherwise a warning is issued + * in debug builds. */ +ZEND_FUNCTION(zend_create_unterminated_string) +{ + zend_string *str, *res; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &str) == FAILURE) { + return; + } + + res = zend_string_alloc(ZSTR_LEN(str), 0); + memcpy(ZSTR_VAL(res), ZSTR_VAL(str), ZSTR_LEN(str)); + /* No trailing null byte */ + + RETURN_STR(res); +} + +/* Enforce terminate null byte on string. This avoids a warning in debug builds. */ +ZEND_FUNCTION(zend_terminate_string) +{ + zend_string *str; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &str) == FAILURE) { + return; + } + + ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0'; +} + +/* {{{ proto void zend_leak_bytes([int num_bytes]) + Cause an intentional memory leak, for testing/debugging purposes */ +ZEND_FUNCTION(zend_leak_bytes) +{ + zend_long leakbytes = 3; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &leakbytes) == FAILURE) { + return; + } + + emalloc(leakbytes); +} +/* }}} */ + +/* {{{ proto void zend_leak_variable(mixed variable) + Leak a refcounted variable */ +ZEND_FUNCTION(zend_leak_variable) +{ + zval *zv; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zv) == FAILURE) { + return; + } + + if (!Z_REFCOUNTED_P(zv)) { + zend_error(E_WARNING, "Cannot leak variable that is not refcounted"); + return; + } + + Z_ADDREF_P(zv); +} +/* }}} */ + +static zend_object *zend_test_class_new(zend_class_entry *class_type) /* {{{ */ { + zend_object *obj = zend_objects_new(class_type); + obj->handlers = &zend_test_class_handlers; + return obj; +} +/* }}} */ + +static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) /* {{{ */ { + zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); + fptr->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY; + fptr->num_args = 1; + fptr->arg_info = NULL; + fptr->scope = (*object)->ce; + fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; + fptr->function_name = zend_string_copy(name); + fptr->handler = ZEND_FN(zend_test_func); + zend_set_function_arg_flags((zend_function*)fptr); + + return (zend_function*)fptr; +} +/* }}} */ + +static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name) /* {{{ */ { + zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); + fptr->type = ZEND_OVERLOADED_FUNCTION; + fptr->num_args = 1; + fptr->arg_info = NULL; + fptr->scope = ce; + fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC; + fptr->function_name = name; + fptr->handler = ZEND_FN(zend_test_func); + zend_set_function_arg_flags((zend_function*)fptr); + + return (zend_function*)fptr; +} +/* }}} */ + +static int zend_test_class_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { + RETVAL_STR(zend_string_copy(method)); + return 0; +} +/* }}} */ + +static ZEND_METHOD(_ZendTestTrait, testMethod) /* {{{ */ { + RETURN_TRUE; +} +/* }}} */ + +static zend_function_entry zend_test_trait_methods[] = { + ZEND_ME(_ZendTestTrait, testMethod, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +PHP_MINIT_FUNCTION(zend_test) +{ + zend_class_entry class_entry; + + INIT_CLASS_ENTRY(class_entry, "_ZendTestInterface", NULL); + zend_test_interface = zend_register_internal_interface(&class_entry); + zend_declare_class_constant_long(zend_test_interface, ZEND_STRL("DUMMY"), 0); + INIT_CLASS_ENTRY(class_entry, "_ZendTestClass", NULL); + zend_test_class = zend_register_internal_class_ex(&class_entry, NULL); + zend_class_implements(zend_test_class, 1, zend_test_interface); + zend_test_class->create_object = zend_test_class_new; + zend_test_class->get_static_method = zend_test_class_static_method_get; + + memcpy(&zend_test_class_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_test_class_handlers.get_method = zend_test_class_method_get; + zend_test_class_handlers.call_method = zend_test_class_call_method; + + INIT_CLASS_ENTRY(class_entry, "_ZendTestTrait", zend_test_trait_methods); + zend_test_trait = zend_register_internal_class(&class_entry); + zend_test_trait->ce_flags |= ZEND_ACC_TRAIT; + zend_declare_property_null(zend_test_trait, "testProp", sizeof("testProp")-1, ZEND_ACC_PUBLIC); + return SUCCESS; +} + +PHP_MSHUTDOWN_FUNCTION(zend_test) +{ + return SUCCESS; +} + +PHP_RINIT_FUNCTION(zend_test) +{ +#if defined(COMPILE_DL_ZEND_TEST) && defined(ZTS) + ZEND_TSRMLS_CACHE_UPDATE(); +#endif + return SUCCESS; +} + +PHP_RSHUTDOWN_FUNCTION(zend_test) +{ + return SUCCESS; +} + +PHP_MINFO_FUNCTION(zend_test) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "zend-test extension", "enabled"); + php_info_print_table_end(); +} + +const zend_function_entry zend_test_functions[] = { + ZEND_FE(zend_test_array_return, arginfo_zend_test_array_return) + ZEND_FE(zend_test_nullable_array_return, arginfo_zend_test_nullable_array_return) + ZEND_FE(zend_create_unterminated_string, NULL) + ZEND_FE(zend_terminate_string, arginfo_zend_terminate_string) + ZEND_FE(zend_leak_bytes, NULL) + ZEND_FE(zend_leak_variable, arginfo_zend_leak_variable) + ZEND_FE_END +}; + +zend_module_entry zend_test_module_entry = { + STANDARD_MODULE_HEADER, + "test", + zend_test_functions, + PHP_MINIT(zend_test), + PHP_MSHUTDOWN(zend_test), + PHP_RINIT(zend_test), + PHP_RSHUTDOWN(zend_test), + PHP_MINFO(zend_test), + PHP_ZEND_TEST_VERSION, + STANDARD_MODULE_PROPERTIES +}; + +#ifdef COMPILE_DL_ZEND_TEST +#ifdef ZTS +ZEND_TSRMLS_CACHE_DEFINE() +#endif +ZEND_GET_MODULE(test) +#endif + diff --git a/travis/compile.sh b/travis/compile.sh index 090cedae69..bd127e716d 100755 --- a/travis/compile.sh +++ b/travis/compile.sh @@ -58,6 +58,7 @@ $TS \ --with-freetype-dir=/usr \ --with-xpm-dir=/usr \ --with-kerberos \ ---enable-sysvmsg +--enable-sysvmsg \ +--enable-zend-test make -j2 --quiet make install |