Compare commits

...
52 Commits
Author SHA1 Message Date
Julien Pauli 6daaf1103b 5.5.7 2013-12-11 00:31:06 +01:00
Stanislav Malyshev 073d24bb50 Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
  5.3.29-dev
  Fix CVE-2013-6420 - memory corruption in openssl_x509_parse
2013-12-11 00:03:32 +01:00
Julien Pauli bdb901b64a 5.5.7RC1 2013-11-27 09:22:41 +01:00
Stanislav Malyshev 5cd8ff9885 Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
  5.4.24-dev now

Conflicts:
	configure.in
	main/php_version.h
2013-11-27 00:14:42 -08:00
Stanislav Malyshev 63f3ff7b5f 5.4.24-dev now 2013-11-27 00:13:45 -08:00
Andrey Hristov 0fc90b100d Merge branch 'PHP-5.5' of git.php.net:php-src into PHP-5.5 2013-11-26 20:10:30 +02:00
Dmitry Stogov de65817136 Fixed opcahce_reset() crash when opcache.protect_memory is set 2013-11-26 21:57:32 +04:00
Dmitry Stogov 2381b817aa Merge branch 'PHP-5.5' of git.php.net:php-src into PHP-5.5
* 'PHP-5.5' of git.php.net:php-src:
  Fixed a wrong test
2013-11-26 21:44:54 +04:00
Andrey Hristov 9a6b72a05a Merge branch 'PHP-5.4' into PHP-5.5 2013-11-26 19:15:43 +02:00
Andrey Hristov 5a3886f15c merge fix 2013-11-26 19:15:30 +02:00
Andrey Hristov 0aadab0e2e add test 2013-11-26 19:15:12 +02:00
Andrey Hristov 40dc242904 Merge branch 'PHP-5.4' into PHP-5.5
Conflicts:
	NEWS
	ext/mysqlnd/mysqlnd.c
2013-11-26 19:02:45 +02:00
Andrey Hristov 74ba88e186 Fix for Bug #66141 (mysqlnd quote function is wrong with NO_BACKSLASH_ESCAPES after failed query) 2013-11-26 19:01:49 +02:00
Dmitry Stogov d79dd9cc1c Fixed bug #66176 (Invalid constant substitution) 2013-11-26 21:00:00 +04:00
Julien Pauli ff20a9019d Fixed a wrong test 2013-11-26 17:43:31 +01:00
Dmitry Stogov 27524b52b5 Fixed bug #66176 (Invalid constant substitution) 2013-11-26 19:55:49 +04:00
Dmitry Stogov d85ac7fb3f Fixed bug #66176 (Invalid constant substitution) 2013-11-26 17:47:02 +04:00
Dmitry Stogov f28ac55b6d Added test 2013-11-26 12:13:42 +04:00
Dmitry Stogov a8c7e50f4d Fixed bug #65559 (Opcache: cache not cleared if changes occur while running) 2013-11-26 11:34:41 +04:00
Andrey Hristov 29ee38bf0d Merge branch 'PHP-5.4' into PHP-5.5
Conflicts:
	NEWS
2013-11-25 21:33:04 +02:00
Andrey Hristov 1b0e6067d5 bring the news 2013-11-25 21:31:51 +02:00
Dmitry Stogov b7b6c35eea Fixed compatibility with old PHP versions 2013-11-25 14:09:57 +04:00
Dmitry Stogov 27dc82d0ec Fixed bug #65915 (Inconsistent results with require return value) 2013-11-25 14:07:24 +04:00
Anatol Belski ad5a63e8bc Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
  fixed test
2013-11-21 21:29:02 +01:00
Anatol Belski 345032946c fixed test 2013-11-21 21:24:47 +01:00
Andrey Hristov 763f4aef8b Merge branch 'PHP-5.4' into PHP-5.5 2013-11-21 21:29:37 +02:00
Andrey Hristov ce09822269 And here is the real fix for #66124 2013-11-21 21:29:21 +02:00
Andrey Hristov c2b2afacc0 Merge branch 'PHP-5.4' into PHP-5.5 2013-11-21 21:15:22 +02:00
Andrey Hristov 4a1c9be857 Fix for Bug #66124 (mysqli under mysqlnd loses precision when bind_param with 'i') 2013-11-21 21:14:42 +02:00
Anatol Belski 18b2b2a0bc Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
  permanently deactivate that place, not on runtime only
2013-11-20 10:11:39 +01:00
Anatol Belski b902a25cc3 permanently deactivate that place, not on runtime only
besides the two "if" checks, this fixes static analyze which is sometimes
broken because of this
2013-11-20 10:09:11 +01:00
Yasuo Ohgaki b8b92bd790 Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
  added a test to cover distinction between boolean return value of unserialize function and deserializing serialized boolean
2013-11-20 07:23:54 +09:00
Yasuo Ohgaki 0d558afc05 Fix WS in serialization_error_002.phpt 2013-11-20 07:17:53 +09:00
Aaron Hamid 050dd59c63 added a test to cover distinction between boolean return value of unserialize function and deserializing serialized boolean 2013-11-20 07:14:53 +09:00
Jeff Welch 72a8489a12 Fixed tests that fail with non-default serialize_precision configurations.
See:

 * https://bugs.php.net/bug.php?id=64760
 * 4dc4302
2013-11-20 06:17:34 +09:00
Jeff Welch 101c780500 Fixed tests that fail with non-default serialize_precision configurations.
See:

 * https://bugs.php.net/bug.php?id=64760
 * 4dc4302
2013-11-20 06:17:23 +09:00
Remi Collet 87cabc04ac Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
  avoid doing a stream_select on a closed stream
2013-11-19 12:42:25 +01:00
Remi Collet 25c08a839a avoid doing a stream_select on a closed stream 2013-11-19 12:41:58 +01:00
Andrea Faulds e3528f086a Updated NEWS 2013-11-18 21:23:45 +00:00
Andrea Faulds 9937e2fda5 Merge branch 'CLIGetAllHeadersBackport' into PHP-5.5
* CLIGetAllHeadersBackport:
  Removed UPGRADING note
  Rewrote test using tcp instead of http:// stream
  Implemented FR #65917 (getallheaders() is not supported by the built-in...)
2013-11-18 21:19:07 +00:00
Xinchen Hui 5e9268f469 Update NEWS 2013-11-17 17:06:27 +08:00
Xinchen Hui de79c51555 Merge branch 'PHP-5.4' into PHP-5.5 2013-11-17 17:05:04 +08:00
Xinchen Hui 823e330c75 Fixed Bug #66094 (unregister_tick_function tries to cast a Closure to a string) 2013-11-17 17:04:37 +08:00
Christopher Jones d0cd112702 This is CLI web server change. Added some common MIME types to the
existing lookup list, pending a more thorough lookup solution, if
anyone wants to do that.  Ref http://news.php.net/php.internals/69990

A router can be used to add to, or override, the MIME type lookups,
see http://php.net/manual/en/features.commandline.webserver.php
2013-11-15 12:36:25 -08:00
Remi Collet cd6eda5e5f NEWS 2013-11-15 09:52:48 +01:00
Remi Collet b8d88bf2c5 Fix Bug #65714 PHP cli forces the tty to cooked mode
Only drop the using_history() call with libedit as I don't know
if it is required with readline.

