Merge branch 'master' into assert

* master:
  Implemented AST pretty-printer
  update NEWS to match the actual stuff in 5.6.6
  update NEWS to match the actual stuff in 5.5.22
  update NEWS(add missing entry for the enchant fix, and reorder the entries a bit)
  fix typo in bug#
  update NEWS
  fix email format
  update NEWS
  update 5.6.6 release date in NEWS
  Fix bug #69033 (Request may get env. variables from previous requests if PHP works as FastCGI)
  BFN
  fix test
  fix test
  fix test
  Fixed bug #65593 (Segfault when calling ob_start from output buffering callback)
  Updated NEWS
  add CVE
  5.4.39 next
  Fix associativity to match Perl
  Blast off to space.

Conflicts:
	Zend/zend_ast.c
This commit is contained in:
Dmitry Stogov 2015-02-19 11:13:08 +03:00
commit 49963ebf9d
14 changed files with 3514 additions and 3192 deletions

View file

@ -467,7 +467,7 @@ ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn) {
* 150 left ^
* 160 left &
* 170 non-associative == != === !==
* 180 non-associative < <= > >=
* 180 non-associative < <= > >= <=>
* 190 left << >>
* 200 left + - .
* 210 left * / %
@ -1252,6 +1252,7 @@ simple_list:
case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ", 180, 181, 181);
case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250);
case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41);
case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181);
EMPTY_SWITCH_DEFAULT_CASE();
}
break;

View file

@ -75,7 +75,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%left '|'
%left '^'
%left '&'
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP
%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
%left T_SL T_SR
%left '+' '-' '.'
@ -131,6 +131,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%token T_IS_NOT_IDENTICAL "!== (T_IS_NOT_IDENTICAL)"
%token T_IS_SMALLER_OR_EQUAL "<= (T_IS_SMALLER_OR_EQUAL)"
%token T_IS_GREATER_OR_EQUAL ">= (T_IS_GREATER_OR_EQUAL)"
%token T_SPACESHIP "<=> (T_SPACESHIP)"
%token T_SL "<< (T_SL)"
%token T_SR ">> (T_SR)"
%token T_INSTANCEOF "instanceof (T_INSTANCEOF)"
@ -846,6 +847,8 @@ expr_without_variable:
{ $$ = zend_ast_create(ZEND_AST_GREATER, $1, $3); }
| expr T_IS_GREATER_OR_EQUAL expr
{ $$ = zend_ast_create(ZEND_AST_GREATER_EQUAL, $1, $3); }
| expr T_SPACESHIP expr
{ $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); }
| expr T_INSTANCEOF class_name_reference
{ $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); }
| '(' expr ')' { $$ = $2; }

File diff suppressed because it is too large Load diff

View file

@ -1453,6 +1453,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_IS_NOT_EQUAL;
}
<ST_IN_SCRIPTING>"<=>" {
return T_SPACESHIP;
}
<ST_IN_SCRIPTING>"<=" {
return T_IS_SMALLER_OR_EQUAL;
}

View file

@ -1,4 +1,4 @@
/* Generated by re2c 0.13.5 */
/* Generated by re2c 0.13.7.5 */
#line 3 "Zend/zend_language_scanner_defs.h"
enum YYCONDTYPE {

View file

@ -864,6 +864,8 @@ ZEND_API binary_op_type get_binary_op(int opcode)
return (binary_op_type) is_smaller_function;
case ZEND_IS_SMALLER_OR_EQUAL:
return (binary_op_type) is_smaller_or_equal_function;
case ZEND_SPACESHIP:
return (binary_op_type) compare_function;
case ZEND_BW_OR:
case ZEND_ASSIGN_BW_OR:
return (binary_op_type) bitwise_or_function;

View file

@ -240,6 +240,22 @@ ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R));
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE

View file

@ -3791,6 +3791,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
EX_CONSTANT(opline->op1),
EX_CONSTANT(opline->op2));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -6890,6 +6906,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OP
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
EX_CONSTANT(opline->op1),
_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -8026,6 +8058,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op2;
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
EX_CONSTANT(opline->op1),
_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -25127,6 +25175,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OP
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
EX_CONSTANT(opline->op2));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -29496,6 +29560,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCOD
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -31528,6 +31608,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_O
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op2;
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -33905,6 +34001,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1;
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
EX_CONSTANT(opline->op2));
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -35714,6 +35826,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_O
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1;
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -36356,6 +36484,22 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZE
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
zval *result = EX_VAR(opline->result.var);
SAVE_OPLINE();
compare_function(result,
_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -41079,6 +41223,31 @@ void zend_init_opcodes_handlers(void)
ZEND_COALESCE_SPEC_CV_HANDLER,
ZEND_COALESCE_SPEC_CV_HANDLER,
ZEND_COALESCE_SPEC_CV_HANDLER,
ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER,
ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER,
ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER,
ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER,
ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_SPACESHIP_SPEC_CV_CV_HANDLER,
ZEND_NULL_HANDLER
};
zend_opcode_handlers = (opcode_handler_t*)labels;

View file

