summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard')
-rw-r--r--ext/standard/basic_functions.c4
-rw-r--r--ext/standard/basic_functions.h4
-rw-r--r--ext/standard/image.c6
-rw-r--r--ext/standard/pack.c154
-rw-r--r--ext/standard/tests/file/bug52820.phpt134
-rw-r--r--ext/standard/tests/streams/proc_open_bug51800.phpt95
-rw-r--r--ext/standard/tests/streams/proc_open_bug51800_right.phpt78
-rw-r--r--ext/standard/tests/streams/proc_open_bug51800_right2.phpt84
-rw-r--r--ext/standard/tests/streams/proc_open_bug60120.phpt71
-rw-r--r--ext/standard/tests/streams/proc_open_bug64438.phpt70
-rw-r--r--ext/standard/tests/strings/pack64.phpt115
-rw-r--r--ext/standard/tests/strings/pack64_32.phpt44
-rw-r--r--ext/standard/tests/strings/setlocale_variation2.phpt7
-rw-r--r--ext/standard/tests/strings/url_t.phpt212
-rw-r--r--ext/standard/tests/url/parse_url_basic_001.phpt8
-rw-r--r--ext/standard/tests/url/parse_url_basic_005.phpt2
-rw-r--r--ext/standard/tests/url/parse_url_basic_006.phpt2
-rw-r--r--ext/standard/url.c12
18 files changed, 940 insertions, 162 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index ca14b28cc..c5392760e 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -5051,7 +5051,7 @@ static int user_tick_function_compare(user_tick_function_entry * tick_fe1, user_
}
/* }}} */
-void php_call_shutdown_functions(TSRMLS_D) /* {{{ */
+PHPAPI void php_call_shutdown_functions(TSRMLS_D) /* {{{ */
{
if (BG(user_shutdown_function_names)) {
zend_try {
@@ -5063,7 +5063,7 @@ void php_call_shutdown_functions(TSRMLS_D) /* {{{ */
}
/* }}} */
-void php_free_shutdown_functions(TSRMLS_D) /* {{{ */
+PHPAPI void php_free_shutdown_functions(TSRMLS_D) /* {{{ */
{
if (BG(user_shutdown_function_names))
zend_try {
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index 3af85b3d4..eaeb9bca8 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -261,4 +261,8 @@ PHPAPI extern zend_bool register_user_shutdown_function(char *function_name, siz
PHPAPI extern zend_bool remove_user_shutdown_function(char *function_name, size_t function_len TSRMLS_DC);
PHPAPI extern zend_bool append_user_shutdown_function(php_shutdown_function_entry shutdown_function_entry TSRMLS_DC);
+PHPAPI void php_call_shutdown_functions(TSRMLS_D);
+PHPAPI void php_free_shutdown_functions(TSRMLS_D);
+
+
#endif /* BASIC_FUNCTIONS_H */
diff --git a/ext/standard/image.c b/ext/standard/image.c
index 02246c626..f1910d219 100644
--- a/ext/standard/image.c
+++ b/ext/standard/image.c
@@ -365,8 +365,8 @@ static unsigned short php_read2(php_stream * stream TSRMLS_DC)
{
unsigned char a[2];
- /* just return 0 if we hit the end-of-file */
- if((php_stream_read(stream, a, sizeof(a))) <= 0) return 0;
+ /* return 0 if we couldn't read enough data */
+ if((php_stream_read(stream, a, sizeof(a))) < sizeof(a)) return 0;
return (((unsigned short)a[0]) << 8) + ((unsigned short)a[1]);
}
@@ -646,7 +646,7 @@ static struct gfxinfo *php_handle_jpc(php_stream * stream TSRMLS_DC)
#endif
result->channels = php_read2(stream TSRMLS_CC); /* Csiz */
- if (result->channels < 0 || result->channels > 256) {
+ if (result->channels == 0 && php_stream_eof(stream) || result->channels > 256) {
efree(result);
return NULL;
}
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index 16a30668d..9427db90a 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -82,6 +82,13 @@ static int machine_endian_long_map[4];
static int big_endian_long_map[4];
static int little_endian_long_map[4];
+#if SIZEOF_LONG > 4
+/* Mappings of bytes from quads (64bit) for all endian environments */
+static int machine_endian_longlong_map[8];
+static int big_endian_longlong_map[8];
+static int little_endian_longlong_map[8];
+#endif
+
/* {{{ php_pack
*/
static void php_pack(zval **val, int size, int *map, char *output)
@@ -98,8 +105,8 @@ static void php_pack(zval **val, int size, int *map, char *output)
}
/* }}} */
-/* pack() idea stolen from Perl (implemented formats behave the same as there)
- * Implemented formats are Z, A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @.
+/* pack() idea stolen from Perl (implemented formats behave the same as there except J and P)
+ * Implemented formats are Z, A, a, h, H, c, C, s, S, i, I, l, L, n, N, q, Q, J, P, f, d, x, X, @.
*/
/* {{{ proto string pack(string format, mixed arg1 [, mixed arg2 [, mixed ...]])
Takes one or more arguments and packs them into a binary string according to the format argument */
@@ -199,6 +206,17 @@ PHP_FUNCTION(pack)
break;
/* Use as many args as specified */
+ case 'q':
+ case 'Q':
+ case 'J':
+ case 'P':
+#if SIZEOF_LONG < 8
+ efree(argv);
+ efree(formatcodes);
+ efree(formatargs);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "64-bit format codes are not available for 32-bit versions of PHP");
+ RETURN_FALSE;
+#endif
case 'c':
case 'C':
case 's':
@@ -283,6 +301,15 @@ PHP_FUNCTION(pack)
INC_OUTPUTPOS(arg,4) /* 32 bit per arg */
break;
+#if SIZEOF_LONG > 4
+ case 'q':
+ case 'Q':
+ case 'J':
+ case 'P':
+ INC_OUTPUTPOS(arg,8) /* 32 bit per arg */
+ break;
+#endif
+
case 'f':
INC_OUTPUTPOS(arg,sizeof(float))
break;
@@ -437,6 +464,27 @@ PHP_FUNCTION(pack)
break;
}
+#if SIZEOF_LONG > 4
+ case 'q':
+ case 'Q':
+ case 'J':
+ case 'P': {
+ int *map = machine_endian_longlong_map;
+
+ if (code == 'J') {
+ map = big_endian_longlong_map;
+ } else if (code == 'P') {
+ map = little_endian_longlong_map;
+ }
+
+ while (arg-- > 0) {
+ php_pack(argv[currentarg++], 8, map, &output[outputpos]);
+ outputpos += 8;
+ }
+ break;
+ }
+#endif
+
case 'f': {
float v;
@@ -522,7 +570,7 @@ static long php_unpack(char *data, int size, int issigned, int *map)
* chars1, chars2, and ints.
* Numeric pack types will return numbers, a and A will return strings,
* f and d will return doubles.
- * Implemented formats are Z, A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @.
+ * Implemented formats are Z, A, a, h, H, c, C, s, S, i, I, l, L, n, N, q, Q, J, P, f, d, x, X, @.
*/
/* {{{ proto array unpack(string format, string input)
Unpack binary string into named array elements according to format argument */
@@ -637,6 +685,20 @@ PHP_FUNCTION(unpack)
size = 4;
break;
+ /* Use 8 bytes of input */
+ case 'q':
+ case 'Q':
+ case 'J':
+ case 'P':
+#if SIZEOF_LONG > 4
+ size = 8;
+ break;
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "64-bit format codes are not available for 32-bit versions of PHP");
+ zval_dtor(return_value);
+ RETURN_FALSE;
+#endif
+
/* Use sizeof(float) bytes of input */
case 'f':
size = sizeof(float);
@@ -860,6 +922,38 @@ PHP_FUNCTION(unpack)
break;
}
+#if SIZEOF_LONG > 4
+ case 'q':
+ case 'Q':
+ case 'J':
+ case 'P': {
+ int issigned = 0;
+ int *map = machine_endian_longlong_map;
+ long v = 0;
+
+ if (type == 'q' || type == 'Q') {
+ issigned = input[inputpos + (machine_little_endian ? 7 : 0)] & 0x80;
+ } else if (type == 'J') {
+ issigned = input[inputpos] & 0x80;
+ map = big_endian_longlong_map;
+ } else if (type == 'P') {
+ issigned = input[inputpos + 7] & 0x80;
+ map = little_endian_longlong_map;
+ }
+
+ v = php_unpack(&input[inputpos], 8, issigned, map);
+
+ if (type == 'q') {
+ v = (signed long int) v;
+ } else {
+ v = (unsigned long int) v;
+ }
+
+ add_assoc_long(return_value, n, v);
+ break;
+ }
+#endif
+
case 'f': {
float v;
@@ -961,6 +1055,33 @@ PHP_MINIT_FUNCTION(pack)
little_endian_long_map[1] = 1;
little_endian_long_map[2] = 2;
little_endian_long_map[3] = 3;
+
+#if SIZEOF_LONG > 4
+ machine_endian_longlong_map[0] = 0;
+ machine_endian_longlong_map[1] = 1;
+ machine_endian_longlong_map[2] = 2;
+ machine_endian_longlong_map[3] = 3;
+ machine_endian_longlong_map[4] = 4;
+ machine_endian_longlong_map[5] = 5;
+ machine_endian_longlong_map[6] = 6;
+ machine_endian_longlong_map[7] = 7;
+ big_endian_longlong_map[0] = 7;
+ big_endian_longlong_map[1] = 6;
+ big_endian_longlong_map[2] = 5;
+ big_endian_longlong_map[3] = 4;
+ big_endian_longlong_map[4] = 3;
+ big_endian_longlong_map[5] = 2;
+ big_endian_longlong_map[6] = 1;
+ big_endian_longlong_map[7] = 0;
+ little_endian_longlong_map[0] = 0;
+ little_endian_longlong_map[1] = 1;
+ little_endian_longlong_map[2] = 2;
+ little_endian_longlong_map[3] = 3;
+ little_endian_longlong_map[4] = 4;
+ little_endian_longlong_map[5] = 5;
+ little_endian_longlong_map[6] = 6;
+ little_endian_longlong_map[7] = 7;
+#endif
}
else {
zval val;
@@ -993,6 +1114,33 @@ PHP_MINIT_FUNCTION(pack)
little_endian_long_map[1] = size - 2;
little_endian_long_map[2] = size - 3;
little_endian_long_map[3] = size - 4;
+
+#if SIZEOF_LONG > 4
+ machine_endian_longlong_map[0] = size - 8;
+ machine_endian_longlong_map[1] = size - 7;
+ machine_endian_longlong_map[2] = size - 6;
+ machine_endian_longlong_map[3] = size - 5;
+ machine_endian_longlong_map[0] = size - 4;
+ machine_endian_longlong_map[1] = size - 3;
+ machine_endian_longlong_map[2] = size - 2;
+ machine_endian_longlong_map[3] = size - 1;
+ big_endian_longlong_map[0] = size - 8;
+ big_endian_longlong_map[1] = size - 7;
+ big_endian_longlong_map[2] = size - 6;
+ big_endian_longlong_map[3] = size - 5;
+ big_endian_longlong_map[0] = size - 4;
+ big_endian_longlong_map[1] = size - 3;
+ big_endian_longlong_map[2] = size - 2;
+ big_endian_longlong_map[3] = size - 1;
+ little_endian_longlong_map[0] = size - 1;
+ little_endian_longlong_map[1] = size - 2;
+ little_endian_longlong_map[2] = size - 3;
+ little_endian_longlong_map[3] = size - 4;
+ little_endian_longlong_map[0] = size - 5;
+ little_endian_longlong_map[1] = size - 6;
+ little_endian_longlong_map[2] = size - 7;
+ little_endian_longlong_map[3] = size - 8;
+#endif
}
return SUCCESS;
diff --git a/ext/standard/tests/file/bug52820.phpt b/ext/standard/tests/file/bug52820.phpt
index 3a9f9c31a..a00ebf50b 100644
--- a/ext/standard/tests/file/bug52820.phpt
+++ b/ext/standard/tests/file/bug52820.phpt
@@ -1,71 +1,63 @@
---TEST--
-Bug #52820 (writes to fopencookie FILE* not committed when seeking the stream)
---SKIPIF--
-<?php
-if (!function_exists('leak_variable'))
- die("skip only for debug builds");
-/* unfortunately no standard function does a cast to FILE*, so we need
- * curl to test this */
-if (!extension_loaded("curl")) exit("skip curl extension not loaded");
-$handle=curl_init('http://127.0.0.1:37349/');
-curl_setopt($handle, CURLOPT_VERBOSE, true);
-curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
-if (!curl_setopt($handle, CURLOPT_STDERR, fopen("php://memory", "w+")))
- die("skip fopencookie not supported on this platform");
---FILE--
-<?php
-function do_stuff($url) {
- $handle=curl_init('http://127.0.0.1:37349/');
- curl_setopt($handle, CURLOPT_VERBOSE, true);
- curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($handle, CURLOPT_STDERR, $o = fopen($url, "w+"));
- curl_exec($handle);
- echo "About to rewind!\n";
- rewind($o);
- echo stream_get_contents($o);
- return $o;
-}
-
-echo "temp stream (close after):\n";
-fclose(do_stuff("php://temp"));
-
-echo "\nmemory stream (close after):\n";
-fclose(do_stuff("php://memory"));
-
-echo "\ntemp stream (leak):\n";
-leak_variable(do_stuff("php://temp"), true);
-
-echo "\nmemory stream (leak):\n";
-leak_variable(do_stuff("php://memory"), true);
-
-echo "\nDone.\n";
---EXPECTF--
-temp stream (close after):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-memory stream (close after):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-temp stream (leak):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-memory stream (leak):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-Done.
+--TEST--
+Bug #52820 (writes to fopencookie FILE* not committed when seeking the stream)
+--SKIPIF--
+<?php
+if (!function_exists('leak_variable'))
+ die("skip only for debug builds");
+/* unfortunately no standard function does a cast to FILE*, so we need
+ * curl to test this */
+if (!extension_loaded("curl")) exit("skip curl extension not loaded");
+$handle=curl_init('http://127.0.0.1:37349/');
+curl_setopt($handle, CURLOPT_VERBOSE, true);
+curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
+if (!curl_setopt($handle, CURLOPT_STDERR, fopen("php://memory", "w+")))
+ die("skip fopencookie not supported on this platform");
+--FILE--
+<?php
+function do_stuff($url) {
+ $handle=curl_init('http://127.0.0.1:37349/');
+ curl_setopt($handle, CURLOPT_VERBOSE, true);
+ curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($handle, CURLOPT_STDERR, $o = fopen($url, "w+"));
+ curl_exec($handle);
+ echo "About to rewind!\n";
+ rewind($o);
+ echo stream_get_contents($o);
+ return $o;
+}
+
+echo "temp stream (close after):\n";
+fclose(do_stuff("php://temp"));
+
+echo "\nmemory stream (close after):\n";
+fclose(do_stuff("php://memory"));
+
+echo "\ntemp stream (leak):\n";
+leak_variable(do_stuff("php://temp"), true);
+
+echo "\nmemory stream (leak):\n";
+leak_variable(do_stuff("php://memory"), true);
+
+echo "\nDone.\n";
+--EXPECTF--
+temp stream (close after):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+memory stream (close after):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+temp stream (leak):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+memory stream (leak):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+Done.
diff --git a/ext/standard/tests/streams/proc_open_bug51800.phpt b/ext/standard/tests/streams/proc_open_bug51800.phpt
new file mode 100644
index 000000000..53cafd855
--- /dev/null
+++ b/ext/standard/tests/streams/proc_open_bug51800.phpt
@@ -0,0 +1,95 @@
+--TEST--
+Bug #51800 proc_open on Windows hangs forever
+--SKIPIF--
+<?php
+ echo 'skip expected to fail or take too long';
+ if (getenv("SKIP_SLOW_TESTS")) {
+ die("skip slow test");
+ }
+?>
+--XFAIL--
+pipes have to be read/written simultaneously
+--FILE--
+<?php
+/* This is the wrong way to do it. The parent will block till it has read all the STDIN.
+The smaller the pipe buffer is, the longer it will take. It might even pass at the end,
+after taking inappropriately long. Pipes have to be read simultaneously in smaller chunks,
+so then the pipe buffer is emptied more often and the child has chance to continue its
+write. The behaviour might look some better if write/read in a separate thread, however
+this is much more resource greedy and complexer to integrate into the user script. */
+
+$callee = dirname(__FILE__) . "/process_proc_open_bug51800.php";
+$php = PHP_BINARY;
+$cmd = "$php $callee";
+
+$status;
+$stdout = "";
+$stderr = "";
+$pipes = array();
+
+$descriptors = array(
+ 0 => array("pipe", "rb"), // stdin
+ 1 => array("pipe", "wb"), // stdout
+ 2 => array("pipe", "wb") // stderr
+ );
+
+/* create the proc file */
+$r = file_put_contents($callee, '<?php
+
+$how_much = 10000;
+
+$data0 = str_repeat("a", $how_much);
+$data1 = str_repeat("b", $how_much);
+fwrite(STDOUT, $data0);
+fwrite(STDERR, $data1);
+
+exit(0);
+');
+
+if (!$r) {
+ die("couldn't create helper script '$callee'");
+}
+
+$process = proc_open($cmd, $descriptors, $pipes);
+
+if (is_resource($process))
+{
+ fclose($pipes[0]);
+
+ while (!feof($pipes[1]))
+ $stdout .= fread($pipes[1], 1024);
+ fclose($pipes[1]);
+
+ while (!feof($pipes[2]))
+ $stderr .= fread($pipes[2], 1024);
+ fclose($pipes[2]);
+
+ $status = proc_close($process);
+}
+
+var_dump(array(
+ "status" => $status,
+ "stdout" => $stdout,
+ "stderr" => $stderr,
+), strlen($stdout), strlen($stderr));
+
+?>
+===DONE===
+--CLEAN--
+<?php
+$callee = dirname(__FILE__) . "/process_proc_open_bug51800.php";
+unlink($callee);
+?>
+--EXPECTF--
+array(3) {
+ ["status"]=>
+ int(0)
+ ["stdout"]=>
+ string(10000) "a%s"
+ ["stderr"]=>
+ string(10000) "b%s"
+}
+int(10000)
+int(10000)
+===DONE===
+
diff --git a/ext/standard/tests/streams/proc_open_bug51800_right.phpt b/ext/standard/tests/streams/proc_open_bug51800_right.phpt
new file mode 100644
index 000000000..b14fed2e5
--- /dev/null
+++ b/ext/standard/tests/streams/proc_open_bug51800_right.phpt
@@ -0,0 +1,78 @@
+--TEST--
+Bug #51800 proc_open on Windows hangs forever, the right way to do it
+--FILE--
+<?php
+$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right.php";
+$php = PHP_BINARY;
+$cmd = "$php $callee";
+
+$status;
+$stdout = "";
+$stderr = "";
+$pipes = array();
+
+$descriptors = array(
+ 0 => array("pipe", "rb"), // stdin
+ 1 => array("pipe", "wb"), // stdout
+ 2 => array("pipe", "wb") // stderr
+ );
+
+/* create the proc file */
+$r = file_put_contents($callee, '<?php
+
+$how_much = 10000;
+
+$data0 = str_repeat("a", $how_much);
+$data1 = str_repeat("b", $how_much);
+fwrite(STDOUT, $data0);
+fwrite(STDERR, $data1);
+
+exit(0);
+');
+
+if (!$r) {
+ die("couldn't create helper script '$callee'");
+}
+
+$process = proc_open($cmd, $descriptors, $pipes);
+
+if (is_resource($process))
+{
+ fclose($pipes[0]);
+
+ while (!feof($pipes[1]) || !feof($pipes[2])) {
+ $stdout .= fread($pipes[1], 1024);
+ $stderr .= fread($pipes[2], 1024);
+ }
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+
+ $status = proc_close($process);
+}
+
+var_dump(array(
+ "status" => $status,
+ "stdout" => $stdout,
+ "stderr" => $stderr,
+), strlen($stdout), strlen($stderr));
+
+?>
+===DONE===
+--CLEAN--
+<?php
+$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right.php";
+unlink($callee);
+?>
+--EXPECTF--
+array(3) {
+ ["status"]=>
+ int(0)
+ ["stdout"]=>
+ string(10000) "a%s"
+ ["stderr"]=>
+ string(10000) "b%s"
+}
+int(10000)
+int(10000)
+===DONE===
+
diff --git a/ext/standard/tests/streams/proc_open_bug51800_right2.phpt b/ext/standard/tests/streams/proc_open_bug51800_right2.phpt
new file mode 100644
index 000000000..1e742745c
--- /dev/null
+++ b/ext/standard/tests/streams/proc_open_bug51800_right2.phpt
@@ -0,0 +1,84 @@
+--TEST--
+Bug #51800 proc_open on Windows hangs forever, the right way to do it with more data
+--FILE--
+<?php
+$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right2.php";
+$php = PHP_BINARY;
+$cmd = "$php $callee";
+
+$status;
+$stdout = "";
+$stderr = "";
+$pipes = array();
+
+$descriptors = array(
+ 0 => array("pipe", "rb"), // stdin
+ 1 => array("pipe", "wb"), // stdout
+ 2 => array("pipe", "wb") // stderr
+ );
+
+/* create the proc file */
+$r = file_put_contents($callee, '<?php
+$how_much = 1000000;
+
+$data0 = str_repeat("a", $how_much);
+$data1 = str_repeat("b", $how_much);
+$i0 = $i1 = 0;
+$step = 1024;
+
+while ($i0 < strlen($data0) && $i1 < strlen($data1)) {
+ fwrite(STDOUT, substr($data0, $i0, $step));
+ fwrite(STDERR, substr($data1, $i1, $step));
+ $i0 += $step;
+ $i1 += $step;
+}
+
+exit(0);
+');
+
+if (!$r) {
+ die("couldn't create helper script '$callee'");
+}
+
+$process = proc_open($cmd, $descriptors, $pipes);
+
+if (is_resource($process))
+{
+ fclose($pipes[0]);
+
+ while (!feof($pipes[1]) || !feof($pipes[2])) {
+ $stdout .= fread($pipes[1], 1024);
+ $stderr .= fread($pipes[2], 1024);
+ }
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+
+ $status = proc_close($process);
+}
+
+var_dump(array(
+ "status" => $status,
+ "stdout" => $stdout,
+ "stderr" => $stderr,
+), strlen($stdout), strlen($stderr));
+
+?>
+===DONE===
+--CLEAN--
+<?php
+$callee = dirname(__FILE__) . "/process_proc_open_bug51800_right2.php";
+unlink($callee);
+?>
+--EXPECTF--
+array(3) {
+ ["status"]=>
+ int(0)
+ ["stdout"]=>
+ string(1000000) "a%s"
+ ["stderr"]=>
+ string(1000000) "b%s"
+}
+int(1000000)
+int(1000000)
+===DONE===
+
diff --git a/ext/standard/tests/streams/proc_open_bug60120.phpt b/ext/standard/tests/streams/proc_open_bug60120.phpt
new file mode 100644
index 000000000..8768257a2
--- /dev/null
+++ b/ext/standard/tests/streams/proc_open_bug60120.phpt
@@ -0,0 +1,71 @@
+--TEST--
+Bug #60120 proc_open hangs with stdin/out with 2048+ bytes
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ $cmd = PHP_BINARY . ' -n -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"';
+} else {
+ $cmd = PHP_BINARY . ' -n -r \'fwrite(STDOUT, $in = file_get_contents("php://stdin")); fwrite(STDERR, $in);\'';
+}
+$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
+$stdin = str_repeat('*', 1024 * 16) . '!';
+$stdin = str_repeat('*', 2049 );
+
+$options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false));
+$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options);
+
+foreach ($pipes as $pipe) {
+ stream_set_blocking($pipe, false);
+}
+$writePipes = array($pipes[0]);
+$stdinLen = strlen($stdin);
+$stdinOffset = 0;
+
+unset($pipes[0]);
+
+while ($pipes || $writePipes) {
+ $r = $pipes;
+ $w = $writePipes;
+ $e = null;
+ $n = stream_select($r, $w, $e, 60);
+
+ if (false === $n) {
+ break;
+ } elseif ($n === 0) {
+ proc_terminate($process);
+
+ }
+ if ($w) {
+ $written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192);
+ if (false !== $written) {
+ $stdinOffset += $written;
+ }
+ if ($stdinOffset >= $stdinLen) {
+ fclose($writePipes[0]);
+ $writePipes = null;
+ }
+ }
+
+ foreach ($r as $pipe) {
+ $type = array_search($pipe, $pipes);
+ $data = fread($pipe, 8192);
+ var_dump($data);
+ if (false === $data || feof($pipe)) {
+ fclose($pipe);
+ unset($pipes[$type]);
+ }
+ }
+}
+
+
+?>
+===DONE===
+--EXPECTF--
+string(2049) "%s"
+string(2049) "%s"
+string(0) ""
+string(0) ""
+===DONE===
+
diff --git a/ext/standard/tests/streams/proc_open_bug64438.phpt b/ext/standard/tests/streams/proc_open_bug64438.phpt
new file mode 100644
index 000000000..b3857d09d
--- /dev/null
+++ b/ext/standard/tests/streams/proc_open_bug64438.phpt
@@ -0,0 +1,70 @@
+--TEST--
+Bug #64438 proc_open hangs with stdin/out with 4097+ bytes
+--FILE--
+<?php
+
+error_reporting(E_ALL);
+
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ $cmd = PHP_BINARY . ' -n -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"';
+} else {
+ $cmd = PHP_BINARY . ' -n -r \'fwrite(STDOUT, $in = file_get_contents("php://stdin")); fwrite(STDERR, $in);\'';
+}
+$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
+$stdin = str_repeat('*', 4097);
+
+$options = array_merge(array('suppress_errors' => true, 'binary_pipes' => true, 'bypass_shell' => false));
+$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options);
+
+foreach ($pipes as $pipe) {
+ stream_set_blocking($pipe, false);
+}
+$writePipes = array($pipes[0]);
+$stdinLen = strlen($stdin);
+$stdinOffset = 0;
+
+unset($pipes[0]);
+
+while ($pipes || $writePipes) {
+ $r = $pipes;
+ $w = $writePipes;
+ $e = null;
+ $n = stream_select($r, $w, $e, 60);
+
+ if (false === $n) {
+ break;
+ } elseif ($n === 0) {
+ proc_terminate($process);
+
+ }
+ if ($w) {
+ $written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192);
+ if (false !== $written) {
+ $stdinOffset += $written;
+ }
+ if ($stdinOffset >= $stdinLen) {
+ fclose($writePipes[0]);
+ $writePipes = null;
+ }
+ }
+
+ foreach ($r as $pipe) {
+ $type = array_search($pipe, $pipes);
+ $data = fread($pipe, 8192);
+ var_dump($data);
+ if (false === $data || feof($pipe)) {
+ fclose($pipe);
+ unset($pipes[$type]);
+ }
+ }
+}
+
+?>
+===DONE===
+--EXPECTF--
+string(4097) "%s"
+string(4097) "%s"
+string(0) ""
+string(0) ""
+===DONE===
+
diff --git a/ext/standard/tests/strings/pack64.phpt b/ext/standard/tests/strings/pack64.phpt
new file mode 100644
index 000000000..9bc24928f
--- /dev/null
+++ b/ext/standard/tests/strings/pack64.phpt
@@ -0,0 +1,115 @@
+--TEST--
+64bit pack()/unpack() tests
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE < 8) {
+ die("skip 64bit test only");
+}
+?>
+--FILE--
+<?php
+print_r(unpack("Q", pack("Q", 0xfffffffffffe)));
+print_r(unpack("Q", pack("Q", 0)));
+print_r(unpack("Q", pack("Q", 0x8000000000000002)));
+print_r(unpack("Q", pack("Q", -1)));
+print_r(unpack("Q", pack("Q", 0x8000000000000000)));
+
+print_r(unpack("J", pack("J", 0xfffffffffffe)));
+print_r(unpack("J", pack("J", 0)));
+print_r(unpack("J", pack("J", 0x8000000000000002)));
+print_r(unpack("J", pack("J", -1)));
+print_r(unpack("J", pack("J", 0x8000000000000000)));
+
+print_r(unpack("P", pack("P", 0xfffffffffffe)));
+print_r(unpack("P", pack("P", 0)));
+print_r(unpack("P", pack("P", 0x8000000000000002)));
+print_r(unpack("P", pack("P", -1)));
+print_r(unpack("P", pack("P", 0x8000000000000000)));
+
+print_r(unpack("q", pack("q", 0xfffffffffffe)));
+print_r(unpack("q", pack("q", 0)));
+print_r(unpack("q", pack("q", 0x8000000000000002)));
+print_r(unpack("q", pack("q", -1)));
+print_r(unpack("q", pack("q", 0x8000000000000000)));
+?>
+--EXPECTF--
+Array
+(
+ [1] => 281474976710654
+)
+Array
+(
+ [1] => 0
+)
+Array
+(
+ [1] => -9223372036854775808
+)
+Array
+(
+ [1] => -1
+)
+Array
+(
+ [1] => -9223372036854775808
+)
+Array
+(
+ [1] => 281474976710654
+)
+Array
+(
+ [1] => 0
+)
+Array
+(
+ [1] => -9223372036854775808
+)
+Array
+(
+ [1] => -1
+)
+Array
+(
+ [1] => -9223372036854775808
+)
+Array
+(
+ [1] => 281474976710654
+)
+Array
+(
+ [1] => 0
+)
+Array
+(
+ [1] => -9223372036854775808
+)
+Array
+(
+ [1] => -1
+)
+Array
+(
+ [1] => -9223372036854775808
+)
+Array
+(
+ [1] => 281474976710654
+)
+Array
+(
+ [1] => 0
+)
+Array
+(
+ [1] => -9223372036854775808
+)
+Array
+(
+ [1] => -1
+)
+Array
+(
+ [1] => -9223372036854775808
+)
diff --git a/ext/standard/tests/strings/pack64_32.phpt b/ext/standard/tests/strings/pack64_32.phpt
new file mode 100644
index 000000000..f52de63ca
--- /dev/null
+++ b/ext/standard/tests/strings/pack64_32.phpt
@@ -0,0 +1,44 @@
+--TEST--
+64bit pack()/unpack() tests
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE > 4) {
+ die("skip 32bit test only");
+}
+?>
+--FILE--
+<?php
+var_dump(pack("Q", 0));
+var_dump(pack("J", 0));
+var_dump(pack("P", 0));
+var_dump(pack("q", 0));
+
+var_dump(unpack("Q", ''));
+var_dump(unpack("J", ''));
+var_dump(unpack("P", ''));
+var_dump(unpack("q", ''));
+?>
+--EXPECTF--
+Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
+
+Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
+
+Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
+
+Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
+
+Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
+
+Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
+
+Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
+
+Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
+bool(false)
diff --git a/ext/standard/tests/strings/setlocale_variation2.phpt b/ext/standard/tests/strings/setlocale_variation2.phpt
index 038ba58c5..5ebdfe8d5 100644
--- a/ext/standard/tests/strings/setlocale_variation2.phpt
+++ b/ext/standard/tests/strings/setlocale_variation2.phpt
@@ -18,8 +18,11 @@ if (substr(PHP_OS, 0, 3) == 'WIN') {
/* setlocale() to set all available locales in the system and check the success count */
echo "*** Testing setlocale() : usage variations ***\n";
-function good_locale($locale) {
- return $locale !== 'tt_RU@iqtelif.UTF-8';
+function good_locale($locale) {
+ /**
+ * Note: no_NO is a bogus locale and should not be used, see https://bugzilla.redhat.com/971416
+ **/
+ return $locale !== 'tt_RU@iqtelif.UTF-8' && $locale !== 'no_NO.ISO-8859-1';
}
/* Prototype : array list_system_locales( void )
diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt
index e0e541103..e172061ec 100644
--- a/ext/standard/tests/strings/url_t.phpt
+++ b/ext/standard/tests/strings/url_t.phpt
@@ -75,6 +75,7 @@ $sample_urls = array (
);
foreach ($sample_urls as $url) {
+ echo "\n--> $url: ";
var_dump(@parse_url($url));
}
@@ -84,21 +85,24 @@ $sample_urls = array (
}
?>
--EXPECT--
-array(1) {
+--> : array(1) {
["path"]=>
string(0) ""
}
-array(1) {
+
+--> 64.246.30.37: array(1) {
["path"]=>
string(12) "64.246.30.37"
}
-array(2) {
+
+--> http://64.246.30.37: array(2) {
["scheme"]=>
string(4) "http"
["host"]=>
string(12) "64.246.30.37"
}
-array(3) {
+
+--> http://64.246.30.37/: array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -106,11 +110,13 @@ array(3) {
["path"]=>
string(1) "/"
}
-array(1) {
+
+--> 64.246.30.37/: array(1) {
["path"]=>
string(13) "64.246.30.37/"
}
-array(3) {
+
+--> 64.246.30.37:80/: array(3) {
["host"]=>
string(12) "64.246.30.37"
["port"]=>
@@ -118,21 +124,25 @@ array(3) {
["path"]=>
string(1) "/"
}
-array(1) {
+
+--> php.net: array(1) {
["path"]=>
string(7) "php.net"
}
-array(1) {
+
+--> php.net/: array(1) {
["path"]=>
string(8) "php.net/"
}
-array(2) {
+
+--> http://php.net: array(2) {
["scheme"]=>
string(4) "http"
["host"]=>
string(7) "php.net"
}
-array(3) {
+
+--> http://php.net/: array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -140,21 +150,25 @@ array(3) {
["path"]=>
string(1) "/"
}
-array(1) {
+
+--> www.php.net: array(1) {
["path"]=>
string(11) "www.php.net"
}
-array(1) {
+
+--> www.php.net/: array(1) {
["path"]=>
string(12) "www.php.net/"
}
-array(2) {
+
+--> http://www.php.net: array(2) {
["scheme"]=>
string(4) "http"
["host"]=>
string(11) "www.php.net"
}
-array(3) {
+
+--> http://www.php.net/: array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -162,13 +176,15 @@ array(3) {
["path"]=>
string(1) "/"
}
-array(2) {
+
+--> www.php.net:80: array(2) {
["host"]=>
string(11) "www.php.net"
["port"]=>
int(80)
}
-array(3) {
+
+--> http://www.php.net:80: array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -176,7 +192,8 @@ array(3) {
["port"]=>
int(80)
}
-array(4) {
+
+--> http://www.php.net:80/: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -186,7 +203,8 @@ array(4) {
["path"]=>
string(1) "/"
}
-array(3) {
+
+--> http://www.php.net/index.php: array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -194,11 +212,13 @@ array(3) {
["path"]=>
string(10) "/index.php"
}
-array(1) {
+
+--> www.php.net/?: array(1) {
["path"]=>
string(12) "www.php.net/"
}
-array(3) {
+
+--> www.php.net:80/?: array(3) {
["host"]=>
string(11) "www.php.net"
["port"]=>
@@ -206,7 +226,8 @@ array(3) {
["path"]=>
string(1) "/"
}
-array(3) {
+
+--> http://www.php.net/?: array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -214,7 +235,8 @@ array(3) {
["path"]=>
string(1) "/"
}
-array(4) {
+
+--> http://www.php.net:80/?: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -224,7 +246,8 @@ array(4) {
["path"]=>
string(1) "/"
}
-array(4) {
+
+--> http://www.php.net:80/index.php: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -234,7 +257,8 @@ array(4) {
["path"]=>
string(10) "/index.php"
}
-array(4) {
+
+--> http://www.php.net:80/foo/bar/index.php: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -244,7 +268,8 @@ array(4) {
["path"]=>
string(18) "/foo/bar/index.php"
}
-array(4) {
+
+--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/file.php: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -254,7 +279,8 @@ array(4) {
["path"]=>
string(53) "/this/is/a/very/deep/directory/structure/and/file.php"
}
-array(5) {
+
+--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/file.php?lots=1&of=2&parameters=3&too=4&here=5: array(5) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -266,7 +292,8 @@ array(5) {
["query"]=>
string(37) "lots=1&of=2&parameters=3&too=4&here=5"
}
-array(4) {
+
+--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -276,7 +303,8 @@ array(4) {
["path"]=>
string(45) "/this/is/a/very/deep/directory/structure/and/"
}
-array(4) {
+
+--> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/file.php: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -286,7 +314,8 @@ array(4) {
["path"]=>
string(53) "/this/is/a/very/deep/directory/structure/and/file.php"
}
-array(4) {
+
+--> http://www.php.net:80/this/../a/../deep/directory: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -296,7 +325,8 @@ array(4) {
["path"]=>
string(28) "/this/../a/../deep/directory"
}
-array(4) {
+
+--> http://www.php.net:80/this/../a/../deep/directory/: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -306,7 +336,8 @@ array(4) {
["path"]=>
string(29) "/this/../a/../deep/directory/"
}
-array(4) {
+
+--> http://www.php.net:80/this/is/a/very/deep/directory/../file.php: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -316,7 +347,8 @@ array(4) {
["path"]=>
string(42) "/this/is/a/very/deep/directory/../file.php"
}
-array(4) {
+
+--> http://www.php.net:80/index.php: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -326,7 +358,8 @@ array(4) {
["path"]=>
string(10) "/index.php"
}
-array(4) {
+
+--> http://www.php.net:80/index.php?: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -336,7 +369,8 @@ array(4) {
["path"]=>
string(10) "/index.php"
}
-array(5) {
+
+--> http://www.php.net:80/#foo: array(5) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -348,7 +382,8 @@ array(5) {
["fragment"]=>
string(3) "foo"
}
-array(4) {
+
+--> http://www.php.net:80/?#: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -358,7 +393,8 @@ array(4) {
["path"]=>
string(1) "/"
}
-array(5) {
+
+--> http://www.php.net:80/?test=1: array(5) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -370,7 +406,8 @@ array(5) {
["query"]=>
string(6) "test=1"
}
-array(4) {
+
+--> http://www.php.net/?test=1&: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -380,7 +417,8 @@ array(4) {
["query"]=>
string(7) "test=1&"
}
-array(5) {
+
+--> http://www.php.net:80/?&: array(5) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -392,7 +430,8 @@ array(5) {
["query"]=>
string(1) "&"
}
-array(5) {
+
+--> http://www.php.net:80/index.php?test=1&: array(5) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -404,7 +443,8 @@ array(5) {
["query"]=>
string(7) "test=1&"
}
-array(4) {
+
+--> http://www.php.net/index.php?&: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -414,7 +454,8 @@ array(4) {
["query"]=>
string(1) "&"
}
-array(5) {
+
+--> http://www.php.net:80/index.php?foo&: array(5) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -426,7 +467,8 @@ array(5) {
["query"]=>
string(4) "foo&"
}
-array(4) {
+
+--> http://www.php.net/index.php?&foo: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -436,7 +478,8 @@ array(4) {
["query"]=>
string(4) "&foo"
}
-array(5) {
+
+--> http://www.php.net:80/index.php?test=1&test2=char&test3=mixesCI: array(5) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -448,7 +491,8 @@ array(5) {
["query"]=>
string(31) "test=1&test2=char&test3=mixesCI"
}
-array(5) {
+
+--> www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(5) {
["host"]=>
string(11) "www.php.net"
["port"]=>
@@ -460,7 +504,8 @@ array(5) {
["fragment"]=>
string(16) "some_page_ref123"
}
-array(7) {
+
+--> http://secret@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -476,13 +521,16 @@ array(7) {
["fragment"]=>
string(16) "some_page_ref123"
}
-array(6) {
+
+--> 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"]=>
@@ -490,13 +538,16 @@ array(6) {
["fragment"]=>
string(16) "some_page_ref123"
}
-array(7) {
+
+--> 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"]=>
@@ -506,7 +557,8 @@ array(7) {
["fragment"]=>
string(16) "some_page_ref123"
}
-array(7) {
+
+--> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -522,7 +574,8 @@ array(7) {
["fragment"]=>
string(16) "some_page_ref123"
}
-array(7) {
+
+--> 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"]=>
@@ -538,7 +591,8 @@ array(7) {
["fragment"]=>
string(16) "some_page_ref123"
}
-array(8) {
+
+--> 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"]=>
@@ -556,13 +610,15 @@ array(8) {
["fragment"]=>
string(16) "some_page_ref123"
}
-array(2) {
+
+--> nntp://news.php.net: array(2) {
["scheme"]=>
string(4) "nntp"
["host"]=>
string(12) "news.php.net"
}
-array(3) {
+
+--> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz: array(3) {
["scheme"]=>
string(3) "ftp"
["host"]=>
@@ -570,25 +626,29 @@ array(3) {
["path"]=>
string(22) "/gnu/glic/glibc.tar.gz"
}
-array(2) {
+
+--> zlib:http://foo@bar: array(2) {
["scheme"]=>
string(4) "zlib"
["path"]=>
string(14) "http://foo@bar"
}
-array(2) {
+
+--> zlib:filename.txt: array(2) {
["scheme"]=>
string(4) "zlib"
["path"]=>
string(12) "filename.txt"
}
-array(2) {
+
+--> zlib:/path/to/my/file/file.txt: array(2) {
["scheme"]=>
string(4) "zlib"
["path"]=>
string(25) "/path/to/my/file/file.txt"
}
-array(3) {
+
+--> foo://foo@bar: array(3) {
["scheme"]=>
string(3) "foo"
["host"]=>
@@ -596,25 +656,29 @@ array(3) {
["user"]=>
string(3) "foo"
}
-array(2) {
+
+--> mailto:me@mydomain.com: array(2) {
["scheme"]=>
string(6) "mailto"
["path"]=>
string(15) "me@mydomain.com"
}
-array(2) {
+
+--> /foo.php?a=b&c=d: array(2) {
["path"]=>
string(8) "/foo.php"
["query"]=>
string(7) "a=b&c=d"
}
-array(2) {
+
+--> foo.php?a=b&c=d: array(2) {
["path"]=>
string(7) "foo.php"
["query"]=>
string(7) "a=b&c=d"
}
-array(6) {
+
+--> http://user:passwd@www.example.com:8080?bar=1&boom=0: array(6) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -628,13 +692,15 @@ array(6) {
["query"]=>
string(12) "bar=1&boom=0"
}
-array(2) {
+
+--> file:///path/to/file: array(2) {
["scheme"]=>
string(4) "file"
["path"]=>
string(13) "/path/to/file"
}
-array(3) {
+
+--> file://path/to/file: array(3) {
["scheme"]=>
string(4) "file"
["host"]=>
@@ -642,13 +708,15 @@ array(3) {
["path"]=>
string(8) "/to/file"
}
-array(2) {
+
+--> file:/path/to/file: array(2) {
["scheme"]=>
string(4) "file"
["path"]=>
string(13) "/path/to/file"
}
-array(4) {
+
+--> http://1.2.3.4:/abc.asp?a=1&b=2: array(4) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -658,7 +726,8 @@ array(4) {
["query"]=>
string(7) "a=1&b=2"
}
-array(3) {
+
+--> http://foo.com#bar: array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -666,11 +735,13 @@ array(3) {
["fragment"]=>
string(3) "bar"
}
-array(1) {
+
+--> scheme:: array(1) {
["scheme"]=>
string(6) "scheme"
}
-array(4) {
+
+--> foo+bar://baz@bang/bla: array(4) {
["scheme"]=>
string(7) "foo+bar"
["host"]=>
@@ -680,13 +751,15 @@ array(4) {
["path"]=>
string(4) "/bla"
}
-array(2) {
+
+--> gg:9130731: array(2) {
["scheme"]=>
string(2) "gg"
["path"]=>
string(7) "9130731"
}
-array(7) {
+
+--> http://user:@pass@host/path?argument?value#etc: array(7) {
["scheme"]=>
string(4) "http"
["host"]=>
@@ -710,3 +783,4 @@ string(7) "hideout"
string(10) "/index.php"
string(31) "test=1&test2=char&test3=mixesCI"
string(16) "some_page_ref123"
+
diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt
index a6f4f7a25..0708691fe 100644
--- a/ext/standard/tests/url/parse_url_basic_001.phpt
+++ b/ext/standard/tests/url/parse_url_basic_001.phpt
@@ -454,13 +454,15 @@ echo "Done";
string(16) "some_page_ref123"
}
---> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) {
+--> 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"]=>
@@ -469,13 +471,15 @@ echo "Done";
string(16) "some_page_ref123"
}
---> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) {
+--> 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"]=>
diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt
index 1fc946e5b..5b2cb98f8 100644
--- a/ext/standard/tests/url/parse_url_basic_005.phpt
+++ b/ext/standard/tests/url/parse_url_basic_005.phpt
@@ -66,7 +66,7 @@ echo "Done";
--> www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
--> http://secret@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
--> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
---> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
+--> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(0) ""
--> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(14) "secret@hideout"
--> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
diff --git a/ext/standard/tests/url/parse_url_basic_006.phpt b/ext/standard/tests/url/parse_url_basic_006.phpt
index 510432619..79af6b8b6 100644
--- a/ext/standard/tests/url/parse_url_basic_006.phpt
+++ b/ext/standard/tests/url/parse_url_basic_006.phpt
@@ -65,7 +65,7 @@ echo "Done";
--> http://www.php.net:80/index.php?test=1&test2=char&test3=mixesCI : NULL
--> www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
--> http://secret@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
---> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
+--> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(0) ""
--> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(7) "hideout"
--> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(7) "hideout"
--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
diff --git a/ext/standard/url.c b/ext/standard/url.c
index fe1b2fe11..06c72e483 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -240,16 +240,12 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length)
/* check for login and password */
if ((p = zend_memrchr(s, '@', (e-s)))) {
if ((pp = memchr(s, ':', (p-s)))) {
- if ((pp-s) > 0) {
- ret->user = estrndup(s, (pp-s));
- php_replace_controlchars_ex(ret->user, (pp - s));
- }
+ ret->user = estrndup(s, (pp-s));
+ php_replace_controlchars_ex(ret->user, (pp - s));
pp++;
- if (p-pp > 0) {
- ret->pass = estrndup(pp, (p-pp));
- php_replace_controlchars_ex(ret->pass, (p-pp));
- }
+ ret->pass = estrndup(pp, (p-pp));
+ php_replace_controlchars_ex(ret->pass, (p-pp));
} else {
ret->user = estrndup(s, (p-s));
php_replace_controlchars_ex(ret->user, (p-s));