This also allow to run a php script in background without
it being aborted on first output.
2013-11-15 09:49:42 +01:00
Adam Harvey d7441f6695 Move the JSON bugfix into the 5.5.6 changelog. 2013-11-14 10:52:07 -08:00
Andrea Faulds 7d2609b0f5 Removed UPGRADING note
Conflicts:
	UPGRADING
2013-11-13 17:05:02 +00:00
Remi Collet 018b9445da Fix failed test with recent glibc
In recent version of strptime glibc upstream has fixed a discrepancy between
documentation and actual behaviour by skipping over the sequence that would match %Z.
See http://repo.or.cz/w/glibc.git/commitdiff/ddc7e412ab252e7360a4357664beb3b5d9c4f42b

So when %Z is used in format
glibc <= 2.18 returns the GMT as unparsed
glibc >= 2.19 returns empty string

Removing %Z from tested format gives the same behavior with all version.
2013-11-13 13:19:10 +01:00
Andrea Faulds a3f5b9f62d Rewrote test using tcp instead of http:// stream 2013-11-12 20:27:38 +00:00
Andrea Faulds aee271ec0d Implemented FR #65917 (getallheaders() is not supported by the built-in...)
- Implemented apache_request_headers() and getallheaders() alias in CLI server
- Implemented apache_response_headers() in CLI server using FastCGI code

Conflicts:
	NEWS
	UPGRADING
2013-11-12 20:27:34 +00:00
Julien Pauli 1984919ddc 5.5.7 now 2013-11-12 18:20:09 +01:00
38 changed files with 828 additions and 211 deletions

No files matched your search