@ -21,7 +21,7 @@
#include <stdio.h>
#include <zend.h>
const char *zend_vm_opcodes_map[170] = {
const char *zend_vm_opcodes_map[171] = {
"ZEND_NOP",
"ZEND_ADD",
"ZEND_SUB",
@ -192,6 +192,7 @@ const char *zend_vm_opcodes_map[170] = {
"ZEND_ASSIGN_POW",
"ZEND_BIND_GLOBAL",
"ZEND_COALESCE",
"ZEND_SPACESHIP",
};
ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {

View file

@ -186,5 +186,6 @@ END_EXTERN_C()
#define ZEND_ASSIGN_POW 167
#define ZEND_BIND_GLOBAL 168
#define ZEND_COALESCE 169
#define ZEND_SPACESHIP 170
#endif

View file

@ -3391,6 +3391,9 @@ static void php_putenv_destructor(zval *zv) /* {{{ */
unsetenv(pe->key);
# elif defined(PHP_WIN32)
SetEnvironmentVariable(pe->key, NULL);
# ifndef ZTS
_putenv_s(pe->key, "");
# endif
# else
char **env;

View file

@ -179,21 +179,21 @@ PHPAPI void php_output_deactivate(void)
{
php_output_handler **handler = NULL;
php_output_header();
if ((OG(flags) & PHP_OUTPUT_ACTIVATED)) {
OG(flags) ^= PHP_OUTPUT_ACTIVATED;
OG(active) = NULL;
OG(running) = NULL;
OG(flags) ^= PHP_OUTPUT_ACTIVATED;
OG(active) = NULL;
OG(running) = NULL;
/* release all output handlers */
if (OG(handlers).elements) {
while ((handler = zend_stack_top(&OG(handlers)))) {
php_output_handler_free(handler);
zend_stack_del_top(&OG(handlers));
/* release all output handlers */
if (OG(handlers).elements) {
while ((handler = zend_stack_top(&OG(handlers)))) {
php_output_handler_free(handler);
zend_stack_del_top(&OG(handlers));
}
}
zend_stack_destroy(&OG(handlers));
}
}
/* }}} */

View file

@ -0,0 +1,94 @@
--TEST--
Test <=> operator : different types
--FILE--
<?php
$valid_true = array(1, "1", "true", 1.0, array(1));
$valid_false = array(0, "", 0.0, array(), NULL);
$int1 = 679;
$int2 = -67835;
$valid_int1 = array("678", "678abc", " 678", "678 ", 678.0, 6.789E2, "+678", +678);
$valid_int2 = array("-67836", "-67836abc", " -67836", "-67836 ", -67835.0001, -6.78351E4);
$invalid_int1 = array(679, "679");
$invalid_int2 = array(-67835, "-67835");
$float1 = 57385.45835;
$float2 = -67345.76567;
$valid_float1 = array("57385.45834", "57385.45834aaa", " 57385.45834", 5.738545834e4);
$valid_float2 = array("-67345.76568", "-67345.76568aaa", " -67345.76568", -6.734576568E4);
$invalid_float1 = array(57385.45835, 5.738545835e4);
$invalid_float2 = array(-67345.76567, -6.734576567E4);
$toCompare = array(
// boolean test will result in both sides being converted to boolean so !0 = true and true is not > true for example
// also note that a string of "0" is converted to false but a string of "0.0" is converted to true
// false cannot be tested as 0 can never be > 0 or 1
true, $valid_false, $valid_true,
$int1, $valid_int1, $invalid_int1,
$int2, $valid_int2, $invalid_int2,
$float1, $valid_float1, $invalid_float1,
$float2, $valid_float2, $invalid_float2
);
$failed = false;
for ($i = 0; $i < count($toCompare); $i +=3) {
$typeToTest = $toCompare[$i];
$valid_compares = $toCompare[$i + 1];
$invalid_compares = $toCompare[$i + 2];
foreach($valid_compares as $compareVal) {
if (($typeToTest <=> $compareVal) === 1) {
// do nothing
}
else {
echo "FAILED: ('$typeToTest' <=> '$compareVal') !== 1\n";
$failed = true;
}
if (($compareVal <=> $typeToTest) === -1) {
// do nothing
}
else {
echo "FAILED: ('$compareVal' <=> '$typeToTest') !== -1\n";
$failed = true;
}
if (($compareVal <=> $compareVal) === 0) {
// do nothing
}
else {
echo "FAILED: ('$compareVal' <=> '$compareVal') !== 0\n";
$failed = true;
}
}
foreach($invalid_compares as $compareVal) {
if (($typeToTest <=> $compareVal) === 1) {
echo "FAILED: ('$typeToTest' <=> '$compareVal') === 1\n";
$failed = true;
}
if (($compareVal <=> $typeToTest) === -1) {
echo "FAILED: ('$compareVal' <=> '$typeToTest') === -1\n";
$failed = true;
}
if (($compareVal <=> $compareVal) !== 0) {
echo "FAILED: ('$compareVal' <=> '$compareVal') !== 0\n";
$failed = true;
}
}
if (($typeToTest <=> $typeToTest) === 0) {
// do nothing
}
else {
echo "FAILED: ('$typeToTest' <=> '$typeToTest') !== 0\n";
$failed = true;
}
}
if ($failed == false) {
echo "Test Passed\n";
}
?>
===DONE===
--EXPECT--
Test Passed
===DONE===

View file

@ -0,0 +1,13 @@
--TEST--
Bug #65593 (ob_start(function(){ob_start();});)
--FILE--
<?php
echo "Test\n";
ob_start(function(){ob_start();});
?>
===DONE===
--EXPECTF--
Test
Fatal error: Cannot destroy active lambda function in %sbug65593.php on line %d