summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Lerdorf <rasmus@php.net>2012-09-20 14:22:55 -0400
committerRasmus Lerdorf <rasmus@php.net>2012-09-20 14:22:55 -0400
commitf037ddc85971496f985d0cea540129b9d928bb97 (patch)
treed2c22102d131fdd7e205da55f7a7b3c7183d117c
parent2322be0fab44401cb2bc624771299ae6f598ee4e (diff)
parentffa72707c86750816f665656c02a0a0451300296 (diff)
downloadphp-git-f037ddc85971496f985d0cea540129b9d928bb97.tar.gz
Merge branch 'PHP-5.4' of git.php.net:php-src into PHP-5.4
-rw-r--r--NEWS24
-rw-r--r--Zend/zend_API.c4
-rw-r--r--Zend/zend_alloc.c6
-rw-r--r--ext/curl/tests/bug62839.phpt2
-rw-r--r--ext/date/php_date.c16
-rw-r--r--ext/date/tests/bug62852.phpt33
-rw-r--r--ext/dom/domerrorhandler.c2
-rw-r--r--ext/openssl/openssl.c32
-rw-r--r--ext/sockets/multicast.h5
-rw-r--r--ext/sockets/tests/bug63000.phpt22
-rw-r--r--ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt52
-rw-r--r--ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt58
-rw-r--r--ext/standard/tests/strings/http_build_query_error.phpt13
-rw-r--r--sapi/cli/php_cli_server.c41
-rw-r--r--sapi/cli/php_http_parser.c10
-rw-r--r--sapi/cli/php_http_parser.h3
-rw-r--r--sapi/cli/tests/bug61679.phpt43
-rw-r--r--sapi/cli/tests/php_cli_server_018.phpt44
-rw-r--r--win32/build/libs_version.txt8
19 files changed, 360 insertions, 58 deletions
diff --git a/NEWS b/NEWS
index db6f7f48d2..0c57e0cda0 100644
--- a/NEWS
+++ b/NEWS
@@ -2,9 +2,18 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2012, PHP 5.4.8
+- CLI server:
+ . Changed response to unknown HTTP method to 501 according to RFC.
+ (Niklas Lindgren).
+ . Support HTTP PATCH method. Patch by Niklas Lindgren, GitHub PR #190.
+ (Lars)
+
- Core:
. Added optional second argument for assert() to specify custom message. Patch
by Lonny Kapelushnik (lonny@lonnylot.com). (Lars)
+ . Support building PHP with the native client toolchain. (Stuart Langley)
+ . Fixed bug #63093 (Segfault while load extension failed in zts-build).
+ (Laruence)
. Fixed bug #62976 (Notice: could not be converted to int when comparing
some builtin classes). (Laruence)
. Fixed bug #62955 (Only one directive is loaded from "Per Directory Values"
@@ -15,6 +24,13 @@ PHP NEWS
. Fixed bug #60909 (custom error handler throwing Exception + fatal error
= no shutdown function). (Dmitry)
+- DOM:
+ . Fixed bug #63015 (Incorrect arginfo for DOMErrorHandler). (Rob)
+
+- OpenSSL:
+ . Implemented FR #61421 (OpenSSL signature verification missing RMD160,
+ SHA224, SHA256, SHA384, SHA512). (Mark Jones)
+
- SOAP
. Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice).
(Dmitry)
@@ -58,10 +74,6 @@ PHP NEWS
(Pierrick)
. Fixed bug #62839 (curl_copy_handle segfault with CURLOPT_FILE). (Pierrick)
-- DateTime:
- . Fixed bug #62852 (Unserialize invalid DateTime causes crash).
- (reeze.xia@gmail.com)
-
- Intl:
. Fixed Spoofchecker not being registered on ICU 49.1. (Gustavo)
. Fix bug #62933 (ext/intl compilation error on icu 3.4.1). (Gustavo)
@@ -238,7 +250,9 @@ PHP NEWS
- Sockets:
. Fixed bug #62025 (__ss_family was changed on AIX 5.3). (Felipe)
-
+ . Fixed bug #63000 (MCAST_JOIN_GROUP on OSX is broken, merge of PR 185 by
+ Igor Wiedler). (Lars)
+
- SPL:
. Fixed bug #62433 (Inconsistent behavior of RecursiveDirectoryIterator to
dot files). (Laruence)
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index a231415547..3c9d59d692 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -2265,7 +2265,9 @@ void module_destructor(zend_module_entry *module) /* {{{ */
/* Deinitilaise module globals */
if (module->globals_size) {
#ifdef ZTS
- ts_free_id(*module->globals_id_ptr);
+ if (*module->globals_id_ptr) {
+ ts_free_id(*module->globals_id_ptr);
+ }
#else
if (module->globals_dtor) {
module->globals_dtor(module->globals_ptr TSRMLS_CC);
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 66cd23c7cb..0b0e8632c1 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -664,7 +664,7 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_
static inline unsigned int zend_mm_high_bit(size_t _size)
{
-#if defined(__GNUC__) && defined(i386)
+#if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
unsigned int n;
__asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size));
@@ -690,7 +690,7 @@ static inline unsigned int zend_mm_high_bit(size_t _size)
static inline unsigned int zend_mm_low_bit(size_t _size)
{
-#if defined(__GNUC__) && defined(i386)
+#if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
unsigned int n;
__asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size));
@@ -2454,7 +2454,7 @@ ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_
return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
-#if defined(__GNUC__) && defined(i386)
+#if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
{
diff --git a/ext/curl/tests/bug62839.phpt b/ext/curl/tests/bug62839.phpt
index 39e6fc9cbe..e6988d6de1 100644
--- a/ext/curl/tests/bug62839.phpt
+++ b/ext/curl/tests/bug62839.phpt
@@ -7,7 +7,7 @@ Bug #62839 (curl_copy_handle segfault with CURLOPT_FILE)
<?php
$curl = curl_init();
-$fd = fopen('/tmp/test', 'wb');
+$fd = tmpfile();
curl_setopt($curl, CURLOPT_FILE, $fd);
curl_copy_handle($curl);
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index 7c4e7820bb..13e7b753d3 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -2467,9 +2467,6 @@ static int php_date_initialize_from_hash(zval **return_value, php_date_obj **dat
if (zend_hash_find(myht, "timezone_type", 14, (void**) &z_timezone_type) == SUCCESS) {
convert_to_long(*z_timezone_type);
if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) == SUCCESS) {
- zend_error_handling error_handling;
-
- zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
convert_to_string(*z_timezone);
switch (Z_LVAL_PP(z_timezone_type)) {
@@ -2477,9 +2474,9 @@ static int php_date_initialize_from_hash(zval **return_value, php_date_obj **dat
case TIMELIB_ZONETYPE_ABBR: {
char *tmp = emalloc(Z_STRLEN_PP(z_date) + Z_STRLEN_PP(z_timezone) + 2);
snprintf(tmp, Z_STRLEN_PP(z_date) + Z_STRLEN_PP(z_timezone) + 2, "%s %s", Z_STRVAL_PP(z_date), Z_STRVAL_PP(z_timezone));
- php_date_initialize(*dateobj, tmp, Z_STRLEN_PP(z_date) + Z_STRLEN_PP(z_timezone) + 1, NULL, NULL, 1 TSRMLS_CC);
+ php_date_initialize(*dateobj, tmp, Z_STRLEN_PP(z_date) + Z_STRLEN_PP(z_timezone) + 1, NULL, NULL, 0 TSRMLS_CC);
efree(tmp);
- break;
+ return 1;
}
case TIMELIB_ZONETYPE_ID:
@@ -2493,15 +2490,10 @@ static int php_date_initialize_from_hash(zval **return_value, php_date_obj **dat
tzobj->tzi.tz = tzi;
tzobj->initialized = 1;
- php_date_initialize(*dateobj, Z_STRVAL_PP(z_date), Z_STRLEN_PP(z_date), NULL, tmp_obj, 1 TSRMLS_CC);
+ php_date_initialize(*dateobj, Z_STRVAL_PP(z_date), Z_STRLEN_PP(z_date), NULL, tmp_obj, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp_obj);
- break;
- default:
- zend_restore_error_handling(&error_handling TSRMLS_CC);
- return 0;
+ return 1;
}
- zend_restore_error_handling(&error_handling TSRMLS_CC);
- return 1;
}
}
}
diff --git a/ext/date/tests/bug62852.phpt b/ext/date/tests/bug62852.phpt
index 6426a80fb8..26de510215 100644
--- a/ext/date/tests/bug62852.phpt
+++ b/ext/date/tests/bug62852.phpt
@@ -2,14 +2,35 @@
Bug #62852 (Unserialize invalid DateTime causes crash)
--INI--
date.timezone=GMT
+--XFAIL--
+bug is not fixed yet
--FILE--
<?php
-try {
- $datetime = unserialize('O:8:"DateTime":3:{s:4:"date";s:20:"10007-06-07 03:51:49";s:13:"timezone_type";i:3;s:8:"timezone";s:3:"UTC";}');
- var_dump($datetime);
-} catch (Exception $e) {
- var_dump($e->getMessage());
+$s1 = 'O:8:"DateTime":3:{s:4:"date";s:20:"10007-06-07 03:51:49";s:13:"timezone_type";i:3;s:8:"timezone";s:3:"UTC";}';
+$s2 = 'O:3:"Foo":3:{s:4:"date";s:20:"10007-06-07 03:51:49";s:13:"timezone_type";i:3;s:8:"timezone";s:3:"UTC";}';
+
+global $foo;
+
+class Foo extends DateTime {
+ function __wakeup() {
+ global $foo;
+ $foo = $this;
+ parent::__wakeup();
+ }
}
+
+// Old test case
+try {
+ unserialize( $s1 );
+} catch ( Exception $e ) {}
+
+// My test case
+try {
+ unserialize( $s2 );
+} catch ( Exception $e ) {}
+var_dump( $foo );
+
+echo "okey";
?>
--EXPECTF--
-string(%d) "DateTime::__wakeup(): Failed to parse time string (%s) at position 12 (0): Double time specification"
+okey
diff --git a/ext/dom/domerrorhandler.c b/ext/dom/domerrorhandler.c
index f1ab2871a8..e282f30146 100644
--- a/ext/dom/domerrorhandler.c
+++ b/ext/dom/domerrorhandler.c
@@ -29,7 +29,7 @@
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_domerrorhandler_handle_error, 0, 0, 1)
- ZEND_ARG_OBJ_INFO(0, error, DOMError, 0)
+ ZEND_ARG_OBJ_INFO(0, error, DOMDomError, 0)
ZEND_END_ARG_INFO();
/* }}} */
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 7187a9601e..2b8cfd571a 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -69,7 +69,13 @@
#define OPENSSL_ALGO_MD2 4
#endif
#define OPENSSL_ALGO_DSS1 5
-
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+#define OPENSSL_ALGO_SHA224 6
+#define OPENSSL_ALGO_SHA256 7
+#define OPENSSL_ALGO_SHA384 8
+#define OPENSSL_ALGO_SHA512 9
+#define OPENSSL_ALGO_RMD160 10
+#endif
#define DEBUG_SMIME 0
/* FIXME: Use the openssl constants instead of
@@ -954,6 +960,23 @@ static EVP_MD * php_openssl_get_evp_md_from_algo(long algo) { /* {{{ */
case OPENSSL_ALGO_DSS1:
mdtype = (EVP_MD *) EVP_dss1();
break;
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+ case OPENSSL_ALGO_SHA224:
+ mdtype = (EVP_MD *) EVP_sha224();
+ break;
+ case OPENSSL_ALGO_SHA256:
+ mdtype = (EVP_MD *) EVP_sha256();
+ break;
+ case OPENSSL_ALGO_SHA384:
+ mdtype = (EVP_MD *) EVP_sha384();
+ break;
+ case OPENSSL_ALGO_SHA512:
+ mdtype = (EVP_MD *) EVP_sha512();
+ break;
+ case OPENSSL_ALGO_RMD160:
+ mdtype = (EVP_MD *) EVP_ripemd160();
+ break;
+#endif
default:
return NULL;
break;
@@ -1048,6 +1071,13 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD2", OPENSSL_ALGO_MD2, CONST_CS|CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);
+#if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA224", OPENSSL_ALGO_SHA224, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA256", OPENSSL_ALGO_SHA256, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA384", OPENSSL_ALGO_SHA384, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA512", OPENSSL_ALGO_SHA512, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_RMD160", OPENSSL_ALGO_RMD160, CONST_CS|CONST_PERSISTENT);
+#endif
/* flags for S/MIME */
REGISTER_LONG_CONSTANT("PKCS7_DETACHED", PKCS7_DETACHED, CONST_CS|CONST_PERSISTENT);
diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h
index ccd9b1d2a8..5619c9c7fb 100644
--- a/ext/sockets/multicast.h
+++ b/ext/sockets/multicast.h
@@ -19,11 +19,12 @@
/* $Id$ */
#if defined(MCAST_JOIN_GROUP) && \
- (!defined(PHP_WIN32) || (_WIN32_WINNT >= 0x600 && SOCKETS_ENABLE_VISTA_API))
+ (!defined(PHP_WIN32) || (_WIN32_WINNT >= 0x600 && SOCKETS_ENABLE_VISTA_API)) && \
+ !defined(__APPLE__)
#define RFC3678_API 1
/* has block/unblock and source membership, in this case for both IPv4 and IPv6 */
#define HAS_MCAST_EXT 1
-#elif defined(IP_ADD_SOURCE_MEMBERSHIP)
+#elif defined(IP_ADD_SOURCE_MEMBERSHIP) && !defined(__APPLE__)
/* has block/unblock and source membership, but only for IPv4 */
#define HAS_MCAST_EXT 1
#endif
diff --git a/ext/sockets/tests/bug63000.phpt b/ext/sockets/tests/bug63000.phpt
new file mode 100644
index 0000000000..c806ba4c08
--- /dev/null
+++ b/ext/sockets/tests/bug63000.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #63000: Multicast on OSX
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets')) {
+ die('skip sockets extension not available.');
+}
+if (PHP_OS !== 'Darwin') {
+ die('is not OSX.');
+}
+--FILE--
+<?php
+$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
+socket_bind($socket, '0.0.0.0', 31057);
+
+$so = socket_set_option($socket, IPPROTO_IP, MCAST_JOIN_GROUP, array(
+ "group" => '224.0.0.251',
+ "interface" => 0,
+));
+var_dump($so);
+--EXPECTF--
+bool(true)
diff --git a/ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt b/ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt
new file mode 100644
index 0000000000..5107cd32b6
--- /dev/null
+++ b/ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt
@@ -0,0 +1,52 @@
+--TEST--
+RecursiveDirectoryIterator::getBasePath() - basic test
+--CREDITS--
+Pawel Krynicki <pawel [dot] krynicki [at] xsolve [dot] pl>
+#testfest AmsterdamPHP 2012-06-23
+--FILE--
+<?php
+$depth0 = md5('recursiveDirectoryIterator::getSubPath');
+$depth1 = md5('depth1');
+$depth2 = md5('depth2');
+$targetDir = __DIR__ . DIRECTORY_SEPARATOR . $depth0 . DIRECTORY_SEPARATOR . $depth1 . DIRECTORY_SEPARATOR . $depth2;
+mkdir($targetDir, 0777, true);
+touch($targetDir . DIRECTORY_SEPARATOR . 'getSubPath_test.tmp');
+$iterator = new RecursiveDirectoryIterator(__DIR__ . DIRECTORY_SEPARATOR . $depth0);
+$it = new RecursiveIteratorIterator($iterator);
+
+$list = [];
+while($it->valid()) {
+ $list[] = $it->getSubPath();
+ $it->next();
+}
+asort($list);
+foreach ($list as $item) {
+ echo $item . "\n";
+}
+?>
+==DONE==
+--CLEAN--
+<?php
+function rrmdir($dir) {
+ foreach(glob($dir . '/*') as $file) {
+ if(is_dir($file)) {
+ rrmdir($file);
+ } else {
+ unlink($file);
+ }
+ }
+
+ rmdir($dir);
+ }
+
+ $targetDir = __DIR__.DIRECTORY_SEPARATOR.md5('recursiveDirectoryIterator::getSubPath');
+ rrmdir($targetDir);
+?>
+
+--EXPECT--
+a0c967a6c2c34786e4802f59af9356f5
+a0c967a6c2c34786e4802f59af9356f5
+a0c967a6c2c34786e4802f59af9356f5/9925aabb545352472e4d77942627b507
+a0c967a6c2c34786e4802f59af9356f5/9925aabb545352472e4d77942627b507
+a0c967a6c2c34786e4802f59af9356f5/9925aabb545352472e4d77942627b507
+==DONE==
diff --git a/ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt b/ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt
new file mode 100644
index 0000000000..4e17ea9d42
--- /dev/null
+++ b/ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt
@@ -0,0 +1,58 @@
+--TEST--
+RecursiveDirectoryIterator::getBasePathname() - basic test
+--CREDITS--
+Pawel Krynicki <pawel [dot] krynicki [at] xsolve [dot] pl>
+#testfest AmsterdamPHP 2012-06-23
+--FILE--
+<?php
+$depth0 = md5('recursiveDirectoryIterator::getSubPathname');
+$depth1 = md5('depth1');
+$depth2 = md5('depth2');
+$targetDir = __DIR__ . DIRECTORY_SEPARATOR . $depth0 . DIRECTORY_SEPARATOR . $depth1 . DIRECTORY_SEPARATOR . $depth2;
+mkdir($targetDir, 0777, true);
+touch($targetDir . DIRECTORY_SEPARATOR . 'getSubPathname_test_2.tmp');
+touch(__DIR__ . DIRECTORY_SEPARATOR . $depth0 . DIRECTORY_SEPARATOR . $depth1 . DIRECTORY_SEPARATOR . 'getSubPathname_test_3.tmp');
+touch(__DIR__ . DIRECTORY_SEPARATOR . $depth0 . DIRECTORY_SEPARATOR . 'getSubPathname_test_1.tmp');
+$iterator = new RecursiveDirectoryIterator(__DIR__ . DIRECTORY_SEPARATOR . $depth0);
+$it = new RecursiveIteratorIterator($iterator);
+
+$list = [];
+while($it->valid()) {
+ $list[] = $it->getSubPathname();
+ $it->next();
+}
+asort($list);
+foreach ($list as $item) {
+ echo $item . "\n";
+}
+?>
+==DONE==
+--CLEAN--
+<?php
+function rrmdir($dir) {
+ foreach(glob($dir . '/*') as $file) {
+ if(is_dir($file)) {
+ rrmdir($file);
+ } else {
+ unlink($file);
+ }
+ }
+
+ rmdir($dir);
+}
+
+$targetDir = __DIR__ . DIRECTORY_SEPARATOR . md5('recursiveDirectoryIterator::getSubPathname');
+rrmdir($targetDir);
+?>
+--EXPECT--
+.
+.
+..
+a0c967a6c2c34786e4802f59af9356f5/.
+a0c967a6c2c34786e4802f59af9356f5/..
+a0c967a6c2c34786e4802f59af9356f5/9925aabb545352472e4d77942627b507/.
+a0c967a6c2c34786e4802f59af9356f5/9925aabb545352472e4d77942627b507/..
+a0c967a6c2c34786e4802f59af9356f5/9925aabb545352472e4d77942627b507/getSubPathname_test_2.tmp
+a0c967a6c2c34786e4802f59af9356f5/getSubPathname_test_3.tmp
+getSubPathname_test_1.tmp
+==DONE==
diff --git a/ext/standard/tests/strings/http_build_query_error.phpt b/ext/standard/tests/strings/http_build_query_error.phpt
new file mode 100644
index 0000000000..30155e62a3
--- /dev/null
+++ b/ext/standard/tests/strings/http_build_query_error.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Testing error on null parameter 1 of http_build_query()
+--CREDITS--
+Pawel Krynicki <pawel.krynicki [at] xsolve [dot] pl>
+#testfest AmsterdamPHP 2012-06-23
+--FILE--
+<?php
+
+$result = http_build_query(null);
+
+?>
+--EXPECTF--
+Warning: http_build_query(): Parameter 1 expected to be Array or Object. %s value given in %s on line %d \ No newline at end of file
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index e80ab68f80..4d15db44af 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -116,7 +116,7 @@ typedef struct php_cli_server_poller {
} php_cli_server_poller;
typedef struct php_cli_server_request {
- enum php_http_method request_method;
+ enum php_http_method request_method;
int protocol_version;
char *request_uri;
size_t request_uri_len;
@@ -247,7 +247,8 @@ static php_cli_server_http_reponse_status_code_pair status_map[] = {
static php_cli_server_http_reponse_status_code_pair template_map[] = {
{ 400, "<h1 class=\"h\">%s</h1><p>Your browser sent a request that this server could not understand.</p>" },
{ 404, "<h1 class=\"h\">%s</h1><p>The requested resource %s was not found on this server.</p>" },
- { 500, "<h1 class=\"h\">%s</h1><p>The server is temporality unavaiable.</p>" }
+ { 500, "<h1 class=\"h\">%s</h1><p>The server is temporarily unavailable.</p>" },
+ { 501, "<h1 class=\"h\">%s</h1><p>Request method not supported.</p>" }
};
static php_cli_server_ext_mime_type_pair mime_type_map[] = {
@@ -275,7 +276,7 @@ static void php_cli_server_log_response(php_cli_server_client *client, int statu
ZEND_DECLARE_MODULE_GLOBALS(cli_server);
-/* {{{ static char php_cli_server_css[]
+/* {{{ static char php_cli_server_css[]
* copied from ext/standard/info.c
*/
static const char php_cli_server_css[] = "<style type=\"text/css\">\n" \
@@ -543,7 +544,7 @@ static void sapi_cli_server_register_variable(zval *track_vars_array, const char
}
} /* }}} */
-static int sapi_cli_server_register_entry_cb(char **entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ {
+static int sapi_cli_server_register_entry_cb(char **entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ {
zval *track_vars_array = va_arg(args, zval *);
if (hash_key->nKeyLength) {
char *real_key, *key;
@@ -583,7 +584,7 @@ static void sapi_cli_server_register_variables(zval *track_vars_array TSRMLS_DC)
} else {
sapi_cli_server_register_variable(track_vars_array, "REMOTE_ADDR", client->addr_str TSRMLS_CC);
}
- }
+ }
{
char *tmp;
spprintf(&tmp, 0, "PHP %s Development Server", PHP_VERSION);
@@ -681,7 +682,7 @@ sapi_module_struct cli_server_sapi_module = {
sapi_cli_server_log_message, /* Log message */
NULL, /* Get request time */
NULL, /* Child terminate */
-
+
STANDARD_SAPI_MODULE_PROPERTIES
}; /* }}} */
@@ -778,7 +779,7 @@ static int php_cli_server_poller_iter_on_active(php_cli_server_poller *poller, v
}
}
}
-
+
#else
php_socket_t fd = 0;
const php_socket_t max_fd = poller->max_fd;
@@ -966,7 +967,7 @@ static int php_cli_server_content_sender_send(php_cli_server_content_sender *sen
} else if (nbytes_sent == chunk->data.immortal.len) {
php_cli_server_chunk_dtor(chunk);
pefree(chunk, 1);
- sender->buffer.first = next;
+ sender->buffer.first = next;
if (!next) {
sender->buffer.last = NULL;
}
@@ -1345,7 +1346,7 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque
}
}
break; /* regular file */
- }
+ }
if (prev_path) {
pefree(prev_path, 1);
*q = DEFAULT_SLASH;
@@ -1384,7 +1385,7 @@ static void php_cli_server_request_translate_vpath(php_cli_server_request *reque
if (request->vpath[i] == '\\') {
request->vpath[i] = '/';
}
- }
+ }
}
#endif
request->sb = sb;
@@ -1452,7 +1453,7 @@ static void normalize_vpath(char **retval, size_t *retval_len, const char *vpath
}
}
}
-
+
*decoded_vpath_end = '\0';
*retval = decoded_vpath;
*retval_len = decoded_vpath_end - decoded_vpath;
@@ -1812,7 +1813,7 @@ static int php_cli_server_send_error_page(php_cli_server *server, php_cli_server
smart_str_append_generic_ex(&buffer, php_cli_server_buffer_size(&client->content_sender.buffer), 1, size_t, _unsigned);
smart_str_appendl_ex(&buffer, "\r\n", 2, 1);
smart_str_appendl_ex(&buffer, "\r\n", 2, 1);
-
+
chunk = php_cli_server_chunk_heap_new(buffer.c, buffer.c, buffer.len);
if (!chunk) {
smart_str_free_ex(&buffer, 1);
@@ -1917,7 +1918,7 @@ static int php_cli_server_begin_send_static(php_cli_server *server, php_cli_serv
}
/* }}} */
-static int php_cli_server_request_startup(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) { /* {{{ */
+static int php_cli_server_request_startup(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) { /* {{{ */
char **auth;
php_cli_server_client_populate_request_info(client, &SG(request_info));
if (SUCCESS == zend_hash_find(&client->request.headers, "Authorization", sizeof("Authorization"), (void**)&auth)) {
@@ -1942,8 +1943,8 @@ static int php_cli_server_request_shutdown(php_cli_server *server, php_cli_serve
SG(server_context) = NULL;
SG(rfc1867_uploaded_files) = NULL;
return SUCCESS;
-}
-/* }}} */
+}
+/* }}} */
static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) /* {{{ */
{
@@ -2002,7 +2003,7 @@ static int php_cli_server_dispatch(php_cli_server *server, php_cli_server_client
destroy_request_info(&SG(request_info));
return SUCCESS;
}
- }
+ }
if (server->router) {
if (!php_cli_server_dispatch_router(server, client TSRMLS_CC)) {
@@ -2016,7 +2017,7 @@ static int php_cli_server_dispatch(php_cli_server *server, php_cli_server_client
|| SUCCESS != php_cli_server_send_error_page(server, client, 500 TSRMLS_CC)) {
php_cli_server_request_shutdown(server, client TSRMLS_CC);
return SUCCESS;
- }
+ }
} else {
if (server->router) {
static int (*send_header_func)(sapi_headers_struct * TSRMLS_DC);
@@ -2029,7 +2030,7 @@ static int php_cli_server_dispatch(php_cli_server *server, php_cli_server_client
sapi_module.send_headers = send_header_func;
SG(sapi_headers).send_default_content_type = 1;
SG(rfc1867_uploaded_files) = NULL;
- }
+ }
if (SUCCESS != php_cli_server_begin_send_static(server, client TSRMLS_CC)) {
php_cli_server_close_connection(server, client TSRMLS_CC);
}
@@ -2191,6 +2192,8 @@ static int php_cli_server_recv_event_read_request(php_cli_server *server, php_cl
efree(errstr);
php_cli_server_close_connection(server, client TSRMLS_CC);
return FAILURE;
+ } else if (status == 1 && client->request.request_method == PHP_HTTP_NOT_IMPLEMENTED) {
+ return php_cli_server_send_error_page(server, client, 501 TSRMLS_CC);
} else if (status == 1) {
php_cli_server_poller_remove(&server->poller, POLLIN, client->sock);
php_cli_server_dispatch(server, client TSRMLS_CC);
@@ -2311,7 +2314,7 @@ static void php_cli_server_do_event_for_each_fd(php_cli_server *server, int(*rha
static int php_cli_server_do_event_loop(php_cli_server *server TSRMLS_DC) /* {{{ */
{
int retval = SUCCESS;
- while (server->is_running) {
+ while (server->is_running) {
static const struct timeval tv = { 1, 0 };
int n = php_cli_server_poller_poll(&server->poller, &tv);
if (n > 0) {
diff --git a/sapi/cli/php_http_parser.c b/sapi/cli/php_http_parser.c
index 13b9ea12bc..d3bc496f4e 100644
--- a/sapi/cli/php_http_parser.c
+++ b/sapi/cli/php_http_parser.c
@@ -81,6 +81,7 @@ static const char *method_strings[] =
, "HEAD"
, "POST"
, "PUT"
+ , "PATCH"
, "CONNECT"
, "OPTIONS"
, "TRACE"
@@ -99,6 +100,7 @@ static const char *method_strings[] =
, "NOTIFY"
, "SUBSCRIBE"
, "UNSUBSCRIBE"
+ , "NOTIMPLEMENTED"
};
@@ -589,7 +591,7 @@ size_t php_http_parser_execute (php_http_parser *parser,
case 'S': parser->method = PHP_HTTP_SUBSCRIBE; break;
case 'T': parser->method = PHP_HTTP_TRACE; break;
case 'U': parser->method = PHP_HTTP_UNLOCK; /* or UNSUBSCRIBE */ break;
- default: goto error;
+ default: parser->method = PHP_HTTP_NOT_IMPLEMENTED; break;
}
state = s_req_method;
break;
@@ -602,7 +604,7 @@ size_t php_http_parser_execute (php_http_parser *parser,
goto error;
matcher = method_strings[parser->method];
- if (ch == ' ' && matcher[index] == '\0') {
+ if (ch == ' ' && (matcher[index] == '\0' || parser->method == PHP_HTTP_NOT_IMPLEMENTED)) {
state = s_req_spaces_before_url;
} else if (ch == matcher[index]) {
; /* nada */
@@ -626,12 +628,14 @@ size_t php_http_parser_execute (php_http_parser *parser,
parser->method = PHP_HTTP_PROPFIND; /* or HTTP_PROPPATCH */
} else if (index == 1 && parser->method == PHP_HTTP_POST && ch == 'U') {
parser->method = PHP_HTTP_PUT;
+ } else if (index == 1 && parser->method == PHP_HTTP_POST && ch == 'A') {
+ parser->method = PHP_HTTP_PATCH;
} else if (index == 2 && parser->method == PHP_HTTP_UNLOCK && ch == 'S') {
parser->method = PHP_HTTP_UNSUBSCRIBE;
} else if (index == 4 && parser->method == PHP_HTTP_PROPFIND && ch == 'P') {
parser->method = PHP_HTTP_PROPPATCH;
} else {
- goto error;
+ parser->method = PHP_HTTP_NOT_IMPLEMENTED;
}
++index;
diff --git a/sapi/cli/php_http_parser.h b/sapi/cli/php_http_parser.h
index 7e72b78d7d..2bf2356725 100644
--- a/sapi/cli/php_http_parser.h
+++ b/sapi/cli/php_http_parser.h
@@ -80,6 +80,7 @@ enum php_http_method
, PHP_HTTP_HEAD
, PHP_HTTP_POST
, PHP_HTTP_PUT
+ , PHP_HTTP_PATCH
/* pathological */
, PHP_HTTP_CONNECT
, PHP_HTTP_OPTIONS
@@ -102,6 +103,8 @@ enum php_http_method
, PHP_HTTP_NOTIFY
, PHP_HTTP_SUBSCRIBE
, PHP_HTTP_UNSUBSCRIBE
+ /* unknown, not implemented */
+ , PHP_HTTP_NOT_IMPLEMENTED
};
diff --git a/sapi/cli/tests/bug61679.phpt b/sapi/cli/tests/bug61679.phpt
new file mode 100644
index 0000000000..819ce2fa89
--- /dev/null
+++ b/sapi/cli/tests/bug61679.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Bug #61679 (Error on non-standard HTTP methods)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+echo "This should never echo";
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+// Send a request with a fictitious request method,
+// I like smurfs, the smurf everything.
+if(fwrite($fp, <<<HEADER
+SMURF / HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ // Only echo the first line from the response,
+ // the rest is not interesting
+ break;
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 501 Not Implemented
diff --git a/sapi/cli/tests/php_cli_server_018.phpt b/sapi/cli/tests/php_cli_server_018.phpt
new file mode 100644
index 0000000000..deb9348768
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_018.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Implement Req #61679 (Support HTTP PATCH method)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+var_dump($_SERVER['REQUEST_METHOD']);
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+PATCH / HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: %s
+Content-type: text/html
+
+string(5) "PATCH"
diff --git a/win32/build/libs_version.txt b/win32/build/libs_version.txt
index 0d1af3d1b4..3df3be3795 100644
--- a/win32/build/libs_version.txt
+++ b/win32/build/libs_version.txt
@@ -4,13 +4,13 @@ freetype-2.4.3
icu-4.6.1
jpeglib-6b
libcurl-7.24.0
-libiconv-1.11
+libiconv-1.14
libmcrypt-2.5.8
libmpir-2.5.1
libpng-1.2.46
libpq-8.3.6
libssh2-1.3.0
libtidy-20090325
-libxslt-1.1.23
-libxml-2.7.7
-openssl-0.9.8u
+libxslt-1.1.27
+libxml-2.7.8
+openssl-0.9.8x