+26 -5
View File
@@ -1,13 +1,30 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2013, PHP 5.5.7
12 Dec 2013, PHP 5.5.7
- JSON
. Fixed whitespace part of bug #64874 ("json_decode handles whitespace and
case-sensitivity incorrectly"). (Andrea Faulds)
- CLI server:
. Added some MIME types to the CLI web server (Chris Jones)
. Implemented FR #65917 (getallheaders() is not supported by the built-in web
server) - also implements apache_response_headers() (Andrea Faulds)
- Core:
. Fixed bug #66094 (unregister_tick_function tries to cast a Closure to a
string). (Laruence)
?? ??? 2013, PHP 5.5.6
- OPCache
. Fixed bug #66176 (Invalid constant substitution). (Dmitry)
. Fixed bug #65915 (Inconsistent results with require return value). (Dmitry)
. Fixed bug #65559 (Opcache: cache not cleared if changes occur while
running). (Dmitry)
- OpenSSL:
. Fixed memory corruption in openssl_x509_parse() (CVE-2013-6420).
(Stefan Esser).
- readline
. Fixed Bug #65714 (PHP cli forces the tty to cooked mode). (Remi)
14 Nov 2013, PHP 5.5.6
- Core:
. Fixed bug #65947 (basename is no more working after fgetcsv in certain
@@ -23,6 +40,10 @@ PHP NEWS
- FPM:
. Changed default listen() backlog to 65535. (Tony)
- JSON
. Fixed whitespace part of bug #64874 ("json_decode handles whitespace and
case-sensitivity incorrectly"). (Andrea Faulds)
- MySQLi:
. Fixed bug #66043 (Segfault calling bind_param() on mysqli). (Laruence)
+2
View File
@@ -789,6 +789,7 @@ static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *o
static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
#if 0
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && 0) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
@@ -843,6 +844,7 @@ static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *o
return SUCCESS;
}
}
#endif
return div_function(result, op1, op2 TSRMLS_CC);
}
+2 -2
View File
@@ -119,8 +119,8 @@ int zend_sprintf(char *buffer, const char *format, ...);
PHP_MAJOR_VERSION=5
PHP_MINOR_VERSION=5
PHP_RELEASE_VERSION=6
PHP_EXTRA_VERSION="-dev"
PHP_RELEASE_VERSION=7
PHP_EXTRA_VERSION=""
PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION"
PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION`
+101
View File
@@ -0,0 +1,101 @@
--TEST--
Bug #66124 (mysqli under mysqlnd loses precision when bind_param with 'i')
--SKIPIF--
<?php
require_once('skipif.inc');
require_once('connect.inc');
require_once('skipifconnectfailure.inc');
?>
--FILE--
<?php
$table_drop = "DROP TABLE IF EXISTS `bug66124`";
$table_create = "CREATE TABLE `bug66124` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8";
$table_insert = "INSERT INTO `bug66124` SET `id`=?";
$table_select = "SELECT * FROM `bug66124`";
$table_delete = "DELETE FROM `bug66124`";
$id = '1311200011005001566';
require_once('connect.inc');
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
printf("Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
$host, $user, $db, $port, $socket);
exit(1);
}
$link->query($table_drop);
$link->query($table_create);
$stmt = $link->prepare($table_insert);
if (!$stmt) {
printf("Can't prepare\n");
exit(1);
}
echo "Using 'i':\n";
$stmt->bind_param('i', $id);
if ($stmt->execute()){
echo "insert id:{$id}=>{$stmt->insert_id}\n";
} else {
printf("Can't execute\n");
exit(1);
}
$result = $link->query($table_select);
if ($result){
while ($row = $result->fetch_assoc()) {
echo "fetch id:{$row['id']}\n";
}
} else {
printf("Can't select\n");
exit(1);
}
$stmt->close();
$link->query($table_drop);
$link->query($table_create);
$stmt = $link->prepare($table_insert);
$stmt->bind_param('s', $id);
echo "Using 's':\n";
if ($stmt->execute()){
echo "insert id:{$id}\n";
} else{
printf("Can't execute\n");
exit(1);
}
$result = $link->query($table_select);
if ($result){
while ($row = $result->fetch_assoc()) {
echo "fetch id:{$row['id']}\n";
}
} else {
printf("Can't select\n");
exit(1);
}
$link->close();
?>
done
--EXPECTF--
Using 'i':
insert id:1311200011005001566=>1311200011005001566
fetch id:1311200011005001566
Using 's':
insert id:1311200011005001566
fetch id:1311200011005001566
done
+8 -4
View File
@@ -257,6 +257,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_handle_response)(MYSQLND_CONN_D
conn->persistent);
if (!ignore_upsert_status) {
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
conn->upsert_status->warning_count = ok_response->warning_count;
conn->upsert_status->server_status = ok_response->server_status;
conn->upsert_status->affected_rows = ok_response->affected_rows;
@@ -319,6 +320,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA
DBG_ENTER("mysqlnd_conn_data::simple_command_send_request");
DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
switch (CONN_GET_STATE(conn)) {
case CONN_READY:
@@ -333,10 +335,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA
DBG_RETURN(FAIL);
}
/* clean UPSERT info */
if (!ignore_upsert_status) {
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
}
SET_ERROR_AFF_ROWS(conn);
SET_EMPTY_ERROR(*conn->error_info);
@@ -811,6 +809,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
{
goto err;
}
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
conn->upsert_status->warning_count = 0;
conn->upsert_status->server_status = greet_packet->server_status;
conn->upsert_status->affected_rows = 0;
@@ -1183,6 +1182,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_query)(MYSQLND_CONN_DATA * conn, const ch
enum_func_status ret = FAIL;
DBG_ENTER("mysqlnd_conn_data::send_query");
DBG_INF_FMT("conn=%llu query=%s", conn->thread_id, query);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
ret = conn->m->simple_command(conn, COM_QUERY, (zend_uchar *) query, query_len,
@@ -1193,6 +1193,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_query)(MYSQLND_CONN_DATA * conn, const ch
}
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
DBG_RETURN(ret);
}
/* }}} */
@@ -1208,6 +1209,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn TSRMLS_DC
DBG_ENTER("mysqlnd_conn_data::reap_query");
DBG_INF_FMT("conn=%llu", conn->thread_id);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
if (state <= CONN_READY || state == CONN_QUIT_SENT) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not opened, clear or has been closed");
@@ -1218,6 +1220,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn TSRMLS_DC
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
DBG_RETURN(ret);
}
/* }}} */
@@ -1603,6 +1606,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, escape_string)(MYSQLND_CONN_DATA * const conn,
DBG_INF_FMT("conn=%llu", conn->thread_id);
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
DBG_INF_FMT("server_status=%u", conn->upsert_status->server_status);
if (conn->upsert_status->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) {
ret = mysqlnd_cset_escape_quotes(conn->charset, newstr, escapestr, escapestr_len TSRMLS_CC);
} else {
+3
View File
@@ -486,6 +486,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC);
if (ret == FAIL) {
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
memset(stmt->upsert_status, 0, sizeof(*stmt->upsert_status));
stmt->upsert_status->affected_rows = conn->upsert_status->affected_rows;
if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) {
/* close the statement here, the connection has been closed */
@@ -905,6 +906,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
DBG_INF("EOF");
/* Mark the connection as usable again */
result->unbuf->eof_reached = TRUE;
memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status));
result->conn->upsert_status->warning_count = row_packet->warning_count;
result->conn->upsert_status->server_status = row_packet->server_status;
/*
@@ -1014,6 +1016,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
row_packet->skip_extraction = stmt->result_bind? FALSE:TRUE;
memset(stmt->upsert_status, 0, sizeof(*stmt->upsert_status));
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) {
unsigned int i, field_count = result->field_count;
+30 -11
View File
@@ -569,9 +569,8 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
occur, and force resend for the next execution.
*/
for (i = 0; i < stmt->param_count; i++) {
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL &&
(stmt->param_bind[i].type == MYSQL_TYPE_LONG || stmt->param_bind[i].type == MYSQL_TYPE_LONGLONG))
{
short current_type = stmt->param_bind[i].type;
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
/* always copy the var, because we do many conversions */
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG &&
PASS != mysqlnd_stmt_copy_it(&copies, stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC))
@@ -585,10 +584,31 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
*/
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
convert_to_double_ex(&tmp_data);
if (Z_DVAL_P(tmp_data) > LONG_MAX || Z_DVAL_P(tmp_data) < LONG_MIN) {
/*
Because converting to double and back to long can lead
to losing precision we need second variable. Conversion to double is to see if
value is too big for a long. As said, precision could be lost.
*/
zval *tmp_data_copy;
MAKE_STD_ZVAL(tmp_data_copy);
*tmp_data_copy = *tmp_data;
Z_SET_REFCOUNT_P(tmp_data_copy, 1);
zval_copy_ctor(tmp_data_copy);
convert_to_double_ex(&tmp_data_copy);
/*
if it doesn't fit in a long send it as a string.
Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
We do transformation here, which will be used later when sending types. The code later relies on this.
*/
if (Z_DVAL_P(tmp_data_copy) > LONG_MAX || Z_DVAL_P(tmp_data_copy) < LONG_MIN) {
stmt->send_types_to_server = resend_types_next_time = 1;
convert_to_string_ex(&tmp_data);
} else {
convert_to_long_ex(&tmp_data);
}
zval_ptr_dtor(&tmp_data_copy);
}
}
}
@@ -631,10 +651,11 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
*/
if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
convert_to_double_ex(&tmp_data);
if (Z_DVAL_P(tmp_data) > LONG_MAX || Z_DVAL_P(tmp_data) < LONG_MIN) {
convert_to_string_ex(&tmp_data);
/*
In case of IS_LONG we do nothing, it is ok, in case of string, we just need to set current_type.
The actual transformation has been performed several dozens line above.
*/
if (Z_TYPE_P(tmp_data) == IS_STRING) {
current_type = MYSQL_TYPE_VAR_STRING;
/*
don't change stmt->param_bind[i].type to MYSQL_TYPE_VAR_STRING
@@ -642,8 +663,6 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
if the type is however not long, then we will do a goto in the next switch.
We want to preserve the original bind type given by the user. Thus, we do these hacks.
*/
} else {
convert_to_long_ex(&tmp_data);
}
}
}
+4
View File
@@ -415,6 +415,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s
DBG_INF("UPSERT");
conn->last_query_type = QUERY_UPSERT;
conn->field_count = rset_header->field_count;
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
conn->upsert_status->warning_count = rset_header->warning_count;
conn->upsert_status->server_status = rset_header->server_status;
conn->upsert_status->affected_rows = rset_header->affected_rows;
@@ -702,6 +703,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
/* Mark the connection as usable again */
DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status);
result->unbuf->eof_reached = TRUE;
memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status));
result->conn->upsert_status->warning_count = row_packet->warning_count;
result->conn->upsert_status->server_status = row_packet->server_status;
/*
@@ -828,6 +830,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
/* Mark the connection as usable again */
DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status);
result->unbuf->eof_reached = TRUE;
memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status));
result->conn->upsert_status->warning_count = row_packet->warning_count;
result->conn->upsert_status->server_status = row_packet->server_status;
/*
@@ -1175,6 +1178,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
/* Finally clean */
if (row_packet->eof) {
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
conn->upsert_status->warning_count = row_packet->warning_count;
conn->upsert_status->server_status = row_packet->server_status;
}
+2
View File
@@ -827,6 +827,7 @@ php_mysqlnd_ok_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
packet->error, sizeof(packet->error),
&packet->error_no, packet->sqlstate
TSRMLS_CC);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
DBG_RETURN(PASS);
}
/* Everything was fine! */
@@ -1069,6 +1070,7 @@ php_mysqlnd_rset_header_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
packet->error_info.error, sizeof(packet->error_info.error),
&packet->error_info.error_no, packet->error_info.sqlstate
TSRMLS_CC);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
DBG_RETURN(PASS);
}
+11 -48
View File
@@ -643,8 +643,11 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
opline->opcode != ZEND_FREE
) {
zend_op *src = VAR_SOURCE(opline->op1);
zval c = ZEND_OP1_LITERAL(src);
VAR_UNSET(opline->op1);
COPY_NODE(opline->op1, src->op1);
zval_copy_ctor(&c);
update_op1_const(op_array, opline, &c TSRMLS_CC);
literal_dtor(&ZEND_OP1_LITERAL(src));
MAKE_NOP(src);
}
@@ -654,51 +657,12 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
VAR_SOURCE(opline->op2)->opcode == ZEND_QM_ASSIGN &&
ZEND_OP1_TYPE(VAR_SOURCE(opline->op2)) == IS_CONST) {
zend_op *src = VAR_SOURCE(opline->op2);
zval c = ZEND_OP1_LITERAL(src);
VAR_UNSET(opline->op2);
COPY_NODE(opline->op2, src->op1);
zval_copy_ctor(&c);
update_op2_const(op_array, opline, &c TSRMLS_CC);
literal_dtor(&ZEND_OP1_LITERAL(src));
MAKE_NOP(src);
#if ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO
/* numeric string constants used as array indeces have to be
converted to long at compile time */
if (opline->opcode == ZEND_ADD_ARRAY_ELEMENT ||
opline->opcode == ZEND_INIT_ARRAY ||
opline->opcode == ZEND_UNSET_DIM ||
opline->opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ ||
opline->opcode == ZEND_FETCH_DIM_R ||
opline->opcode == ZEND_FETCH_DIM_W ||
opline->opcode == ZEND_FETCH_DIM_RW ||
opline->opcode == ZEND_FETCH_DIM_IS ||
opline->opcode == ZEND_FETCH_DIM_FUNC_ARG ||
opline->opcode == ZEND_FETCH_DIM_UNSET ||
opline->opcode == ZEND_FETCH_DIM_TMP_VAR ||
(opline->opcode == ZEND_OP_DATA &&
((opline-1)->opcode == ZEND_ASSIGN_DIM ||
((opline-1)->extended_value == ZEND_ASSIGN_DIM &&
((opline-1)->opcode == ZEND_ASSIGN_ADD ||
(opline-1)->opcode == ZEND_ASSIGN_SUB ||
(opline-1)->opcode == ZEND_ASSIGN_MUL ||
(opline-1)->opcode == ZEND_ASSIGN_DIV ||
(opline-1)->opcode == ZEND_ASSIGN_MOD ||
(opline-1)->opcode == ZEND_ASSIGN_SL ||
(opline-1)->opcode == ZEND_ASSIGN_SR ||
(opline-1)->opcode == ZEND_ASSIGN_CONCAT ||
(opline-1)->opcode == ZEND_ASSIGN_BW_OR ||
(opline-1)->opcode == ZEND_ASSIGN_BW_AND ||
(opline-1)->opcode == ZEND_ASSIGN_BW_XOR))))) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
ulong index;
int numeric = 0;
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline))+1, index, numeric = 1);
if (numeric) {
zval_dtor(&ZEND_OP2_LITERAL(opline));
ZVAL_LONG(&ZEND_OP2_LITERAL(opline), index);
}
}
}
#endif
}
/* T = PRINT(X), F(T) => ECHO(X), F(1) */
@@ -1070,10 +1034,9 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
literal_dtor(&ZEND_OP1_LITERAL(opline));
literal_dtor(&ZEND_OP2_LITERAL(opline));
ZEND_OP1_LITERAL(opline) = result;
SET_UNUSED(opline->op2);
opline->opcode = ZEND_QM_ASSIGN;
SET_UNUSED(opline->op2);
update_op1_const(op_array, opline, &result TSRMLS_CC);
}
EG(error_reporting) = er;
} else if ((opline->opcode == ZEND_BOOL ||
@@ -1097,8 +1060,8 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
}
PZ_SET_REFCOUNT_P(&result, 1);
PZ_UNSET_ISREF_P(&result);
ZEND_OP1_LITERAL(opline) = result;
opline->opcode = ZEND_QM_ASSIGN;
update_op1_const(op_array, opline, &result TSRMLS_CC);
} else if ((opline->opcode == ZEND_RETURN || opline->opcode == ZEND_EXIT) &&
ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
VAR_SOURCE(opline->op1) &&
+7 -16
View File
@@ -219,15 +219,11 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
EG(in_execution) = 1;
EG(active_op_array) = op_array;
if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) {
zend_uint tv = ZEND_RESULT(opline).var;
literal_dtor(&ZEND_OP2_LITERAL(opline));
ZEND_OP1_TYPE(opline) = IS_CONST;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
opline->op1.constant = zend_optimizer_add_literal(op_array, &offset TSRMLS_CC);
#else
ZEND_OP1_LITERAL(opline) = offset;
#endif
SET_UNUSED(opline->op2);
opline->opcode = ZEND_QM_ASSIGN;
MAKE_NOP(opline);
replace_tmp_by_const(op_array, opline, tv, &offset TSRMLS_CC);
}
EG(active_op_array) = orig_op_array;
EG(in_execution) = orig_in_execution;
@@ -238,20 +234,15 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
ZEND_OP2_TYPE(opline) == IS_CONST &&
ZEND_OP2_LITERAL(opline).type == IS_STRING) {
/* substitute persistent constants */
zend_uint tv = ZEND_RESULT(opline).var;
zval c;
if (!zend_get_persistent_constant(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) {
break;
}
literal_dtor(&ZEND_OP2_LITERAL(opline));
ZEND_OP1_TYPE(opline) = IS_CONST;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
opline->op1.constant = zend_optimizer_add_literal(op_array, &c TSRMLS_CC);
#else
ZEND_OP1_LITERAL(opline) = c;
#endif
SET_UNUSED(opline->op2);
opline->opcode = ZEND_QM_ASSIGN;
MAKE_NOP(opline);
replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
}
break;
+165 -106
View File
@@ -19,6 +19,7 @@
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "Optimizer/zend_optimizer.h"
#include "Optimizer/zend_optimizer_internal.h"
#include "zend_API.h"
@@ -110,6 +111,167 @@ int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC
#endif
static void update_op1_const(zend_op_array *op_array,
zend_op *opline,
zval *val TSRMLS_DC)
{
if (opline->opcode == ZEND_FREE) {
MAKE_NOP(opline);
zval_dtor(val);
} else {
ZEND_OP1_TYPE(opline) = IS_CONST;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (Z_TYPE_P(val) == IS_STRING) {
switch (opline->opcode) {
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_CATCH:
case ZEND_FETCH_CONSTANT:
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1);
break;
case ZEND_DO_FCALL:
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
break;
default:
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
break;
}
} else {
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
}
#else
ZEND_OP1_LITERAL(opline) = *val;
#endif
}
}
static void update_op2_const(zend_op_array *op_array,
zend_op *opline,
zval *val TSRMLS_DC)
{
ZEND_OP2_TYPE(opline) = IS_CONST;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
opline->op2.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
if (Z_TYPE_P(val) == IS_STRING) {
Z_HASH_P(&ZEND_OP2_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1);
switch (opline->opcode) {
case ZEND_FETCH_R:
case ZEND_FETCH_W:
case ZEND_FETCH_RW:
case ZEND_FETCH_IS:
case ZEND_FETCH_UNSET:
case ZEND_FETCH_FUNC_ARG:
case ZEND_FETCH_CLASS:
case ZEND_INIT_FCALL_BY_NAME:
/*case ZEND_INIT_NS_FCALL_BY_NAME:*/
case ZEND_UNSET_VAR:
case ZEND_ISSET_ISEMPTY_VAR:
case ZEND_ADD_INTERFACE:
case ZEND_ADD_TRAIT:
op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++;
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
break;
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
/* break missing intentionally */
/*case ZEND_FETCH_CONSTANT:*/
case ZEND_ASSIGN_OBJ:
case ZEND_FETCH_OBJ_R:
case ZEND_FETCH_OBJ_W:
case ZEND_FETCH_OBJ_RW:
case ZEND_FETCH_OBJ_IS:
case ZEND_FETCH_OBJ_UNSET:
case ZEND_FETCH_OBJ_FUNC_ARG:
case ZEND_UNSET_OBJ:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
op_array->last_cache_slot += 2;
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
op_array->last_cache_slot += 2;
}
break;
#if ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO
case ZEND_OP_DATA:
if ((opline-1)->opcode == ZEND_ASSIGN_DIM ||
((opline-1)->extended_value == ZEND_ASSIGN_DIM &&
((opline-1)->opcode == ZEND_ASSIGN_ADD ||
(opline-1)->opcode == ZEND_ASSIGN_SUB ||
(opline-1)->opcode == ZEND_ASSIGN_MUL ||
(opline-1)->opcode == ZEND_ASSIGN_DIV ||
(opline-1)->opcode == ZEND_ASSIGN_MOD ||
(opline-1)->opcode == ZEND_ASSIGN_SL ||
(opline-1)->opcode == ZEND_ASSIGN_SR ||
(opline-1)->opcode == ZEND_ASSIGN_CONCAT ||
(opline-1)->opcode == ZEND_ASSIGN_BW_OR ||
(opline-1)->opcode == ZEND_ASSIGN_BW_AND ||
(opline-1)->opcode == ZEND_ASSIGN_BW_XOR))) {
goto check_numeric;
}
break;
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
case ZEND_ADD_ARRAY_ELEMENT:
case ZEND_INIT_ARRAY:
case ZEND_UNSET_DIM:
case ZEND_FETCH_DIM_R:
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_IS:
case ZEND_FETCH_DIM_FUNC_ARG:
case ZEND_FETCH_DIM_UNSET:
case ZEND_FETCH_DIM_TMP_VAR:
check_numeric:
{
ulong index;
int numeric = 0;
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(val), Z_STRLEN_P(val)+1, index, numeric = 1);
if (numeric) {
zval_dtor(val);
ZVAL_LONG(val, index);
op_array->literals[opline->op2.constant].constant = *val;
}
}
break;
#endif
default:
break;
}
}
#else
ZEND_OP2_LITERAL(opline) = *val;
#endif
}
static void replace_tmp_by_const(zend_op_array *op_array,
zend_op *opline,
zend_uint var,
@@ -122,42 +284,7 @@ static void replace_tmp_by_const(zend_op_array *op_array,
if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP1(opline).var == var) {
if (opline->opcode == ZEND_FREE) {
MAKE_NOP(opline);
zval_dtor(val);
} else {
ZEND_OP1_TYPE(opline) = IS_CONST;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (Z_TYPE_P(val) == IS_STRING) {
switch (opline->opcode) {
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_CATCH:
case ZEND_FETCH_CONSTANT:
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1);
break;
case ZEND_DO_FCALL:
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
break;
default:
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
break;
}
} else {
opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
}
#else
ZEND_OP1_LITERAL(opline) = *val;
#endif
}
update_op1_const(op_array, opline, val TSRMLS_CC);
/* TMP_VAR my be used only once */
break;
}
@@ -165,76 +292,8 @@ static void replace_tmp_by_const(zend_op_array *op_array,
if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP2(opline).var == var) {
ZEND_OP2_TYPE(opline) = IS_CONST;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
opline->op2.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
if (Z_TYPE_P(val) == IS_STRING) {
Z_HASH_P(&ZEND_OP2_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1);
switch (opline->opcode) {
case ZEND_FETCH_R:
case ZEND_FETCH_W:
case ZEND_FETCH_RW:
case ZEND_FETCH_IS:
case ZEND_FETCH_UNSET:
case ZEND_FETCH_FUNC_ARG:
case ZEND_FETCH_CLASS:
case ZEND_INIT_FCALL_BY_NAME:
/*case ZEND_INIT_NS_FCALL_BY_NAME:*/
case ZEND_UNSET_VAR:
case ZEND_ISSET_ISEMPTY_VAR:
case ZEND_ADD_INTERFACE:
case ZEND_ADD_TRAIT:
op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++;
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
break;
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
zend_optimizer_add_literal(op_array, val TSRMLS_CC);
op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
/* break missing intentionally */
/*case ZEND_FETCH_CONSTANT:*/
case ZEND_ASSIGN_OBJ:
case ZEND_FETCH_OBJ_R:
case ZEND_FETCH_OBJ_W:
case ZEND_FETCH_OBJ_RW:
case ZEND_FETCH_OBJ_IS:
case ZEND_FETCH_OBJ_UNSET:
case ZEND_FETCH_OBJ_FUNC_ARG:
case ZEND_UNSET_OBJ:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
op_array->last_cache_slot += 2;
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
op_array->last_cache_slot += 2;
}
break;
default:
break;
}
}
#else
ZEND_OP2_LITERAL(opline) = *val;
#endif
update_op2_const(op_array, opline, val TSRMLS_CC);
/* TMP_VAR my be used only once */
break;
}
opline++;
+6
View File
@@ -103,6 +103,12 @@ opcache.revalidate_freq (default "2")
memory storage allocation. ("1" means validate once per second, but only
once per request. "0" means always validate)
opcache.file_update_protection (default "2")
Prevents caching files that are less than this number of seconds old.
It protects from caching of incompletely updated files. In case all file
updates on your site are atomic, you may increase performance setting it
to "0".
opcache.revalidate_path (default "0")
Enables or disables file search in include_path optimization
If the file search is disabled and a cached file is found that uses
+12 -1
View File
@@ -1331,7 +1331,9 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han
}
#endif
if (ZCG(accel_directives).validate_timestamps || ZCG(accel_directives).max_file_size > 0) {
if (ZCG(accel_directives).validate_timestamps ||
ZCG(accel_directives).file_update_protection ||
ZCG(accel_directives).max_file_size > 0) {
size_t size = 0;
/* Obtain the file timestamps, *before* actually compiling them,
@@ -1347,6 +1349,13 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han
return NULL;
}
/* check if file is too new (may be it's not written completely yet) */
if (ZCG(accel_directives).file_update_protection &&
(ZCG(request_time) - ZCG(accel_directives).file_update_protection < timestamp)) {
*op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
return NULL;
}
if (ZCG(accel_directives).max_file_size > 0 && size > (size_t)ZCG(accel_directives).max_file_size) {
ZCSG(blacklist_misses)++;
*op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
@@ -2721,6 +2730,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC)
}
zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled!");
SHM_UNPROTECT();
ZCSG(restart_pending) = 1;
ZCSG(restart_reason) = reason;
ZCSG(cache_status_before_restart) = ZCSG(accelerator_enabled);
@@ -2731,6 +2741,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC)
} else {
ZCSG(force_restart_time) = 0;
}
SHM_PROTECT();
}
/* this is needed because on WIN32 lock is not decreased unless ZCG(counted) is set */
+1
View File
@@ -229,6 +229,7 @@ typedef struct _zend_accel_directives {
zend_bool inherited_hack;
zend_bool enable_cli;
unsigned long revalidate_freq;
unsigned long file_update_protection;
char *error_log;
#ifdef ZEND_WIN32
char *mmap_base;
+22
View File
@@ -0,0 +1,22 @@
--TEST--
Bug #65559 (cache not cleared if changes occur while running)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=2
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$file = __DIR__ . "/bug6559.inc.php";
file_put_contents($file, '<?php return 1;');
$var = include $file;
var_dump($var);
file_put_contents($file, '<?php return 2;');
$var = include $file;
var_dump($var);
@unlink($file);
?>
--EXPECT--
int(1)
int(2)
+26
View File
@@ -0,0 +1,26 @@
--TEST--
Bug #65915 (Inconsistent results with require return value)
--INI--
opcache.enable=1
opcache.enable_cli=1
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$tmp = __DIR__ . "/bug65915.inc.php";
file_put_contents($tmp, '<?php return function(){ return "a";};');
$f = require $tmp;
var_dump($f());
opcache_invalidate($tmp, true);
file_put_contents($tmp, '<?php return function(){ return "b";};');
$f = require $tmp;
var_dump($f());
@unlink($tmp);
?>
--EXPECT--
string(1) "a"
string(1) "b"
+19
View File
@@ -0,0 +1,19 @@
--TEST--
Bug #66176 (Invalid constant substitution)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.file_update_protection=0
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
function foo($v) {
global $a;
return $a[$v];
}
$a = array(PHP_VERSION => 1);
var_dump(foo(PHP_VERSION));
--EXPECT--
int(1)
+2 -1
View File
@@ -259,7 +259,8 @@ ZEND_INI_BEGIN()
STD_PHP_INI_ENTRY("opcache.consistency_checks" , "0" , PHP_INI_ALL , OnUpdateLong, accel_directives.consistency_checks, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.force_restart_timeout" , "180" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.force_restart_timeout, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.revalidate_freq" , "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.revalidate_freq, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.file_update_protection", "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.file_update_protection, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.blacklist_filename" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.user_blacklist_filename, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.max_file_size" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.max_file_size, zend_accel_globals, accel_globals)
+13 -1
View File
@@ -835,7 +835,19 @@ static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_co
}
} else {
if (p->nKeyLength > 0 && p->arKey[0] == 0) {
/* Mangled key, ignore and wait for runtime */
/* Mangled key */
#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
if (((zend_function*)p->pData)->common.fn_flags & ZEND_ACC_CLOSURE) {
/* update closure */
if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) {
if (pCopyConstructor) {
pCopyConstructor(t);
}
}
} else {
/* ignore and wait for runtime */
}
#endif
} else if (!ignore_dups && zend_hash_quick_find(target, p->arKey, p->nKeyLength, p->h, &t) == SUCCESS) {
*fail_data = p->pData;
*conflict_data = t;
+14 -4
View File
@@ -657,18 +657,28 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */
char * thestr;
long gmadjust = 0;
if (timestr->length < 13) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "extension author too lazy to parse %s correctly", timestr->data);
if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal ASN1 data type for timestamp");
return (time_t)-1;
}
strbuf = estrdup((char *)timestr->data);
if (ASN1_STRING_length(timestr) != strlen(ASN1_STRING_data(timestr))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal length in timestamp");
return (time_t)-1;
}
if (ASN1_STRING_length(timestr) < 13) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data);
return (time_t)-1;
}
strbuf = estrdup((char *)ASN1_STRING_data(timestr));
memset(&thetime, 0, sizeof(thetime));
/* we work backwards so that we can use atoi more easily */
thestr = strbuf + timestr->length - 3;
thestr = strbuf + ASN1_STRING_length(timestr) - 3;
thetime.tm_sec = atoi(thestr);
*thestr = '\0';
+29
View File
@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIEpDCCA4ygAwIBAgIJAJzu8r6u6eBcMA0GCSqGSIb3DQEBBQUAMIHDMQswCQYD
VQQGEwJERTEcMBoGA1UECAwTTm9yZHJoZWluLVdlc3RmYWxlbjEQMA4GA1UEBwwH
S8ODwrZsbjEUMBIGA1UECgwLU2VrdGlvbkVpbnMxHzAdBgNVBAsMFk1hbGljaW91
cyBDZXJ0IFNlY3Rpb24xITAfBgNVBAMMGG1hbGljaW91cy5zZWt0aW9uZWlucy5k
ZTEqMCgGCSqGSIb3DQEJARYbc3RlZmFuLmVzc2VyQHNla3Rpb25laW5zLmRlMHUY
ZDE5NzAwMTAxMDAwMDAwWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAXDTE0MTEyODExMzkzNVowgcMxCzAJBgNVBAYTAkRFMRwwGgYDVQQIDBNO
b3JkcmhlaW4tV2VzdGZhbGVuMRAwDgYDVQQHDAdLw4PCtmxuMRQwEgYDVQQKDAtT
ZWt0aW9uRWluczEfMB0GA1UECwwWTWFsaWNpb3VzIENlcnQgU2VjdGlvbjEhMB8G
A1UEAwwYbWFsaWNpb3VzLnNla3Rpb25laW5zLmRlMSowKAYJKoZIhvcNAQkBFhtz
dGVmYW4uZXNzZXJAc2VrdGlvbmVpbnMuZGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDDAf3hl7JY0XcFniyEJpSSDqn0OqBr6QP65usJPRt/8PaDoqBu
wEYT/Na+6fsgPjC0uK9DZgWg2tHWWoanSblAMoz5PH6Z+S4SHRZ7e2dDIjPjdhjh
0mLg2UMO5yp0V797Ggs9lNt6JRfH81MN2obXWs4NtztLMuD6egqpr8dDbr34aOs8
pkdui5UawTZksy5pLPHq5cMhFGm06v65CLo0V2Pd9+KAokPrPcN5KLKebz7mLpk6
SMeEXOKP4idEqxyQ7O7fBuHMedsQhu+prY3si3BUyKfQtP5CZnX2bp0wKHxX12DX
1nfFIt9DbGvHTcyOuN+nZLPBm3vWxntyIIvVAgMBAAGjQjBAMAkGA1UdEwQCMAAw
EQYJYIZIAYb4QgEBBAQDAgeAMAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEF
BQcDAjANBgkqhkiG9w0BAQUFAAOCAQEAG0fZYYCTbdj1XYc+1SnoaPR+vI8C8CaD
8+0UYhdnyU4gga0BAcDrY9e94eEAu6ZqycF6FjLqXXdAboppWocr6T6GD1x33Ckl
VArzG/KxQohGD2JeqkhIMlDomxHO7ka39+Oa8i2vWLVyjU8AZvWMAruHa4EENyG7
lW2AagaFKFCr9TnXTfrdxGVEbv7KVQ6bdhg5p5SjpWH1+Mq03uR3ZXPBYdyV8319
o0lVj1KFI2DCL/liWisJRoof+1cR35Ctd0wYBcpB6TZslMcOPl76dwKwJgeJo2Qg
Zsfmc2vC1/qOlNuNq/0TzzkVGv8ETT3CgaU+UXe4XOVvkccebJn2dg==
-----END CERTIFICATE-----
+18
View File
@@ -0,0 +1,18 @@
--TEST--
CVE-2013-6420
--SKIPIF--
<?php
if (!extension_loaded("openssl")) die("skip");
?>
--FILE--
<?php
$crt = substr(__FILE__, 0, -4).'.crt';
$info = openssl_x509_parse("file://$crt");
var_dump($info['issuer']['emailAddress'], $info["validFrom_time_t"]);
?>
Done
--EXPECTF--
%s openssl_x509_parse(): illegal ASN1 data type for timestamp in %s/cve-2013-6420.php on line 3
string(27) "stefan.esser@sektioneins.de"
int(-1)
Done
+38
View File
@@ -0,0 +1,38 @@
--TEST--
Bug #66141 (mysqlnd quote function is wrong with NO_BACKSLASH_ESCAPES after failed query)
--SKIPIF--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
MySQLPDOTest::skip();
?>
--FILE--
<?php
include __DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
$input = 'Something\', 1 as one, 2 as two FROM dual; -- f';
$quotedInput0 = $db->quote($input);
$db->query('set session sql_mode="NO_BACKSLASH_ESCAPES"');
// injection text from some user input
$quotedInput1 = $db->quote($input);
$db->query('something that throws an exception');
$quotedInput2 = $db->quote($input);
var_dump($quotedInput0);
var_dump($quotedInput1);
var_dump($quotedInput2);
?>
done
--EXPECTF--
Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'something that throws an exception' at line %d in %s on line %d
string(50) "'Something\', 1 as one, 2 as two FROM dual; -- f'"
string(50) "'Something'', 1 as one, 2 as two FROM dual; -- f'"
string(50) "'Something'', 1 as one, 2 as two FROM dual; -- f'"
done
+4 -1
View File
@@ -170,7 +170,10 @@ ZEND_GET_MODULE(readline)
PHP_MINIT_FUNCTION(readline)
{
using_history();
#if HAVE_LIBREADLINE
/* libedit don't need this call which set the tty in cooked mode */
using_history();
#endif
return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
}
+1 -1
View File
@@ -5776,7 +5776,7 @@ PHP_FUNCTION(unregister_tick_function)
return;
}
if (Z_TYPE_P(function) != IS_ARRAY) {
if (Z_TYPE_P(function) != IS_ARRAY && Z_TYPE_P(function) != IS_OBJECT) {
convert_to_string(function);
}
@@ -0,0 +1,12 @@
--TEST--
Bug #66094 (unregister_tick_function tries to cast a Closure to a string)
--FILE--
<?php
declare(ticks=1);
register_tick_function($closure = function () { echo "Tick!\n"; });
unregister_tick_function($closure);
echo "done";
?>
--EXPECTF--
Tick!
done
@@ -1,7 +1,7 @@
--TEST--
Test var_export() function with locale
--INI--
precision=14
serialize_precision=17
--SKIPIF--
<?php
if (!setlocale(LC_ALL, "german", "de","de_DE","de_DE.ISO8859-1","de_DE.ISO_8859-1","de_DE.UTF-8")) {
@@ -1,7 +1,7 @@
--TEST--
Test var_export() function with valid float values
--INI--
precision=14
serialize_precision=17
--FILE--
<?php
/* Prototype : mixed var_export(mixed var [, bool return])
@@ -1,5 +1,7 @@
--TEST--
Test var_export() function with valid arrays
--INI--
serialize_precision=17
--FILE--
<?php
/* Prototype : mixed var_export(mixed var [, bool return])
@@ -0,0 +1,52 @@
--TEST--
Test unserialize(): error is indistinguishable from deserialized boolean
--FILE--
<?php
/* Prototype : proto string serialize(mixed variable)
* Description: Returns a string representation of variable (which can later be unserialized)
* Source code: ext/standard/var.c
* Alias to functions:
*/
/* Prototype : proto mixed unserialize(string variable_representation)
* Description: Takes a string representation of variable and recreates it
* Source code: ext/standard/var.c
* Alias to functions:
*/
echo "*** Testing unserialize() error/boolean distinction ***\n";
$garbage = "obvious non-serialized data";
$serialized_false = serialize(false);
var_dump($serialized_false);
$deserialized_garbage = unserialize($garbage);
var_dump($deserialized_garbage);
$deserialized_false = unserialize($serialized_false);
var_dump($deserialized_false);
echo "unserialize error and deserialized false are identical? " . (bool) ($deserialized_false == $deserialized_garbage) . "\n";
// candidate safe idiom for determining whether data is serialized
function isSerialized($str) {
return ($str == serialize(false) || @unserialize($str) !== false);
}
// Test unserialize error idiom
var_dump(isSerialized($garbage));
var_dump(isSerialized($serialized_false));
echo "Done";
?>
--EXPECTF--
*** Testing unserialize() error/boolean distinction ***
string(4) "b:0;"
Notice: unserialize(): Error at offset 0 of 27 bytes in %s%eserialization_error_002.php on line 20
bool(false)
bool(false)
unserialize error and deserialized false are identical? 1
bool(false)
bool(true)
Done
+2 -2
View File
@@ -24,7 +24,7 @@ $input = "10:00:00 AM July 2 1963";
$tstamp = strtotime($input);
$str = strftime("%r %B%e %Y %Z", $tstamp);
var_dump(strptime($str, '%H:%M:%S %p %B %d %Y %Z'));
var_dump(strptime($str, '%H:%M:%S %p %B %d %Y'));
$str = strftime("%T %D", $tstamp);
var_dump(strptime($str, '%H:%M:%S %m/%d/%y'));
@@ -55,7 +55,7 @@ array(9) {
["tm_yday"]=>
int(182)
["unparsed"]=>
string(3) "GMT"
string(4) " GMT"
}
array(9) {
["tm_sec"]=>
+4 -4
View File
@@ -2,7 +2,7 @@
/* edit configure.in to change version number */
#define PHP_MAJOR_VERSION 5
#define PHP_MINOR_VERSION 5
#define PHP_RELEASE_VERSION 6
#define PHP_EXTRA_VERSION "-dev"
#define PHP_VERSION "5.5.6-dev"
#define PHP_VERSION_ID 50506
#define PHP_RELEASE_VERSION 7
#define PHP_EXTRA_VERSION ""
#define PHP_VERSION "5.5.7"
#define PHP_VERSION_ID 50507
+2
View File
@@ -241,6 +241,7 @@ $ini_overwrites = array(
'precision=14',
'memory_limit=128M',
'opcache.fast_shutdown=0',
'opcache.file_update_protection=0',
);
function write_information($show_html)
@@ -1090,6 +1091,7 @@ function system_with_timeout($commandline, $env = null, $stdin = null)
fwrite($pipes[0], $stdin);
}
fclose($pipes[0]);
unset($pipes[0]);
$timeout = $leak_check ? 300 : (isset($env['TEST_TIMEOUT']) ? $env['TEST_TIMEOUT'] : 60);
+2 -2
View File
@@ -1688,8 +1688,8 @@ static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS
PHP_FUNCTION(apache_response_headers) /* {{{ */
{
if (ZEND_NUM_ARGS() > 0) {
WRONG_PARAM_COUNT;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!&SG(sapi_headers).headers) {
+115
View File
@@ -133,6 +133,7 @@ typedef struct php_cli_server_request {
char *query_string;
size_t query_string_len;
HashTable headers;
HashTable headers_original_case;
char *content;
size_t content_len;
const char *ext;
@@ -275,6 +276,42 @@ static php_cli_server_ext_mime_type_pair mime_type_map[] = {
{ "webm", "video/webm" },
{ "ogv", "video/ogg" },
{ "ogg", "audio/ogg" },
{ "3gp", "video/3gpp" }, /* This is standard video format used for MMS in phones */
{ "apk", "application/vnd.android.package-archive" },
{ "avi", "video/x-msvideo" },
{ "bmp", "image/x-ms-bmp" },
{ "csv", "text/comma-separated-values" },
{ "doc", "application/msword" },
{ "docx", "application/msword" },
{ "flac", "audio/flac" },
{ "gz", "application/x-gzip" },
{ "gzip", "application/x-gzip" },
{ "ics", "text/calendar" },
{ "kml", "application/vnd.google-earth.kml+xml" },
{ "kmz", "application/vnd.google-earth.kmz" },
{ "m4a", "audio/mp4" },
{ "mp3", "audio/mpeg" },
{ "mp4", "video/mp4" },
{ "mpg", "video/mpeg" },
{ "mpeg", "video/mpeg" },
{ "mov", "video/quicktime" },
{ "odp", "application/vnd.oasis.opendocument.presentation" },
{ "ods", "application/vnd.oasis.opendocument.spreadsheet" },
{ "odt", "application/vnd.oasis.opendocument.text" },
{ "oga", "audio/ogg" },
{ "pdf", "application/pdf" },
{ "pptx", "application/vnd.ms-powerpoint" },
{ "pps", "application/vnd.ms-powerpoint" },
{ "qt", "video/quicktime" },
{ "swf", "application/x-shockwave-flash" },
{ "tar", "application/x-tar" },
{ "text", "text/plain" },
{ "tif", "image/tiff" },
{ "wav", "audio/wav" },
{ "wmv", "video/x-ms-wmv" },
{ "xls", "application/vnd.ms-excel" },
{ "xlsx", "application/vnd.ms-excel" },
{ "zip", "application/x-zip-compressed" },
{ NULL, NULL }
};
@@ -435,6 +472,75 @@ static const char *get_mime_type(const char *ext, size_t ext_len) /* {{{ */
return NULL;
} /* }}} */
PHP_FUNCTION(apache_request_headers) /* {{{ */
{
php_cli_server_client *client;
HashTable *headers;
char *key;
uint key_len;
char **value_pointer;
HashPosition pos;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
client = SG(server_context);
headers = &client->request.headers_original_case;
array_init_size(return_value, zend_hash_num_elements(headers));
zend_hash_internal_pointer_reset_ex(headers, &pos);
while (zend_hash_get_current_data_ex(headers, (void **)&value_pointer, &pos) == SUCCESS) {
zend_hash_get_current_key_ex(headers, &key, &key_len, NULL, 0, &pos);
add_assoc_string_ex(return_value, key, key_len, *value_pointer, 1);
zend_hash_move_forward_ex(headers, &pos);
}
}
/* }}} */
static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS_DC) /* {{{ */
{
char *s, *p;
int len;
ALLOCA_FLAG(use_heap)
if (h->header_len > 0) {
p = strchr(h->header, ':');
len = p - h->header;
if (p && (len > 0)) {
while (len > 0 && (h->header[len-1] == ' ' || h->header[len-1] == '\t')) {
len--;
}
if (len) {
s = do_alloca(len + 1, use_heap);
memcpy(s, h->header, len);
s[len] = 0;
do {
p++;
} while (*p == ' ' || *p == '\t');
add_assoc_stringl_ex(return_value, s, len+1, p, h->header_len - (p - h->header), 1);
free_alloca(s, use_heap);
}
}
}
}
/* }}} */
PHP_FUNCTION(apache_response_headers) /* {{{ */
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (!&SG(sapi_headers).headers) {
RETURN_FALSE;
}
array_init(return_value);
zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t)add_response_header, return_value TSRMLS_CC);
}
/* }}} */
/* {{{ cli_server module
*/
@@ -479,9 +585,15 @@ zend_module_entry cli_server_module_entry = {
};
/* }}} */
ZEND_BEGIN_ARG_INFO(arginfo_no_args, 0)
ZEND_END_ARG_INFO()
const zend_function_entry server_additional_functions[] = {
PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
PHP_FE(cli_get_process_title, arginfo_cli_get_process_title)
PHP_FE(apache_request_headers, arginfo_no_args)
PHP_FE(apache_response_headers, arginfo_no_args)
PHP_FALIAS(getallheaders, apache_request_headers, arginfo_no_args)
{NULL, NULL, NULL}
};
@@ -1300,6 +1412,7 @@ static int php_cli_server_request_ctor(php_cli_server_request *req) /* {{{ */
req->query_string = NULL;
req->query_string_len = 0;
zend_hash_init(&req->headers, 0, NULL, (void(*)(void*))char_ptr_dtor_p, 1);
zend_hash_init(&req->headers_original_case, 0, NULL, NULL, 1);
req->content = NULL;
req->content_len = 0;
req->ext = NULL;
@@ -1325,6 +1438,7 @@ static void php_cli_server_request_dtor(php_cli_server_request *req) /* {{{ */
pefree(req->query_string, 1);
}
zend_hash_destroy(&req->headers);
zend_hash_destroy(&req->headers_original_case);
if (req->content) {
pefree(req->content, 1);
}
@@ -1569,6 +1683,7 @@ static int php_cli_server_client_read_request_on_header_value(php_http_parser *p
{
char *header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len);
zend_hash_add(&client->request.headers, header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
zend_hash_add(&client->request.headers_original_case, client->current_header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
efree(header_name);
}
+68
View File
@@ -0,0 +1,68 @@
--TEST--
Implement Req #65917 (getallheaders() is not supported by the built-in web server)
--SKIPIF--
<?php
include "skipif.inc";
?>
--FILE--
<?php
include "php_cli_server.inc";
php_cli_server_start(<<<'PHP'
header('Bar-Foo: Foo');
var_dump(getallheaders());
var_dump(apache_request_headers());
var_dump(apache_response_headers());
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
GET / HTTP/1.1
Host: {$host}
Foo-Bar: Bar
HEADER
)) {
while (!feof($fp)) {
echo fgets($fp);
}
}
fclose($fp);
?>
--EXPECTF--
HTTP/1.1 200 OK
Host: %s
Connection: close
X-Powered-By: %s
Bar-Foo: Foo
Content-type: text/html
array(2) {
["Host"]=>
string(9) "localhost"
["Foo-Bar"]=>
string(3) "Bar"
}
array(2) {
["Host"]=>
string(9) "localhost"
["Foo-Bar"]=>
string(3) "Bar"
}
array(3) {
["X-Powered-By"]=>
string(%d) "P%s"
["Bar-Foo"]=>
string(3) "Foo"
["Content-type"]=>
string(9) "text/html"
}
+1
View File
@@ -2,6 +2,7 @@
Bug #24640 (var_export and var_dump can't output large float)
--INI--
precision=12
serialize_precision=17
--FILE--
<?php
function test($v)