Browse Source

Merge branch 'PHP-5.4' of git.php.net:php-src into PHP-5.4

pull/203/head
Rasmus Lerdorf 14 years ago
parent
commit
f037ddc859
  1. 24
      NEWS
  2. 4
      Zend/zend_API.c
  3. 6
      Zend/zend_alloc.c
  4. 2
      ext/curl/tests/bug62839.phpt
  5. 16
      ext/date/php_date.c
  6. 33
      ext/date/tests/bug62852.phpt
  7. 2
      ext/dom/domerrorhandler.c
  8. 32
      ext/openssl/openssl.c
  9. 5
      ext/sockets/multicast.h
  10. 22
      ext/sockets/tests/bug63000.phpt
  11. 52
      ext/spl/tests/RecursiveDirectoryIterator_getSubPath_basic.phpt
  12. 58
      ext/spl/tests/RecursiveDirectoryIterator_getSubPathname_basic.phpt
  13. 13
      ext/standard/tests/strings/http_build_query_error.phpt
  14. 41
      sapi/cli/php_cli_server.c
  15. 10
      sapi/cli/php_http_parser.c
  16. 3
      sapi/cli/php_http_parser.h
  17. 43
      sapi/cli/tests/bug61679.phpt
  18. 44
      sapi/cli/tests/php_cli_server_018.phpt
  19. 8
      win32/build/libs_version.txt

24
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)

4
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);

6
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)
{

2
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);

16
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;
}
}
}

33
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

2
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();
/* }}} */

32
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);

5
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

22
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)

52
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==

58
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==

13
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

41
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) {

10
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;

3
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
};

43
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

44
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"

8
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
Loading…
Cancel
Save