diff --git a/Zend/tests/partial_application/attributes_004.phpt b/Zend/tests/partial_application/attributes_004.phpt new file mode 100644 index 000000000000..15e62b96df67 --- /dev/null +++ b/Zend/tests/partial_application/attributes_004.phpt @@ -0,0 +1,60 @@ +--TEST-- +PFA attribute UAF +--CREDITS-- +Ryan @ Calif.io +--FILE-- +getAttributes(NoDiscard::class)[0]->getArguments(); +} + +$original = new ReflectionFunction('userTarget'); +var_dump(arguments($original)); + +$partial = userTarget(?); +echo "partial-created\n"; +var_dump(arguments($original)); +var_dump(arguments(new ReflectionFunction($partial))); + +unset($partial); +gc_collect_cycles(); +echo "partial-destroyed\n"; +var_dump(arguments($original)); + +userTarget('discarded'); + +?> +--EXPECTF-- +array(1) { + [0]=> + string(266) "message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-%d" +} +partial-created +array(1) { + [0]=> + string(266) "message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-%d" +} +array(1) { + [0]=> + string(266) "message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-%d" +} +partial-destroyed +array(1) { + [0]=> + string(266) "message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-%d" +} + +Warning: The return value of function userTarget() should either be used or intentionally ignored by casting it as (void), message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-message-%d in %s on line %d diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 97cd2f895d3c..f6c0a1ad0e98 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -326,10 +326,11 @@ struct _zend_mm_chunk { zend_mm_heap *heap; zend_mm_chunk *next; zend_mm_chunk *prev; + zend_mm_chunk *next_shadow; /* shadow of "next" while the chunk is cached */ uint32_t free_pages; /* number of free pages */ uint32_t free_tail; /* number of free pages at the end of chunk */ uint32_t num; - char reserve[64 - (sizeof(void*) * 3 + sizeof(uint32_t) * 3)]; + char reserve[64 - (sizeof(void*) * 4 + sizeof(uint32_t) * 3)]; zend_mm_heap heap_slot; /* used only in main chunk */ zend_mm_page_map free_map; /* 512 bits or 64 bytes */ zend_mm_page_info map[ZEND_MM_PAGES]; /* 2 KB = 512 * 4 */ @@ -883,6 +884,64 @@ static zend_always_inline void zend_mm_chunk_init(zend_mm_heap *heap, zend_mm_ch chunk->map[0] = ZEND_MM_LRUN(ZEND_MM_FIRST_PAGE); } +/* Cached chunks are linked through their headers, which live in memory a heap + * overflow can reach, so the link is mirrored in an encoded shadow. The shadow + * is byte-swapped, so that small overwrites hit the most significant bytes of + * the address, XOR'ed with the heap key, and XOR'ed with its own address so + * that a valid (link, shadow) pair cannot be replayed into another chunk. */ +static zend_always_inline zend_mm_chunk *zend_mm_encode_cached_chunk(const zend_mm_heap *heap, const void *holder, const zend_mm_chunk *next) +{ +#ifdef WORDS_BIGENDIAN + return (zend_mm_chunk*)((uintptr_t)next ^ heap->shadow_key ^ (uintptr_t)holder); +#else + return (zend_mm_chunk*)(BSWAPPTR((uintptr_t)next) ^ heap->shadow_key ^ (uintptr_t)holder); +#endif +} + +static zend_always_inline zend_mm_chunk *zend_mm_decode_cached_chunk_key(uintptr_t key, const void *holder, const zend_mm_chunk *encoded) +{ +#ifdef WORDS_BIGENDIAN + zend_mm_chunk *next = (zend_mm_chunk*)((uintptr_t)encoded ^ key ^ (uintptr_t)holder); +#else + zend_mm_chunk *next = (zend_mm_chunk*)(BSWAPPTR((uintptr_t)encoded ^ key ^ (uintptr_t)holder)); +#endif + + ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(next, ZEND_MM_CHUNK_SIZE) == 0, "zend_mm_heap corrupted"); + return next; +} + +static zend_always_inline void zend_mm_set_next_cached_chunk(zend_mm_heap *heap, zend_mm_chunk *chunk, zend_mm_chunk *next) +{ + chunk->next = next; + chunk->next_shadow = zend_mm_encode_cached_chunk(heap, &chunk->next_shadow, next); +} + +static zend_always_inline zend_mm_chunk *zend_mm_get_next_cached_chunk_key(uintptr_t key, const zend_mm_chunk *chunk) +{ + zend_mm_chunk *next = zend_mm_decode_cached_chunk_key(key, &chunk->next_shadow, chunk->next_shadow); + + ZEND_MM_CHECK(chunk->next == next, "zend_mm_heap corrupted"); + return next; +} + +static zend_always_inline zend_mm_chunk *zend_mm_get_next_cached_chunk(const zend_mm_heap *heap, const zend_mm_chunk *chunk) +{ + return zend_mm_get_next_cached_chunk_key(heap->shadow_key, chunk); +} + +/* Re-encode the cached links after the heap key changed. */ +static zend_always_inline void zend_mm_rekey_cached_chunks(zend_mm_heap *heap, uintptr_t old_key) +{ + zend_mm_chunk *chunk = heap->cached_chunks; + + while (chunk != NULL) { + zend_mm_chunk *next = zend_mm_get_next_cached_chunk_key(old_key, chunk); + + zend_mm_set_next_cached_chunk(heap, chunk, next); + chunk = next; + } +} + /***********************/ /* Huge Runs (forward) */ /***********************/ @@ -1031,7 +1090,9 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count ZEND_F if (heap->cached_chunks) { heap->cached_chunks_count--; chunk = heap->cached_chunks; - heap->cached_chunks = chunk->next; + /* The list head lives in the heap, which is as reachable as the chunk headers. */ + ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(chunk, ZEND_MM_CHUNK_SIZE) == 0, "zend_mm_heap corrupted"); + heap->cached_chunks = zend_mm_get_next_cached_chunk(heap, chunk); } else { #if ZEND_MM_LIMIT if (UNEXPECTED(ZEND_MM_CHUNK_SIZE > heap->limit - heap->real_size)) { @@ -1150,7 +1211,7 @@ static zend_always_inline void zend_mm_delete_chunk(zend_mm_heap *heap, zend_mm_ && heap->last_chunks_delete_count >= 4)) { /* delay deletion */ heap->cached_chunks_count++; - chunk->next = heap->cached_chunks; + zend_mm_set_next_cached_chunk(heap, chunk, heap->cached_chunks); heap->cached_chunks = chunk; } else { #if ZEND_MM_STAT || ZEND_MM_LIMIT @@ -1168,7 +1229,7 @@ static zend_always_inline void zend_mm_delete_chunk(zend_mm_heap *heap, zend_mm_ zend_mm_chunk_free(heap, chunk, ZEND_MM_CHUNK_SIZE); } else { //TODO: select the best chunk to delete??? - chunk->next = heap->cached_chunks->next; + zend_mm_set_next_cached_chunk(heap, chunk, zend_mm_get_next_cached_chunk(heap, heap->cached_chunks)); zend_mm_chunk_free(heap, heap->cached_chunks, ZEND_MM_CHUNK_SIZE); heap->cached_chunks = chunk; } @@ -1276,35 +1337,38 @@ static zend_always_inline int zend_mm_small_size_to_bin(size_t size) * before dereference by comparing them with a shadow. * * The shadow is a copy of the pointer, stored at the end of the slot. It is - * XOR'ed with a random key, and converted to big-endian so that smaller - * corruptions affect the most significant bytes, which has a high chance of - * resulting in an invalid address instead of pointing to an adjacent slot. + * XOR'ed with a random key and with its own address, and converted to + * big-endian so that smaller corruptions affect the most significant bytes, + * which has a high chance of resulting in an invalid address instead of + * pointing to an adjacent slot. Mixing in the holder address keeps the key from + * being stored verbatim when the encoded pointer is NULL, and prevents a valid + * shadow from being naïvely replayed into another slot. */ -#define ZEND_MM_FREE_SLOT_PTR_SHADOW(free_slot, bin_num) \ - *((zend_mm_free_slot**)((char*)(free_slot) + bin_data_size[(bin_num)] - sizeof(zend_mm_free_slot*))) +#define ZEND_MM_FREE_SLOT_PTR_SHADOW_ADDR(free_slot, bin_num) \ + ((zend_mm_free_slot**)((char*)(free_slot) + bin_data_size[(bin_num)] - sizeof(zend_mm_free_slot*))) -static zend_always_inline zend_mm_free_slot* zend_mm_encode_free_slot(const zend_mm_heap *heap, const zend_mm_free_slot *slot) +static zend_always_inline zend_mm_free_slot* zend_mm_encode_free_slot(const zend_mm_heap *heap, const void *holder, const zend_mm_free_slot *next) { #ifdef WORDS_BIGENDIAN - return (zend_mm_free_slot*)(((uintptr_t)slot) ^ heap->shadow_key); + return (zend_mm_free_slot*)((uintptr_t)next ^ heap->shadow_key ^ (uintptr_t)holder); #else - return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot) ^ heap->shadow_key); + return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)next) ^ heap->shadow_key ^ (uintptr_t)holder); #endif } -static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot_key(uintptr_t shadow_key, zend_mm_free_slot *slot) +static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot_key(uintptr_t shadow_key, const void *holder, zend_mm_free_slot *shadow) { #ifdef WORDS_BIGENDIAN - return (zend_mm_free_slot*)((uintptr_t)slot ^ shadow_key); + return (zend_mm_free_slot*)((uintptr_t)shadow ^ shadow_key ^ (uintptr_t)holder); #else - return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ shadow_key)); + return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)shadow ^ shadow_key ^ (uintptr_t)holder)); #endif } -static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot) +static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, const void *holder, zend_mm_free_slot *shadow) { - return zend_mm_decode_free_slot_key(heap->shadow_key, slot); + return zend_mm_decode_free_slot_key(heap->shadow_key, holder, shadow); } static zend_always_inline void zend_mm_set_next_free_slot(zend_mm_heap *heap, uint32_t bin_num, zend_mm_free_slot *slot, zend_mm_free_slot *next) @@ -1312,15 +1376,17 @@ static zend_always_inline void zend_mm_set_next_free_slot(zend_mm_heap *heap, ui ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE); slot->next_free_slot = next; - ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, bin_num) = zend_mm_encode_free_slot(heap, next); + + zend_mm_free_slot **shadow_addr = ZEND_MM_FREE_SLOT_PTR_SHADOW_ADDR(slot, bin_num); + *shadow_addr = zend_mm_encode_free_slot(heap, shadow_addr, next); } static zend_always_inline zend_mm_free_slot *zend_mm_get_next_free_slot(zend_mm_heap *heap, uint32_t bin_num, zend_mm_free_slot* slot) { zend_mm_free_slot *next = slot->next_free_slot; if (EXPECTED(next != NULL)) { - zend_mm_free_slot *shadow = ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, bin_num); - if (UNEXPECTED(next != zend_mm_decode_free_slot(heap, shadow))) { + zend_mm_free_slot **shadow_addr = ZEND_MM_FREE_SLOT_PTR_SHADOW_ADDR(slot, bin_num); + if (UNEXPECTED(next != zend_mm_decode_free_slot(heap, shadow_addr, *shadow_addr))) { zend_mm_panic("zend_mm_heap corrupted"); } } @@ -2054,8 +2120,8 @@ ZEND_API void zend_mm_refresh_key_child(zend_mm_heap *heap) } zend_mm_free_slot *next; while ((next = slot->next_free_slot)) { - zend_mm_free_slot *shadow = ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, i); - if (UNEXPECTED(next != zend_mm_decode_free_slot_key(old_key, shadow))) { + zend_mm_free_slot **shadow_addr = ZEND_MM_FREE_SLOT_PTR_SHADOW_ADDR(slot, i); + if (UNEXPECTED(next != zend_mm_decode_free_slot_key(old_key, shadow_addr, *shadow_addr))) { zend_mm_panic("zend_mm_heap corrupted"); } zend_mm_set_next_free_slot(heap, i, slot, next); @@ -2063,6 +2129,8 @@ ZEND_API void zend_mm_refresh_key_child(zend_mm_heap *heap) } } + zend_mm_rekey_cached_chunks(heap, old_key); + #if ZEND_DEBUG heap->pid = getpid(); #endif @@ -2516,7 +2584,7 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent) p = heap->main_chunk->next; while (p != heap->main_chunk) { zend_mm_chunk *q = p->next; - p->next = heap->cached_chunks; + zend_mm_set_next_cached_chunk(heap, p, heap->cached_chunks); heap->cached_chunks = p; p = q; heap->chunks_count--; @@ -2527,7 +2595,7 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent) /* free all cached chunks */ while (heap->cached_chunks) { p = heap->cached_chunks; - heap->cached_chunks = p->next; + heap->cached_chunks = zend_mm_get_next_cached_chunk(heap, p); zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE); } /* free the first chunk */ @@ -2538,16 +2606,16 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent) while ((double)heap->cached_chunks_count + 0.9 > heap->avg_chunks_count && heap->cached_chunks) { p = heap->cached_chunks; - heap->cached_chunks = p->next; + heap->cached_chunks = zend_mm_get_next_cached_chunk(heap, p); zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE); heap->cached_chunks_count--; } /* clear cached chunks */ p = heap->cached_chunks; while (p != NULL) { - zend_mm_chunk *q = p->next; + zend_mm_chunk *q = zend_mm_get_next_cached_chunk(heap, p); memset(p, 0, sizeof(zend_mm_chunk)); - p->next = q; + zend_mm_set_next_cached_chunk(heap, p, q); p = q; } @@ -2584,7 +2652,12 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent) && "heap was re-used without calling zend_mm_refresh_key_child() after a fork"); #endif + uintptr_t old_key = heap->shadow_key; + zend_mm_refresh_key(heap); + + /* Cached chunks outlive the request, so re-encode their links */ + zend_mm_rekey_cached_chunks(heap, old_key); } } @@ -2931,7 +3004,7 @@ ZEND_API zend_result zend_set_memory_limit(size_t memory_limit) /* free some cached chunks to fit into new memory limit */ do { zend_mm_chunk *p = heap->cached_chunks; - heap->cached_chunks = p->next; + heap->cached_chunks = zend_mm_get_next_cached_chunk(heap, p); zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE); heap->cached_chunks_count--; heap->real_size -= ZEND_MM_CHUNK_SIZE; diff --git a/Zend/zend_partial.c b/Zend/zend_partial.c index de243bd7e65f..a4cc4a4ce571 100644 --- a/Zend/zend_partial.c +++ b/Zend/zend_partial.c @@ -472,7 +472,9 @@ static zend_ast *zp_attribute_to_ast(zend_attribute *attribute) if (attribute->argc) { args_ast = zend_ast_create_arg_list(0, ZEND_AST_ARG_LIST); for (uint32_t i = 0; i < attribute->argc; i++) { - zend_ast *arg_ast = zend_ast_create_zval(&attribute->args[i].value); + zval *zv = &attribute->args[i].value; + Z_TRY_ADDREF_P(zv); + zend_ast *arg_ast = zend_ast_create_zval(zv); if (attribute->args[i].name) { arg_ast = zend_ast_create(ZEND_AST_NAMED_ARG, zend_ast_create_zval_from_str( @@ -561,6 +563,7 @@ static zend_ast *zp_compile_forwarding_call( args_ast = zend_ast_list_add(args_ast, default_value_ast); } else if (zp_is_const_arg(const_args, offset)) { ZEND_ASSERT(Z_TYPE(argv[offset]) < IS_OBJECT); + ZEND_ASSERT(!Z_REFCOUNTED(argv[offset])); /* This argument never changes, so we can burn it into the op_array * and check its type ahead of time. */ diff --git a/ext/opcache/shared_alloc_mmap.c b/ext/opcache/shared_alloc_mmap.c index a805912d0d75..4825da3e4c01 100644 --- a/ext/opcache/shared_alloc_mmap.c +++ b/ext/opcache/shared_alloc_mmap.c @@ -243,9 +243,9 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ /* to got HUGE PAGES in low 32-bit address we have to reserve address space and then remap it using MAP_HUGETLB */ - p = mmap(NULL, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_32BIT, fd, 0); + p = mmap(NULL, requested_size + huge_page_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_32BIT, fd, 0); if (p != MAP_FAILED) { - munmap(p, requested_size); + munmap(p, requested_size + huge_page_size); p = (void*)(ZEND_MM_ALIGNED_SIZE_EX((ptrdiff_t)p, huge_page_size)); p = mmap(p, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_32BIT|MAP_HUGETLB|MAP_FIXED, -1, 0); if (p != MAP_FAILED) { diff --git a/ext/openssl/tests/ServerClientTestCase.inc b/ext/openssl/tests/ServerClientTestCase.inc index b7e866954fcf..0c3c49db7259 100644 --- a/ext/openssl/tests/ServerClientTestCase.inc +++ b/ext/openssl/tests/ServerClientTestCase.inc @@ -24,7 +24,7 @@ function phpt_has_sslv3() { if (!is_null($result)) { return $result; } - $server = @stream_socket_server('sslv3://127.0.0.1:10013'); + $server = @stream_socket_server('sslv3://127.0.0.1:0'); if ($result = !!$server) { fclose($server); } diff --git a/ext/openssl/tests/gh20802.phpt b/ext/openssl/tests/gh20802.phpt index 786679c41c6a..e078f461fc44 100644 --- a/ext/openssl/tests/gh20802.phpt +++ b/ext/openssl/tests/gh20802.phpt @@ -26,7 +26,7 @@ $serverCode = <<<'CODE' ] ] ]); - $server = stream_socket_server('tls://127.0.0.1:12443', $errno, $errstr, $flags, $ctx); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); phpt_notify_server_start($server); stream_socket_accept($server, 3); CODE; @@ -42,7 +42,7 @@ $ctx = stream_context_create([ 'verify_peer' => false ] ]); - @stream_socket_client("tls://127.0.0.1:12443", $errno, $errstr, 1, $flags, $ctx); + @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 1, $flags, $ctx); CODE; include 'CertificateGenerator.inc'; diff --git a/ext/openssl/tests/openssl_error_string_basic_openssl3.phpt b/ext/openssl/tests/openssl_error_string_basic_openssl3.phpt index 093681cb2e10..d36fcac194e0 100644 --- a/ext/openssl/tests/openssl_error_string_basic_openssl3.phpt +++ b/ext/openssl/tests/openssl_error_string_basic_openssl3.phpt @@ -53,7 +53,7 @@ function dump_openssl_errors($name) { } // common output file -$output_file = __DIR__ . "/openssl_error_string_basic_output.tmp"; +$output_file = __DIR__ . "/openssl_error_string_basic_openssl3_output.tmp"; // invalid file for read is something that does not exist in current directory $invalid_file_for_read = __DIR__ . "/invalid_file_for_read_operation.txt"; // invalid file for is the test dir as writing file to existing dir should always fail @@ -156,7 +156,7 @@ expect_openssl_errors('openssl_csr_get_subjec pem', [$err_pem_no_start_line]); ?> --CLEAN-- --CLEAN-- --CLEAN-- --FILE-- run($clientCode, $serverCode); ?> --CLEAN-- --EXPECTF-- string(%d) "-----BEGIN SSL SESSION PARAMETERS----- diff --git a/ext/openssl/tests/session_resumption_invalid_session_import.phpt b/ext/openssl/tests/session_resumption_invalid_session_import.phpt index a9c5b65f2051..efd49e7c693b 100644 --- a/ext/openssl/tests/session_resumption_invalid_session_import.phpt +++ b/ext/openssl/tests/session_resumption_invalid_session_import.phpt @@ -15,9 +15,5 @@ try { echo $e->getMessage() . "\n"; } ?> ---CLEAN-- - --EXPECT-- Failed to import session data diff --git a/ext/openssl/tests/session_resumption_serialize_session.phpt b/ext/openssl/tests/session_resumption_serialize_session.phpt index f2f3c98e5e5b..ca43c46c3901 100644 --- a/ext/openssl/tests/session_resumption_serialize_session.phpt +++ b/ext/openssl/tests/session_resumption_serialize_session.phpt @@ -8,7 +8,7 @@ if (!function_exists("proc_open")) die("skip no proc_open"); ?> --FILE-- run($clientCode, $serverCode); ?> --CLEAN-- --EXPECTF-- string(%d) "O:15:"Openssl\Session":1:{s:3:"pem";s:%d:"-----BEGIN SSL SESSION PARAMETERS----- diff --git a/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt b/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt index 02c6a7dcfdc7..f8aa9ce33050 100644 --- a/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt +++ b/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt @@ -8,7 +8,7 @@ if (!function_exists("proc_open")) die("skip no proc_open"); ?> --FILE-- run($clientCode, $serverCode); ?> --CLEAN-- --EXPECTF-- Client first connection resumed: no diff --git a/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt b/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt index bdc3d2ce1bf6..7b4d8bfa5a99 100644 --- a/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt +++ b/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt @@ -8,7 +8,7 @@ if (!function_exists("proc_open")) die("skip no proc_open"); ?> --FILE-- run($clientCode, $serverCode); ?> --CLEAN-- --EXPECTF-- Client first connection resumed: no diff --git a/ext/openssl/tests/stream_server_reneg_limit.phpt b/ext/openssl/tests/stream_server_reneg_limit.phpt index d84906c81ca7..b8e7c1726734 100644 --- a/ext/openssl/tests/stream_server_reneg_limit.phpt +++ b/ext/openssl/tests/stream_server_reneg_limit.phpt @@ -25,7 +25,7 @@ $certFile = __DIR__ . DIRECTORY_SEPARATOR . 'stream_server_reneg_limit.pem.tmp'; $serverCode = <<<'CODE' $printed = false; - $serverUri = "ssl://127.0.0.1:64321"; + $serverUri = "ssl://127.0.0.1:0"; $serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN; $serverCtx = stream_context_create(['ssl' => [ 'local_cert' => '%s', @@ -42,7 +42,7 @@ $serverCode = <<<'CODE' ]]); $server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx); - phpt_notify(); + phpt_notify(message: stream_socket_get_name($server, false)); $clients = []; while (1) { @@ -71,9 +71,9 @@ CODE; $serverCode = sprintf($serverCode, $certFile); $clientCode = <<<'CODE' - phpt_wait(); + $serverUri = trim(phpt_wait()); - $cmd = 'openssl s_client -connect 127.0.0.1:64321'; + $cmd = 'openssl s_client -connect ' . escapeshellarg($serverUri); $descriptorSpec = [["pipe", "r"], ["pipe", "w"], ["pipe", "w"]]; $process = proc_open($cmd, $descriptorSpec, $pipes); diff --git a/ext/uri/tests/003.phpt b/ext/uri/tests/003.phpt deleted file mode 100644 index 38d62b0ec8e6..000000000000 --- a/ext/uri/tests/003.phpt +++ /dev/null @@ -1,89 +0,0 @@ ---TEST-- -Parse special URIs ---FILE-- - ---EXPECTF-- -NULL -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(4) "http" - ["username"]=> - string(8) "username" - ["password"]=> - string(8) "password" - ["host"]=> - string(18) "xn--hostname-b1aaa" - ["port"]=> - int(9090) - ["path"]=> - string(5) "/path" - ["query"]=> - string(14) "arg=va%C3%A9ue" - ["fragment"]=> - string(6) "anchor" -} -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - NULL - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(7) "host123" - ["port"]=> - NULL - ["path"]=> - string(1) "/" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - NULL - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(0) "" - ["port"]=> - NULL - ["path"]=> - string(5) "/foo/" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - NULL - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - NULL - ["port"]=> - NULL - ["path"]=> - string(7) "/page:1" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -NULL diff --git a/ext/uri/tests/004.phpt b/ext/uri/tests/004.phpt deleted file mode 100644 index c6ad96ce99a7..000000000000 --- a/ext/uri/tests/004.phpt +++ /dev/null @@ -1,83 +0,0 @@ ---TEST-- -Parse invalid URLs ---FILE-- -getMessage(), "\n"; -} - -var_dump(Uri\WhatWg\Url::parse("")); - -var_dump(Uri\Rfc3986\Uri::parse("192.168/contact.html")); -var_dump(Uri\WhatWg\Url::parse("192.168/contact.html", null)); - -var_dump(Uri\Rfc3986\Uri::parse("http://RuPaul's Drag Race All Stars 7 Winners Cast on This Season's")); -var_dump(Uri\WhatWg\Url::parse("http://RuPaul's Drag Race All Stars 7 Winners Cast on This Season's", null)); - -?> ---EXPECTF-- -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - NULL - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - NULL - ["port"]=> - NULL - ["path"]=> - string(0) "" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - NULL - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - NULL - ["port"]=> - NULL - ["path"]=> - string(0) "" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -Uri\WhatWg\InvalidUrlException: The specified URI is malformed (MissingSchemeNonRelativeUrl) -NULL -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - NULL - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - NULL - ["port"]=> - NULL - ["path"]=> - string(20) "192.168/contact.html" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -NULL -NULL -NULL diff --git a/ext/uri/tests/006.phpt b/ext/uri/tests/006.phpt deleted file mode 100644 index e7fa79a8b837..000000000000 --- a/ext/uri/tests/006.phpt +++ /dev/null @@ -1,49 +0,0 @@ ---TEST-- -Test successful manual Uri child instance creation ---FILE-- - ---EXPECTF-- -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - string(5) "https" - ["username"]=> - string(8) "username" - ["password"]=> - string(8) "password" - ["host"]=> - string(11) "example.com" - ["port"]=> - int(8080) - ["path"]=> - string(5) "/path" - ["query"]=> - string(3) "q=r" - ["fragment"]=> - string(8) "fragment" -} -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(5) "https" - ["username"]=> - string(8) "username" - ["password"]=> - string(8) "password" - ["host"]=> - string(11) "example.com" - ["port"]=> - int(8080) - ["path"]=> - string(5) "/path" - ["query"]=> - string(3) "q=r" - ["fragment"]=> - string(8) "fragment" -} diff --git a/ext/uri/tests/007.phpt b/ext/uri/tests/007.phpt deleted file mode 100644 index 9d2f389e2513..000000000000 --- a/ext/uri/tests/007.phpt +++ /dev/null @@ -1,68 +0,0 @@ ---TEST-- -Test URI creation errors ---FILE-- -getMessage(), "\n"; -} - -try { - new Uri\WhatWg\Url("https://example.com:8080@username:password/path?q=r#fragment"); -} catch (Throwable $e) { - echo $e::class, ': ', $e->getMessage(), "\n"; - var_dump($e->errors); -} - -$failures = []; -$url = new Uri\WhatWg\Url(" https://example.org ", null, $failures); -var_dump($url->toAsciiString()); -var_dump($failures); - -?> ---EXPECTF-- -Uri\InvalidUriException: The specified URI is malformed -Uri\WhatWg\InvalidUrlException: The specified URI is malformed (PortInvalid) -array(%d) { - [0]=> - object(Uri\WhatWg\UrlValidationError)#%d (%d) { - ["context"]=> - string(26) "password/path?q=r#fragment" - ["type"]=> - enum(Uri\WhatWg\UrlValidationErrorType::PortInvalid) - ["failure"]=> - bool(true) - } - [1]=> - object(Uri\WhatWg\UrlValidationError)#%d (%d) { - ["context"]=> - string(36) "@username:password/path?q=r#fragment" - ["type"]=> - enum(Uri\WhatWg\UrlValidationErrorType::InvalidCredentials) - ["failure"]=> - bool(false) - } -} -string(20) "https://example.org/" -array(2) { - [0]=> - object(Uri\WhatWg\UrlValidationError)#%d (%d) { - ["context"]=> - string(1) " " - ["type"]=> - enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit) - ["failure"]=> - bool(false) - } - [1]=> - object(Uri\WhatWg\UrlValidationError)#%d (%d) { - ["context"]=> - string(21) " https://example.org " - ["type"]=> - enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit) - ["failure"]=> - bool(false) - } -} diff --git a/ext/uri/tests/008.phpt b/ext/uri/tests/008.phpt deleted file mode 100644 index 0a02bae63163..000000000000 --- a/ext/uri/tests/008.phpt +++ /dev/null @@ -1,76 +0,0 @@ ---TEST-- -Test Uri getters ---FILE-- -getScheme()); - var_dump($uri->getRawScheme()); - var_dump($uri->getUsername()); - var_dump($uri->getRawUsername()); - var_dump($uri->getPassword()); - var_dump($uri->getRawPassword()); - var_dump($uri->getUserInfo()); - var_dump($uri->getRawUserInfo()); - var_dump($uri->getHost()); - var_dump($uri->getRawHost()); - var_dump($uri->getPort()); - var_dump($uri->getPath()); - var_dump($uri->getRawPath()); - var_dump($uri->getQuery()); - var_dump($uri->getRawQuery()); - var_dump($uri->getFragment()); - var_dump($uri->getRawFragment()); -} - -function callWhatWgGetters($url) -{ - var_dump($url->getScheme()); - var_dump($url->getUsername()); - var_dump($url->getPassword()); - var_dump($url->getAsciiHost()); - var_dump($url->getUnicodeHost()); - var_dump($url->getPort()); - var_dump($url->getPath()); - var_dump($url->getQuery()); - var_dump($url->getFragment()); -} - -$uri = Uri\Rfc3986\Uri::parse("https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); -callRfc3986Getters($uri); - -echo "\n"; - -$url = Uri\WhatWg\Url::parse("https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); -callWhatWgGetters($url); - -?> ---EXPECT-- -string(5) "https" -string(5) "https" -string(8) "username" -string(8) "username" -string(8) "password" -string(8) "password" -string(17) "username:password" -string(17) "username:password" -string(15) "www.example.com" -string(15) "www.example.com" -int(8080) -string(30) "/pathname1/pathname2/pathname3" -string(30) "/pathname1/pathname2/pathname3" -string(10) "query=true" -string(10) "query=true" -string(11) "hash-exists" -string(11) "hash-exists" - -string(5) "https" -string(8) "username" -string(8) "password" -string(15) "www.example.com" -string(15) "www.example.com" -int(8080) -string(30) "/pathname1/pathname2/pathname3" -string(10) "query=true" -string(11) "hash-exists" diff --git a/ext/uri/tests/009.phpt b/ext/uri/tests/009.phpt deleted file mode 100644 index 9c896d0153b2..000000000000 --- a/ext/uri/tests/009.phpt +++ /dev/null @@ -1,46 +0,0 @@ ---TEST-- -Test parsing with IANA schemes ---FILE-- - ---EXPECTF-- -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - string(16) "chrome-extension" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(11) "example.com" - ["port"]=> - NULL - ["path"]=> - string(0) "" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(16) "chrome-extension" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(11) "example.com" - ["port"]=> - NULL - ["path"]=> - string(0) "" - ["query"]=> - NULL - ["fragment"]=> - NULL -} diff --git a/ext/uri/tests/010.phpt b/ext/uri/tests/010.phpt deleted file mode 100644 index ff5a37000775..000000000000 --- a/ext/uri/tests/010.phpt +++ /dev/null @@ -1,84 +0,0 @@ ---TEST-- -Test parsing URIs when a base URI is present ---FILE-- - ---EXPECTF-- -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - string(4) "http" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(11) "example.com" - ["port"]=> - NULL - ["path"]=> - string(14) "/path/to/file2" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - string(5) "https" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(8) "test.com" - ["port"]=> - NULL - ["path"]=> - string(14) "/path/to/file2" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(4) "http" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(11) "example.com" - ["port"]=> - NULL - ["path"]=> - string(14) "/path/to/file1" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(5) "https" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(8) "test.com" - ["port"]=> - NULL - ["path"]=> - string(14) "/path/to/file1" - ["query"]=> - NULL - ["fragment"]=> - NULL -} diff --git a/ext/uri/tests/011.phpt b/ext/uri/tests/011.phpt deleted file mode 100644 index 0e8fd8ec8f48..000000000000 --- a/ext/uri/tests/011.phpt +++ /dev/null @@ -1,31 +0,0 @@ ---TEST-- -Test encoding and normalization ---FILE-- -toRawString()); -var_dump(Uri\Rfc3986\Uri::parse("https://www.example.com/dir1/../dir2")->toRawString()); -var_dump(Uri\Rfc3986\Uri::parse("https://你好你好")); -var_dump(Uri\Rfc3986\Uri::parse("https://0Xc0.0250.01")); -var_dump(Uri\Rfc3986\Uri::parse("HttPs://0300.0250.0000.0001/path?query=foo%20bar")->toRawString()); - -var_dump(Uri\WhatWg\Url::parse("http://////www.EXAMPLE.com:80")->toAsciiString()); -var_dump(Uri\WhatWg\Url::parse("https://www.example.com:443/dir1/../dir2")->toAsciiString()); -var_dump(Uri\WhatWg\Url::parse("https://你好你好")->toAsciiString()); -var_dump(Uri\WhatWg\Url::parse("https://你好你好")->toUnicodeString()); -var_dump(Uri\WhatWg\Url::parse("https://0Xc0.0250.01")->toAsciiString()); -var_dump(Uri\WhatWg\Url::parse("HttPs://0300.0250.0000.0001/path?query=foo%20bar")->toAsciiString()); - -?> ---EXPECT-- -string(29) "http://////www.EXAMPLE.com:80" -string(36) "https://www.example.com/dir1/../dir2" -NULL -NULL -string(48) "HttPs://0300.0250.0000.0001/path?query=foo%20bar" -string(23) "http://www.example.com/" -string(28) "https://www.example.com/dir2" -string(23) "https://xn--6qqa088eba/" -string(21) "https://你好你好/" -string(20) "https://192.168.0.1/" -string(40) "https://192.168.0.1/path?query=foo%20bar" diff --git a/ext/uri/tests/012.phpt b/ext/uri/tests/012.phpt deleted file mode 100644 index e033223a6426..000000000000 --- a/ext/uri/tests/012.phpt +++ /dev/null @@ -1,85 +0,0 @@ ---TEST-- -Test parsing of various schemes ---FILE-- - ---EXPECTF-- -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - string(6) "mailto" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - NULL - ["port"]=> - NULL - ["path"]=> - string(15) "Joe@Example.COM" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(6) "mailto" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - NULL - ["port"]=> - NULL - ["path"]=> - string(15) "Joe@Example.COM" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\Rfc3986\Uri)#%d (%d) { - ["scheme"]=> - string(4) "file" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(0) "" - ["port"]=> - NULL - ["path"]=> - string(30) "/E:/Documents%20and%20Settings" - ["query"]=> - NULL - ["fragment"]=> - NULL -} -object(Uri\WhatWg\Url)#%d (%d) { - ["scheme"]=> - string(4) "file" - ["username"]=> - NULL - ["password"]=> - NULL - ["host"]=> - string(0) "" - ["port"]=> - NULL - ["path"]=> - string(30) "/E:/Documents%20and%20Settings" - ["query"]=> - NULL - ["fragment"]=> - NULL -} diff --git a/ext/uri/tests/013.phpt b/ext/uri/tests/013.phpt deleted file mode 100644 index 865843ec27e8..000000000000 --- a/ext/uri/tests/013.phpt +++ /dev/null @@ -1,129 +0,0 @@ ---TEST-- -Test parsing of query strings ---FILE-- - + @")); - -var_dump(Uri\WhatWg\Url::parse("http://example.com?foobar=%27%3Cscript%3E+%2B+%40")); -var_dump(Uri\WhatWg\Url::parse("http://example.com?foobar='