Merge branch 'master' into merge-fastcgi

This commit is contained in:
Xinchen Hui 2015-05-26 14:17:21 +08:00
commit 49b10ee264
79 changed files with 3091 additions and 1150 deletions

3
NEWS
View file

@ -77,7 +77,8 @@
. Implemented the RFC `Constructor behaviour of internal classes`. (Dan, Dmitry)
. Implemented the RFC `Fix "foreach" behavior`. (Dmitry)
. Implemented the RFC `Generator Delegation`. (Bob)
. Implemented the RFC ` Anonymous Class Support`. (Joe, Nikita, Dmitry)
. Implemented the RFC `Anonymous Class Support`. (Joe, Nikita, Dmitry)
. Implemented the RFC `Context Sensitive Lexer`. (Marcio Almada)
. Fixed bug #69511 (Off-by-one buffer overflow in php_sys_readlink).
(Jan Starke, Anatol)

View file

@ -530,6 +530,8 @@ Other
(RFC: https://wiki.php.net/rfc/combined-comparison-operator)
. Added the yield from operator for delegating Generators like coroutines.
(RFC: https://wiki.php.net/rfc/generator-delegation)
. Reserved keywords can now be used in various new contexts.
(RFC: https://wiki.php.net/rfc/context_sensitive_lexer)
- OpenSSL
. Added "alpn_protocols" SSL context option allowing encrypted client/server

View file

@ -0,0 +1,33 @@
--TEST--
Test to check static method calls syntax regression
--FILE--
<?php
class Foo {
public static function function(){ echo __METHOD__, PHP_EOL; }
}
Foo::function();
Foo::
function();
Foo::
function();
Foo::
function(
);
echo "\nDone\n";
--EXPECTF--
Foo::function
Foo::function
Foo::function
Foo::function
Done

View file

@ -0,0 +1,22 @@
--TEST--
Test to ensure ::class still works
--FILE--
<?php
class Foo {}
var_dump(Foo::class);
var_dump(Foo:: class);
var_dump(Foo:: CLASS);
var_dump(Foo::
CLASS);
--EXPECTF--
string(3) "Foo"
string(3) "Foo"
string(3) "Foo"
string(3) "Foo"

View file

@ -0,0 +1,13 @@
--TEST--
Test to ensure ::class is still reserved in obj scope
--FILE--
<?php
class Obj
{
const CLASS = 'class';
}
?>
--EXPECTF--
Fatal error: A class constant must not be called 'class'; it is reserved for class name fetching in %s on line %d

View file

@ -0,0 +1,15 @@
--TEST--
Test possible function naming regression on procedural scope
--FILE--
<?php
class Obj
{
function echo(){} // valid
function return(){} // valid
}
function echo(){} // not valid
--EXPECTF--
Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting identifier (T_STRING) or '(' in %s on line 9

View file

@ -0,0 +1,14 @@
--TEST--
Test possible constant naming regression on procedural scope
--FILE--
<?php
class Obj
{
const return = 'yep';
}
const return = 'nope';
--EXPECTF--
Parse error: syntax error, unexpected 'return' (T_RETURN), expecting identifier (T_STRING) in %s on line 8

View file

@ -0,0 +1,30 @@
--TEST--
Test to ensure const list syntax declaration works
--FILE--
<?php
class Obj
{
const DECLARE = 'declare',
RETURN = 'return',
FUNCTION = 'function',
USE = 'use';
}
echo Obj::DECLARE, PHP_EOL;
echo Obj::RETURN, PHP_EOL;
echo Obj::FUNCTION, PHP_EOL;
echo Obj::USE, PHP_EOL;
echo Obj::
USE, PHP_EOL;
echo "\nDone\n";
--EXPECTF--
declare
return
function
use
use
Done

View file

@ -0,0 +1,44 @@
--TEST--
Test to ensure semi reserved words allow deference
--FILE--
<?php
class Foo {
const use = 'yay';
public static function new() {
echo __METHOD__, PHP_EOL;
return new static();
}
public function self() {
echo __METHOD__, PHP_EOL;
return $this;
}
}
Foo::new()::new()::new();
var_dump(
(new Foo)->self()::new()->self()->self()::use
);
Foo::{'new'}();
var_dump(Foo::use);
echo "\nDone\n";
--EXPECTF--
Foo::new
Foo::new
Foo::new
Foo::self
Foo::new
Foo::self
Foo::self
string(3) "yay"
Foo::new
string(3) "yay"
Done

View file

@ -0,0 +1,21 @@
--TEST--
Test to check regressions on string interpolation with class members access
--FILE--
<?php
class Friday {
public $require = "fun";
}
$friday = new Friday;
echo "$friday->require ($friday->require) {$friday->require}", PHP_EOL;
echo "\nDone\n";
--EXPECTF--
fun (fun) fun
Done

View file

@ -0,0 +1,18 @@
--TEST--
Test to check regressions on use statements and lexer state
--FILE--
<?php
use A\B\C\D;
class Foo
{
private static $foo;
}
echo PHP_EOL, "Done", PHP_EOL;
--EXPECTF--
Done

View file

@ -0,0 +1,14 @@
--TEST--
Test to check regressions on T_IMPLEMENTS followed by a T_NS_SEPARATOR
--FILE--
<?php
interface A{}
class B implements\A {}
echo "Done", PHP_EOL;
--EXPECTF--
Done

View file

@ -0,0 +1,18 @@
--TEST--
Testing instantiation using namespace:: prefix
--FILE--
<?php
namespace foo;
class bar {
}
class_alias('foo\bar', 'foo\baz');
var_dump(new namespace\baz);
?>
--EXPECTF--
object(foo\bar)#%d (0) {
}

View file

@ -0,0 +1,13 @@
--TEST--
Testing for regression on const list syntax and arrays
--FILE--
<?php
class A {
const A = [1, FOREACH];
}
?>
--EXPECTF--
Parse error: syntax error, unexpected 'FOREACH' (T_FOREACH), expecting ']' in %s on line %d

View file

@ -0,0 +1,13 @@
--TEST--
Testing for regression with encapsed variables in class declaration context
--FILE--
<?php
class A { function foo() { "{${$a}}"; } function list() {} }
echo "Done", PHP_EOL;
?>
--EXPECTF--
Done

View file

@ -0,0 +1,209 @@
--TEST--
Test semi-reserved words as class methods
--FILE--
<?php
class Obj
{
function empty(){ echo __METHOD__, PHP_EOL; }
function callable(){ echo __METHOD__, PHP_EOL; }
function trait(){ echo __METHOD__, PHP_EOL; }
function extends(){ echo __METHOD__, PHP_EOL; }
function implements(){ echo __METHOD__, PHP_EOL; }
function const(){ echo __METHOD__, PHP_EOL; }
function enddeclare(){ echo __METHOD__, PHP_EOL; }
function endfor(){ echo __METHOD__, PHP_EOL; }
function endforeach(){ echo __METHOD__, PHP_EOL; }
function endif(){ echo __METHOD__, PHP_EOL; }
function endwhile(){ echo __METHOD__, PHP_EOL; }
function and(){ echo __METHOD__, PHP_EOL; }
function global(){ echo __METHOD__, PHP_EOL; }
function goto(){ echo __METHOD__, PHP_EOL; }
function instanceof(){ echo __METHOD__, PHP_EOL; }
function insteadof(){ echo __METHOD__, PHP_EOL; }
function interface(){ echo __METHOD__, PHP_EOL; }
function new(){ echo __METHOD__, PHP_EOL; }
function or(){ echo __METHOD__, PHP_EOL; }
function xor(){ echo __METHOD__, PHP_EOL; }
function try(){ echo __METHOD__, PHP_EOL; }
function use(){ echo __METHOD__, PHP_EOL; }
function var(){ echo __METHOD__, PHP_EOL; }
function exit(){ echo __METHOD__, PHP_EOL; }
function list(){ echo __METHOD__, PHP_EOL; }
function clone(){ echo __METHOD__, PHP_EOL; }
function include(){ echo __METHOD__, PHP_EOL; }
function include_once(){ echo __METHOD__, PHP_EOL; }
function throw(){ echo __METHOD__, PHP_EOL; }
function array(){ echo __METHOD__, PHP_EOL; }
function print(){ echo __METHOD__, PHP_EOL; }
function echo(){ echo __METHOD__, PHP_EOL; }
function require(){ echo __METHOD__, PHP_EOL; }
function require_once(){ echo __METHOD__, PHP_EOL; }
function return(){ echo __METHOD__, PHP_EOL; }
function else(){ echo __METHOD__, PHP_EOL; }
function elseif(){ echo __METHOD__, PHP_EOL; }
function default(){ echo __METHOD__, PHP_EOL; }
function break(){ echo __METHOD__, PHP_EOL; }
function continue(){ echo __METHOD__, PHP_EOL; }
function switch(){ echo __METHOD__, PHP_EOL; }
function yield(){ echo __METHOD__, PHP_EOL; }
function function(){ echo __METHOD__, PHP_EOL; }
function if(){ echo __METHOD__, PHP_EOL; }
function endswitch(){ echo __METHOD__, PHP_EOL; }
function finally(){ echo __METHOD__, PHP_EOL; }
function for(){ echo __METHOD__, PHP_EOL; }
function foreach(){ echo __METHOD__, PHP_EOL; }
function declare(){ echo __METHOD__, PHP_EOL; }
function case(){ echo __METHOD__, PHP_EOL; }
function do(){ echo __METHOD__, PHP_EOL; }
function while(){ echo __METHOD__, PHP_EOL; }
function as(){ echo __METHOD__, PHP_EOL; }
function catch(){ echo __METHOD__, PHP_EOL; }
function die(){ echo __METHOD__, PHP_EOL; }
function self(){ echo __METHOD__, PHP_EOL; }
function parent(){ echo __METHOD__, PHP_EOL; }
function public(){ echo __METHOD__, PHP_EOL; }
function protected(){ echo __METHOD__, PHP_EOL; }
function private(){ echo __METHOD__, PHP_EOL; }
function static(){ echo __METHOD__, PHP_EOL; }
function abstract(){ echo __METHOD__, PHP_EOL; }
function final(){ echo __METHOD__, PHP_EOL; }
function class(){ echo __METHOD__, PHP_EOL; }
}
$obj = new Obj;
$obj->empty();
$obj->callable();
$obj->trait();
$obj->extends();
$obj->implements();
$obj->const();
$obj->enddeclare();
$obj->endfor();
$obj->endforeach();
$obj->endif();
$obj->endwhile();
$obj->and();
$obj->global();
$obj->goto();
$obj->instanceof();
$obj->insteadof();
$obj->interface();
$obj->new();
$obj->or();
$obj->xor();
$obj->try();
$obj->use();
$obj->var();
$obj->exit();
$obj->list();
$obj->clone();
$obj->include();
$obj->include_once();
$obj->throw();
$obj->array();
$obj->print();
$obj->echo();
$obj->require();
$obj->require_once();
$obj->return();
$obj->else();
$obj->elseif();
$obj->default();
$obj->break();
$obj->continue();
$obj->switch();
$obj->yield();
$obj->function();
$obj->if();
$obj->endswitch();
$obj->finally();
$obj->for();
$obj->foreach();
$obj->declare();
$obj->case();
$obj->do();
$obj->while();
$obj->as();
$obj->catch();
$obj->die();
$obj->self();
$obj->parent();
$obj->public();
$obj->protected();
$obj->private();
$obj->static();
$obj->abstract();
$obj->final();
$obj->class();
echo "\nDone\n";
--EXPECTF--
Obj::empty
Obj::callable
Obj::trait
Obj::extends
Obj::implements
Obj::const
Obj::enddeclare
Obj::endfor
Obj::endforeach
Obj::endif
Obj::endwhile
Obj::and
Obj::global
Obj::goto
Obj::instanceof
Obj::insteadof
Obj::interface
Obj::new
Obj::or
Obj::xor
Obj::try
Obj::use
Obj::var
Obj::exit
Obj::list
Obj::clone
Obj::include
Obj::include_once
Obj::throw
Obj::array
Obj::print
Obj::echo
Obj::require
Obj::require_once
Obj::return
Obj::else
Obj::elseif
Obj::default
Obj::break
Obj::continue
Obj::switch
Obj::yield
Obj::function
Obj::if
Obj::endswitch
Obj::finally
Obj::for
Obj::foreach
Obj::declare
Obj::case
Obj::do
Obj::while
Obj::as
Obj::catch
Obj::die
Obj::self
Obj::parent
Obj::public
Obj::protected
Obj::private
Obj::static
Obj::abstract
Obj::final
Obj::class
Done

View file

@ -0,0 +1,207 @@
--TEST--
Test semi-reserved words as static class methods
--FILE--
<?php
class Obj
{
static function empty(){ echo __METHOD__, PHP_EOL; }
static function callable(){ echo __METHOD__, PHP_EOL; }
static function trait(){ echo __METHOD__, PHP_EOL; }
static function extends(){ echo __METHOD__, PHP_EOL; }
static function implements(){ echo __METHOD__, PHP_EOL; }
static function const(){ echo __METHOD__, PHP_EOL; }
static function enddeclare(){ echo __METHOD__, PHP_EOL; }
static function endfor(){ echo __METHOD__, PHP_EOL; }
static function endforeach(){ echo __METHOD__, PHP_EOL; }
static function endif(){ echo __METHOD__, PHP_EOL; }
static function endwhile(){ echo __METHOD__, PHP_EOL; }
static function and(){ echo __METHOD__, PHP_EOL; }
static function global(){ echo __METHOD__, PHP_EOL; }
static function goto(){ echo __METHOD__, PHP_EOL; }
static function instanceof(){ echo __METHOD__, PHP_EOL; }
static function insteadof(){ echo __METHOD__, PHP_EOL; }
static function interface(){ echo __METHOD__, PHP_EOL; }
static function new(){ echo __METHOD__, PHP_EOL; }
static function or(){ echo __METHOD__, PHP_EOL; }
static function xor(){ echo __METHOD__, PHP_EOL; }
static function try(){ echo __METHOD__, PHP_EOL; }
static function use(){ echo __METHOD__, PHP_EOL; }
static function var(){ echo __METHOD__, PHP_EOL; }
static function exit(){ echo __METHOD__, PHP_EOL; }
static function list(){ echo __METHOD__, PHP_EOL; }
static function clone(){ echo __METHOD__, PHP_EOL; }
static function include(){ echo __METHOD__, PHP_EOL; }
static function include_once(){ echo __METHOD__, PHP_EOL; }
static function throw(){ echo __METHOD__, PHP_EOL; }
static function array(){ echo __METHOD__, PHP_EOL; }
static function print(){ echo __METHOD__, PHP_EOL; }
static function echo(){ echo __METHOD__, PHP_EOL; }
static function require(){ echo __METHOD__, PHP_EOL; }
static function require_once(){ echo __METHOD__, PHP_EOL; }
static function return(){ echo __METHOD__, PHP_EOL; }
static function else(){ echo __METHOD__, PHP_EOL; }
static function elseif(){ echo __METHOD__, PHP_EOL; }
static function default(){ echo __METHOD__, PHP_EOL; }
static function break(){ echo __METHOD__, PHP_EOL; }
static function continue(){ echo __METHOD__, PHP_EOL; }
static function switch(){ echo __METHOD__, PHP_EOL; }
static function yield(){ echo __METHOD__, PHP_EOL; }
static function function(){ echo __METHOD__, PHP_EOL; }
static function if(){ echo __METHOD__, PHP_EOL; }
static function endswitch(){ echo __METHOD__, PHP_EOL; }
static function finally(){ echo __METHOD__, PHP_EOL; }
static function for(){ echo __METHOD__, PHP_EOL; }
static function foreach(){ echo __METHOD__, PHP_EOL; }
static function declare(){ echo __METHOD__, PHP_EOL; }
static function case(){ echo __METHOD__, PHP_EOL; }
static function do(){ echo __METHOD__, PHP_EOL; }
static function while(){ echo __METHOD__, PHP_EOL; }
static function as(){ echo __METHOD__, PHP_EOL; }
static function catch(){ echo __METHOD__, PHP_EOL; }
static function die(){ echo __METHOD__, PHP_EOL; }
static function self(){ echo __METHOD__, PHP_EOL; }
static function parent(){ echo __METHOD__, PHP_EOL; }
static function public(){ echo __METHOD__, PHP_EOL; }
static function protected(){ echo __METHOD__, PHP_EOL; }
static function private(){ echo __METHOD__, PHP_EOL; }
static function static(){ echo __METHOD__, PHP_EOL; }
static function abstract(){ echo __METHOD__, PHP_EOL; }
static function final(){ echo __METHOD__, PHP_EOL; }
static function class(){ echo __METHOD__, PHP_EOL; }
}
Obj::empty();
Obj::callable();
Obj::trait();
Obj::extends();
Obj::implements();
Obj::const();
Obj::enddeclare();
Obj::endfor();
Obj::endforeach();
Obj::endif();
Obj::endwhile();
Obj::and();
Obj::global();
Obj::goto();
Obj::instanceof();
Obj::insteadof();
Obj::interface();
Obj::new();
Obj::or();
Obj::xor();
Obj::try();
Obj::use();
Obj::var();
Obj::exit();
Obj::list();
Obj::clone();
Obj::include();
Obj::include_once();
Obj::throw();
Obj::array();
Obj::print();
Obj::echo();
Obj::require();
Obj::require_once();
Obj::return();
Obj::else();
Obj::elseif();
Obj::default();
Obj::break();
Obj::continue();
Obj::switch();
Obj::yield();
Obj::function();
Obj::if();
Obj::endswitch();
Obj::finally();
Obj::for();
Obj::foreach();
Obj::declare();
Obj::case();
Obj::do();
Obj::while();
Obj::as();
Obj::catch();
Obj::die();
Obj::self();
Obj::parent();
Obj::public();
Obj::protected();
Obj::private();
Obj::static();
Obj::abstract();
Obj::final();
Obj::class();
echo "\nDone\n";
--EXPECTF--
Obj::empty
Obj::callable
Obj::trait
Obj::extends
Obj::implements
Obj::const
Obj::enddeclare
Obj::endfor
Obj::endforeach
Obj::endif
Obj::endwhile
Obj::and
Obj::global
Obj::goto
Obj::instanceof
Obj::insteadof
Obj::interface
Obj::new
Obj::or
Obj::xor
Obj::try
Obj::use
Obj::var
Obj::exit
Obj::list
Obj::clone
Obj::include
Obj::include_once
Obj::throw
Obj::array
Obj::print
Obj::echo
Obj::require
Obj::require_once
Obj::return
Obj::else
Obj::elseif
Obj::default
Obj::break
Obj::continue
Obj::switch
Obj::yield
Obj::function
Obj::if
Obj::endswitch
Obj::finally
Obj::for
Obj::foreach
Obj::declare
Obj::case
Obj::do
Obj::while
Obj::as
Obj::catch
Obj::die
Obj::self
Obj::parent
Obj::public
Obj::protected
Obj::private
Obj::static
Obj::abstract
Obj::final
Obj::class
Done

View file

@ -0,0 +1,210 @@
--TEST--
Test semi-reserved words as class properties
--FILE--
<?php
class Obj
{
var $empty = 'empty';
var $callable = 'callable';
var $class = 'class';
var $trait = 'trait';
var $extends = 'extends';
var $implements = 'implements';
var $static = 'static';
var $abstract = 'abstract';
var $final = 'final';
var $public = 'public';
var $protected = 'protected';
var $private = 'private';
var $const = 'const';
var $enddeclare = 'enddeclare';
var $endfor = 'endfor';
var $endforeach = 'endforeach';
var $endif = 'endif';
var $endwhile = 'endwhile';
var $and = 'and';
var $global = 'global';
var $goto = 'goto';
var $instanceof = 'instanceof';
var $insteadof = 'insteadof';
var $interface = 'interface';
var $namespace = 'namespace';
var $new = 'new';
var $or = 'or';
var $xor = 'xor';
var $try = 'try';
var $use = 'use';
var $var = 'var';
var $exit = 'exit';
var $list = 'list';
var $clone = 'clone';
var $include = 'include';
var $include_once = 'include_once';
var $throw = 'throw';
var $array = 'array';
var $print = 'print';
var $echo = 'echo';
var $require = 'require';
var $require_once = 'require_once';
var $return = 'return';
var $else = 'else';
var $elseif = 'elseif';
var $default = 'default';
var $break = 'break';
var $continue = 'continue';
var $switch = 'switch';
var $yield = 'yield';
var $function = 'function';
var $if = 'if';
var $endswitch = 'endswitch';
var $finally = 'finally';
var $for = 'for';
var $foreach = 'foreach';
var $declare = 'declare';
var $case = 'case';
var $do = 'do';
var $while = 'while';
var $as = 'as';
var $catch = 'catch';
var $die = 'die';
var $self = 'self';
}
$obj = new Obj;
echo $obj->empty, PHP_EOL;
echo $obj->callable, PHP_EOL;
echo $obj->class, PHP_EOL;
echo $obj->trait, PHP_EOL;
echo $obj->extends, PHP_EOL;
echo $obj->implements, PHP_EOL;
echo $obj->static, PHP_EOL;
echo $obj->abstract, PHP_EOL;
echo $obj->final, PHP_EOL;
echo $obj->public, PHP_EOL;
echo $obj->protected, PHP_EOL;
echo $obj->private, PHP_EOL;
echo $obj->const, PHP_EOL;
echo $obj->enddeclare, PHP_EOL;
echo $obj->endfor, PHP_EOL;
echo $obj->endforeach, PHP_EOL;
echo $obj->endif, PHP_EOL;
echo $obj->endwhile, PHP_EOL;
echo $obj->and, PHP_EOL;
echo $obj->global, PHP_EOL;
echo $obj->goto, PHP_EOL;
echo $obj->instanceof, PHP_EOL;
echo $obj->insteadof, PHP_EOL;
echo $obj->interface, PHP_EOL;
echo $obj->namespace, PHP_EOL;
echo $obj->new, PHP_EOL;
echo $obj->or, PHP_EOL;
echo $obj->xor, PHP_EOL;
echo $obj->try, PHP_EOL;
echo $obj->use, PHP_EOL;
echo $obj->var, PHP_EOL;
echo $obj->exit, PHP_EOL;
echo $obj->list, PHP_EOL;
echo $obj->clone, PHP_EOL;
echo $obj->include, PHP_EOL;
echo $obj->include_once, PHP_EOL;
echo $obj->throw, PHP_EOL;
echo $obj->array, PHP_EOL;
echo $obj->print, PHP_EOL;
echo $obj->echo, PHP_EOL;
echo $obj->require, PHP_EOL;
echo $obj->require_once, PHP_EOL;
echo $obj->return, PHP_EOL;
echo $obj->else, PHP_EOL;
echo $obj->elseif, PHP_EOL;
echo $obj->default, PHP_EOL;
echo $obj->break, PHP_EOL;
echo $obj->continue, PHP_EOL;
echo $obj->switch, PHP_EOL;
echo $obj->yield, PHP_EOL;
echo $obj->function, PHP_EOL;
echo $obj->if, PHP_EOL;
echo $obj->endswitch, PHP_EOL;
echo $obj->finally, PHP_EOL;
echo $obj->for, PHP_EOL;
echo $obj->foreach, PHP_EOL;
echo $obj->declare, PHP_EOL;
echo $obj->case, PHP_EOL;
echo $obj->do, PHP_EOL;
echo $obj->while, PHP_EOL;
echo $obj->as, PHP_EOL;
echo $obj->catch, PHP_EOL;
echo $obj->die, PHP_EOL;
echo $obj->self, PHP_EOL;
echo "\nDone\n";
?>
--EXPECTF--
empty
callable
class
trait
extends
implements
static
abstract
final
public
protected
private
const
enddeclare
endfor
endforeach
endif
endwhile
and
global
goto
instanceof
insteadof
interface
namespace
new
or
xor
try
use
var
exit
list
clone
include
include_once
throw
array
print
echo
require
require_once
return
else
elseif
default
break
continue
switch
yield
function
if
endswitch
finally
for
foreach
declare
case
do
while
as
catch
die
self
Done

View file

@ -0,0 +1,210 @@
--TEST--
Test semi-reserved words as static class properties
--FILE--
<?php
class Obj
{
static $empty = 'empty';
static $callable = 'callable';
static $class = 'class';
static $trait = 'trait';
static $extends = 'extends';
static $implements = 'implements';
static $static = 'static';
static $abstract = 'abstract';
static $final = 'final';
static $public = 'public';
static $protected = 'protected';
static $private = 'private';
static $const = 'const';
static $enddeclare = 'enddeclare';
static $endfor = 'endfor';
static $endforeach = 'endforeach';
static $endif = 'endif';
static $endwhile = 'endwhile';
static $and = 'and';
static $global = 'global';
static $goto = 'goto';
static $instanceof = 'instanceof';
static $insteadof = 'insteadof';
static $interface = 'interface';
static $namespace = 'namespace';
static $new = 'new';
static $or = 'or';
static $xor = 'xor';
static $try = 'try';
static $use = 'use';
static $var = 'var';
static $exit = 'exit';
static $list = 'list';
static $clone = 'clone';
static $include = 'include';
static $include_once = 'include_once';
static $throw = 'throw';
static $array = 'array';
static $print = 'print';
static $echo = 'echo';
static $require = 'require';
static $require_once = 'require_once';
static $return = 'return';
static $else = 'else';
static $elseif = 'elseif';
static $default = 'default';
static $break = 'break';
static $continue = 'continue';
static $switch = 'switch';
static $yield = 'yield';
static $function = 'function';
static $if = 'if';
static $endswitch = 'endswitch';
static $finally = 'finally';
static $for = 'for';
static $foreach = 'foreach';
static $declare = 'declare';
static $case = 'case';
static $do = 'do';
static $while = 'while';
static $as = 'as';
static $catch = 'catch';
static $die = 'die';
static $self = 'self';
static $parent = 'parent';
}
echo Obj::$empty, PHP_EOL;
echo Obj::$callable, PHP_EOL;
echo Obj::$class, PHP_EOL;
echo Obj::$trait, PHP_EOL;
echo Obj::$extends, PHP_EOL;
echo Obj::$implements, PHP_EOL;
echo Obj::$static, PHP_EOL;
echo Obj::$abstract, PHP_EOL;
echo Obj::$final, PHP_EOL;
echo Obj::$public, PHP_EOL;
echo Obj::$protected, PHP_EOL;
echo Obj::$private, PHP_EOL;
echo Obj::$const, PHP_EOL;
echo Obj::$enddeclare, PHP_EOL;
echo Obj::$endfor, PHP_EOL;
echo Obj::$endforeach, PHP_EOL;
echo Obj::$endif, PHP_EOL;
echo Obj::$endwhile, PHP_EOL;
echo Obj::$and, PHP_EOL;
echo Obj::$global, PHP_EOL;
echo Obj::$goto, PHP_EOL;
echo Obj::$instanceof, PHP_EOL;
echo Obj::$insteadof, PHP_EOL;
echo Obj::$interface, PHP_EOL;
echo Obj::$namespace, PHP_EOL;
echo Obj::$new, PHP_EOL;
echo Obj::$or, PHP_EOL;
echo Obj::$xor, PHP_EOL;
echo Obj::$try, PHP_EOL;
echo Obj::$use, PHP_EOL;
echo Obj::$var, PHP_EOL;
echo Obj::$exit, PHP_EOL;
echo Obj::$list, PHP_EOL;
echo Obj::$clone, PHP_EOL;
echo Obj::$include, PHP_EOL;
echo Obj::$include_once, PHP_EOL;
echo Obj::$throw, PHP_EOL;
echo Obj::$array, PHP_EOL;
echo Obj::$print, PHP_EOL;
echo Obj::$echo, PHP_EOL;
echo Obj::$require, PHP_EOL;
echo Obj::$require_once, PHP_EOL;
echo Obj::$return, PHP_EOL;
echo Obj::$else, PHP_EOL;
echo Obj::$elseif, PHP_EOL;
echo Obj::$default, PHP_EOL;
echo Obj::$break, PHP_EOL;
echo Obj::$continue, PHP_EOL;
echo Obj::$switch, PHP_EOL;
echo Obj::$yield, PHP_EOL;
echo Obj::$function, PHP_EOL;
echo Obj::$if, PHP_EOL;
echo Obj::$endswitch, PHP_EOL;
echo Obj::$finally, PHP_EOL;
echo Obj::$for, PHP_EOL;
echo Obj::$foreach, PHP_EOL;
echo Obj::$declare, PHP_EOL;
echo Obj::$case, PHP_EOL;
echo Obj::$do, PHP_EOL;
echo Obj::$while, PHP_EOL;
echo Obj::$as, PHP_EOL;
echo Obj::$catch, PHP_EOL;
echo Obj::$die, PHP_EOL;
echo Obj::$self, PHP_EOL;
echo Obj::$parent, PHP_EOL;
echo "\nDone\n";
--EXPECTF--
empty
callable
class
trait
extends
implements
static
abstract
final
public
protected
private
const
enddeclare
endfor
endforeach
endif
endwhile
and
global
goto
instanceof
insteadof
interface
namespace
new
or
xor
try
use
var
exit
list
clone
include
include_once
throw
array
print
echo
require
require_once
return
else
elseif
default
break
continue
switch
yield
function
if
endswitch
finally
for
foreach
declare
case
do
while
as
catch
die
self
parent
Done

View file

@ -0,0 +1,207 @@
--TEST--
Test semi-reserved words as class constants
--FILE--
<?php
class Obj
{
const EMPTY = 'empty';
const CALLABLE = 'callable';
const TRAIT = 'trait';
const EXTENDS = 'extends';
const IMPLEMENTS = 'implements';
const CONST = 'const';
const ENDDECLARE = 'enddeclare';
const ENDFOR = 'endfor';
const ENDFOREACH = 'endforeach';
const ENDIF = 'endif';
const ENDWHILE = 'endwhile';
const AND = 'and';
const GLOBAL = 'global';
const GOTO = 'goto';
const INSTANCEOF = 'instanceof';
const INSTEADOF = 'insteadof';
const INTERFACE = 'interface';
const NAMESPACE = 'namespace';
const NEW = 'new';
const OR = 'or';
const XOR = 'xor';
const TRY = 'try';
const USE = 'use';
const VAR = 'var';
const EXIT = 'exit';
const LIST = 'list';
const CLONE = 'clone';
const INCLUDE = 'include';
const INCLUDE_ONCE = 'include_once';
const THROW = 'throw';
const ARRAY = 'array';
const PRINT = 'print';
const ECHO = 'echo';
const REQUIRE = 'require';
const REQUIRE_ONCE = 'require_once';
const RETURN = 'return';
const ELSE = 'else';
const ELSEIF = 'elseif';
const DEFAULT = 'default';
const BREAK = 'break';
const CONTINUE = 'continue';
const SWITCH = 'switch';
const YIELD = 'yield';
const FUNCTION = 'function';
const IF = 'if';
const ENDSWITCH = 'endswitch';
const FINALLY = 'finally';
const FOR = 'for';
const FOREACH = 'foreach';
const DECLARE = 'declare';
const CASE = 'case';
const DO = 'do';
const WHILE = 'while';
const AS = 'as';
const CATCH = 'catch';
const DIE = 'die';
const SELF = 'self';
const PARENT = 'parent';
const PUBLIC = 'public';
const PROTECTED = 'protected';
const PRIVATE = 'private';
const STATIC = 'static';
const ABSTRACT = 'abstract';
const FINAL = 'final';
}
echo Obj::EMPTY, PHP_EOL;
echo Obj::CALLABLE, PHP_EOL;
echo Obj::TRAIT, PHP_EOL;
echo Obj::EXTENDS, PHP_EOL;
echo Obj::IMPLEMENTS, PHP_EOL;
echo Obj::CONST, PHP_EOL;
echo Obj::ENDDECLARE, PHP_EOL;
echo Obj::ENDFOR, PHP_EOL;
echo Obj::ENDFOREACH, PHP_EOL;
echo Obj::ENDIF, PHP_EOL;
echo Obj::ENDWHILE, PHP_EOL;
echo Obj::AND, PHP_EOL;
echo Obj::GLOBAL, PHP_EOL;
echo Obj::GOTO, PHP_EOL;
echo Obj::INSTANCEOF, PHP_EOL;
echo Obj::INSTEADOF, PHP_EOL;
echo Obj::INTERFACE, PHP_EOL;
echo Obj::NAMESPACE, PHP_EOL;
echo Obj::NEW, PHP_EOL;
echo Obj::OR, PHP_EOL;
echo Obj::XOR, PHP_EOL;
echo Obj::TRY, PHP_EOL;
echo Obj::USE, PHP_EOL;
echo Obj::VAR, PHP_EOL;
echo Obj::EXIT, PHP_EOL;
echo Obj::LIST, PHP_EOL;
echo Obj::CLONE, PHP_EOL;
echo Obj::INCLUDE, PHP_EOL;
echo Obj::INCLUDE_ONCE, PHP_EOL;
echo Obj::THROW, PHP_EOL;
echo Obj::ARRAY, PHP_EOL;
echo Obj::PRINT, PHP_EOL;
echo Obj::ECHO, PHP_EOL;
echo Obj::REQUIRE, PHP_EOL;
echo Obj::REQUIRE_ONCE, PHP_EOL;
echo Obj::RETURN, PHP_EOL;
echo Obj::ELSE, PHP_EOL;
echo Obj::ELSEIF, PHP_EOL;
echo Obj::DEFAULT, PHP_EOL;
echo Obj::BREAK, PHP_EOL;
echo Obj::CONTINUE, PHP_EOL;
echo Obj::SWITCH, PHP_EOL;
echo Obj::YIELD, PHP_EOL;
echo Obj::FUNCTION, PHP_EOL;
echo Obj::IF, PHP_EOL;
echo Obj::ENDSWITCH, PHP_EOL;
echo Obj::FINALLY, PHP_EOL;
echo Obj::FOR, PHP_EOL;
echo Obj::FOREACH, PHP_EOL;
echo Obj::DECLARE, PHP_EOL;
echo Obj::CASE, PHP_EOL;
echo Obj::DO, PHP_EOL;
echo Obj::WHILE, PHP_EOL;
echo Obj::AS, PHP_EOL;
echo Obj::CATCH, PHP_EOL;
echo Obj::DIE, PHP_EOL;
echo Obj::SELF, PHP_EOL;
echo Obj::PARENT, PHP_EOL;
echo Obj::PUBLIC, PHP_EOL;
echo Obj::PROTECTED, PHP_EOL;
echo Obj::PRIVATE, PHP_EOL;
echo Obj::STATIC, PHP_EOL;
echo Obj::ABSTRACT, PHP_EOL;
echo Obj::FINAL, PHP_EOL;
echo "\nDone\n";
--EXPECTF--
empty
callable
trait
extends
implements
const
enddeclare
endfor
endforeach
endif
endwhile
and
global
goto
instanceof
insteadof
interface
namespace
new
or
xor
try
use
var
exit
list
clone
include
include_once
throw
array
print
echo
require
require_once
return
else
elseif
default
break
continue
switch
yield
function
if
endswitch
finally
for
foreach
declare
case
do
while
as
catch
die
self
parent
public
protected
private
static
abstract
final
Done

View file

@ -0,0 +1,80 @@
--TEST--
Test semi-reserved method and constant names and trait conflict resolution
--FILE--
<?php
trait TraitA
{
public function catch(){ echo __METHOD__, PHP_EOL; }
private function list(){ echo __METHOD__, PHP_EOL; }
}
trait TraitB
{
static $list = ['a' => ['b' => ['c']]];
public static function catch(){ echo __METHOD__, PHP_EOL; }
private static function throw(){ echo __METHOD__, PHP_EOL; }
private static function self(){ echo __METHOD__, PHP_EOL; }
}
trait TraitC
{
public static function exit(){ echo __METHOD__, PHP_EOL; }
protected static function try(){ echo __METHOD__, PHP_EOL; }
}
class Foo
{
use TraitA, TraitB {
TraitA
::
catch insteadof namespace\TraitB;
TraitA::list as public foreach;
TraitB::throw as public;
TraitB::self as public;
}
use TraitC {
try as public attempt;
exit as die;
\TraitC::exit as bye;
namespace\TraitC::exit as byebye;
TraitC
::
exit as farewell;
}
}
(new Foo)->catch();
(new Foo)->foreach();
Foo::throw();
Foo::self();
var_dump(Foo::$list['a']);
Foo::attempt();
Foo::die();
Foo::bye();
Foo::byebye();
Foo::farewell();
echo "\nDone\n";
--EXPECTF--
TraitA::catch
TraitA::list
TraitB::throw
TraitB::self
array(1) {
["b"]=>
array(1) {
[0]=>
string(1) "c"
}
}
TraitC::try
TraitC::exit
TraitC::exit
TraitC::exit
TraitC::exit
Done

View file

@ -0,0 +1,37 @@
--TEST--
Edge case: self::self, self::parent, parent::self semi reserved constants access
--FILE--
<?php
class Foo {
const self = "self";
const parent = "parent";
public function __construct() {
echo "From ", __METHOD__, ":", PHP_EOL;
echo self::self, PHP_EOL;
echo self::parent, PHP_EOL;
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
echo "From ", __METHOD__, ":", PHP_EOL;
echo parent::self, PHP_EOL;
echo parent::parent, PHP_EOL;
}
}
new Bar;
echo "\nDone\n";
--EXPECTF--
From Foo::__construct:
self
parent
From Bar::__construct:
self
parent
Done

View file

@ -0,0 +1,68 @@
--TEST--
Testing with comments around semi-reserved names (not intended to be legible)
--FILE--
<?php
trait TraitA
{
public static function list(){ echo __METHOD__, PHP_EOL; }
public static function /* comment */ catch(){ echo __METHOD__, PHP_EOL; }
private static function // comment
throw(){ echo __METHOD__, PHP_EOL; }
private static function
# comment
self(){ echo __METHOD__, PHP_EOL; }
}
trait TraitB
{
public static function exit(){ echo __METHOD__, PHP_EOL; }
protected static function try(){ echo __METHOD__, PHP_EOL; }
}
class Foo
{
use TraitA {
TraitA::
//
/** doc comment */
#
catch /* comment */
// comment
# comment
insteadof TraitB;
TraitA::list as public /**/ foreach;
}
use TraitB {
try /*comment*/ as public attempt;
exit // comment
as/*comment*/die; // non qualified
\TraitB::exit as bye; // full qualified
namespace\TraitB::exit #
as byebye; // even more full qualified
TraitB
::
/** */
exit as farewell; // full qualified with weird spacing
}
}
Foo /**/
#
//
/** */
::
/**/
#
//
/** */
attempt();
echo PHP_EOL, "Done", PHP_EOL;
--EXPECTF--
TraitB::try
Done

View file

@ -0,0 +1,25 @@
--TEST--
Edge case: T_STRING<as> as T_STRING<?>
--FILE--
<?php
trait TraitA
{
public static function as(){ echo __METHOD__, PHP_EOL; }
}
class Foo
{
use TraitA {
as as try;
}
}
Foo::try();
echo PHP_EOL, "Done", PHP_EOL;
--EXPECTF--
TraitA::as
Done

View file

@ -0,0 +1,31 @@
--TEST--
Edge case: T_STRING<insteadof> insteadof T_STRING<?>
--FILE--
<?php
trait TraitA
{
public static function insteadof(){ echo __METHOD__, PHP_EOL; }
}
trait TraitB
{
public static function insteadof(){ echo __METHOD__, PHP_EOL; }
}
class Foo
{
use TraitA , TraitB {
TraitB::insteadof
insteadof TraitA;
}
}
Foo::insteadof();
echo PHP_EOL, "Done", PHP_EOL;
--EXPECTF--
TraitB::insteadof
Done

View file

@ -1149,9 +1149,6 @@ simple_list:
case ZEND_AST_CONST:
zend_ast_export_ns_name(str, ast->child[0], 0, indent);
break;
case ZEND_AST_RESOLVE_CLASS_NAME:
zend_ast_export_ns_name(str, ast->child[0], 0, indent);
APPEND_STR("::class");
case ZEND_AST_UNPACK:
smart_str_appends(str, "...");
ast = ast->child[0];

View file

@ -66,7 +66,6 @@ enum _zend_ast_kind {
/* 1 child node */
ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT,
ZEND_AST_CONST,
ZEND_AST_RESOLVE_CLASS_NAME,
ZEND_AST_UNPACK,
ZEND_AST_UNARY_PLUS,
ZEND_AST_UNARY_MINUS,

View file

@ -557,7 +557,10 @@ static int zend_add_const_name_literal(zend_op_array *op_array, zend_string *nam
op.constant = zend_add_literal(CG(active_op_array), &_c); \
} while (0)
void zend_stop_lexing(void) {
void zend_stop_lexing(void)
{
if(LANG_SCNG(on_event)) LANG_SCNG(on_event)(ON_STOP, END, 0);
LANG_SCNG(yy_cursor) = LANG_SCNG(yy_limit);
}
@ -1345,6 +1348,88 @@ static inline zend_bool class_name_refers_to_active_ce(zend_string *class_name,
}
/* }}} */
uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
{
if (zend_string_equals_literal_ci(name, "self")) {
return ZEND_FETCH_CLASS_SELF;
} else if (zend_string_equals_literal_ci(name, "parent")) {
return ZEND_FETCH_CLASS_PARENT;
} else if (zend_string_equals_literal_ci(name, "static")) {
return ZEND_FETCH_CLASS_STATIC;
} else {
return ZEND_FETCH_CLASS_DEFAULT;
}
}
/* }}} */
static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
{
/* Fully qualified names are always default refs */
if (name_ast->attr == ZEND_NAME_FQ) {
return ZEND_FETCH_CLASS_DEFAULT;
}
return zend_get_class_fetch_type(zend_ast_get_str(name_ast));
}
/* }}} */
static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
{
if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG(active_class_entry) && zend_is_scope_known()) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active",
fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
}
}
/* }}} */
static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast, zend_ast *name_ast, zend_bool constant) /* {{{ */
{
uint32_t fetch_type;
if (name_ast->kind != ZEND_AST_ZVAL) {
return 0;
}
if (!zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "class")) {
return 0;
}
if (class_ast->kind != ZEND_AST_ZVAL) {
zend_error_noreturn(E_COMPILE_ERROR,
"Dynamic class names are not allowed in compile-time ::class fetch");
}
fetch_type = zend_get_class_fetch_type(zend_ast_get_str(class_ast));
zend_ensure_valid_class_fetch_type(fetch_type);
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
if (constant || (CG(active_class_entry) && zend_is_scope_known())) {
ZVAL_STR_COPY(zv, CG(active_class_entry)->name);
} else {
ZVAL_NULL(zv);
}
return 1;
case ZEND_FETCH_CLASS_STATIC:
case ZEND_FETCH_CLASS_PARENT:
if (constant) {
zend_error_noreturn(E_COMPILE_ERROR,
"%s::class cannot be used for compile-time class name resolution",
fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
);
} else {
ZVAL_NULL(zv);
}
return 1;
case ZEND_FETCH_CLASS_DEFAULT:
ZVAL_STR(zv, zend_resolve_class_name_ast(class_ast));
return 1;
EMPTY_SWITCH_DEFAULT_CASE()
}
}
/* }}} */
static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */
{
uint32_t fetch_type = zend_get_class_fetch_type(class_name);
@ -1625,41 +1710,6 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
}
/* }}} */
uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
{
if (zend_string_equals_literal_ci(name, "self")) {
return ZEND_FETCH_CLASS_SELF;
} else if (zend_string_equals_literal_ci(name, "parent")) {
return ZEND_FETCH_CLASS_PARENT;
} else if (zend_string_equals_literal_ci(name, "static")) {
return ZEND_FETCH_CLASS_STATIC;
} else {
return ZEND_FETCH_CLASS_DEFAULT;
}
}
/* }}} */
static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
{
/* Fully qualified names are always default refs */
if (name_ast->attr == ZEND_NAME_FQ) {
return ZEND_FETCH_CLASS_DEFAULT;
}
return zend_get_class_fetch_type(zend_ast_get_str(name_ast));
}
/* }}} */
static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
{
if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG(active_class_entry) && zend_is_scope_known()) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active",
fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
}
}
/* }}} */
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var) /* {{{ */
{
return op_array->vars[EX_VAR_TO_NUM(var)];
@ -2164,14 +2214,6 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint
znode name_node;
zend_op *opline;
/* there is a chance someone is accessing $this */
if (ast->kind != ZEND_AST_ZVAL
&& CG(active_op_array)->scope && CG(active_op_array)->this_var == (uint32_t)-1
) {
zend_string *key = zend_string_init("this", sizeof("this") - 1, 0);
CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key);
}
zend_compile_expr(&name_node, name_ast);
if (name_node.op_type == IS_CONST) {
convert_to_string(&name_node.u.constant);
@ -2183,10 +2225,18 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint
opline = zend_emit_op(result, ZEND_FETCH_R, &name_node, NULL);
}
opline->extended_value = ZEND_FETCH_LOCAL;
if (name_node.op_type == IS_CONST) {
if (zend_is_auto_global(Z_STR(name_node.u.constant))) {
opline->extended_value = ZEND_FETCH_GLOBAL;
if (name_node.op_type == IS_CONST &&
zend_is_auto_global(Z_STR(name_node.u.constant))) {
opline->extended_value = ZEND_FETCH_GLOBAL;
} else {
opline->extended_value = ZEND_FETCH_LOCAL;
/* there is a chance someone is accessing $this */
if (ast->kind != ZEND_AST_ZVAL
&& CG(active_op_array)->scope && CG(active_op_array)->this_var == (uint32_t)-1
) {
zend_string *key = zend_string_init("this", sizeof("this") - 1, 0);
CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key);
}
}
@ -4747,6 +4797,11 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
zend_string *name = zend_ast_get_str(name_ast);
zval value_zv;
if (zend_string_equals_literal_ci(name, "class")) {
zend_error(E_COMPILE_ERROR,
"A class constant must not be called 'class'; it is reserved for class name fetching");
}
zend_const_expr_to_zval(&value_zv, value_ast);
name = zend_new_interned_string_safe(name);
@ -6313,6 +6368,16 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
zend_op *opline;
zend_string *resolved_name;
if (zend_try_compile_const_expr_resolve_class_name(&result->u.constant, class_ast, const_ast, 0)) {
if (Z_TYPE(result->u.constant) == IS_NULL) {
zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
opline->extended_value = zend_get_class_fetch_type(zend_ast_get_str(class_ast));
} else {
result->op_type = IS_CONST;
}
return;
}
zend_eval_const_expr(&class_ast);
zend_eval_const_expr(&const_ast);
@ -6324,6 +6389,10 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
return;
}
}
if (const_ast->kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci(zend_ast_get_str(const_ast), "class")) {
zend_error_noreturn(E_COMPILE_ERROR,
"Dynamic class names are not allowed in compile-time ::class fetch");
}
if (zend_is_const_default_class_ref(class_ast)) {
class_node.op_type = IS_CONST;
@ -6536,7 +6605,7 @@ zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
|| kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
|| kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
|| kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
|| kind == ZEND_AST_RESOLVE_CLASS_NAME || kind == ZEND_AST_MAGIC_CONST;
|| kind == ZEND_AST_MAGIC_CONST;
}
/* }}} */
@ -6555,6 +6624,11 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
"Dynamic class names are not allowed in compile-time class constant references");
}
if (zend_try_compile_const_expr_resolve_class_name(&result, class_ast, const_ast, 1)) {
*ast_ptr = zend_ast_create_zval(&result);
return;
}
class_name = zend_ast_get_str(class_ast);
fetch_type = zend_get_class_fetch_type(class_name);
@ -6610,36 +6684,6 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
}
/* }}} */
void zend_compile_const_expr_resolve_class_name(zend_ast **ast_ptr) /* {{{ */
{
zend_ast *ast = *ast_ptr;
zend_ast *name_ast = ast->child[0];
zval result;
uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
zend_ensure_valid_class_fetch_type(fetch_type);
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
ZVAL_STR_COPY(&result, CG(active_class_entry)->name);
break;
case ZEND_FETCH_CLASS_STATIC:
case ZEND_FETCH_CLASS_PARENT:
zend_error_noreturn(E_COMPILE_ERROR,
"%s::class cannot be used for compile-time class name resolution",
fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
);
break;
case ZEND_FETCH_CLASS_DEFAULT:
ZVAL_STR(&result, zend_resolve_class_name_ast(name_ast));
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
zend_ast_destroy(ast);
*ast_ptr = zend_ast_create_zval(&result);
}
/* }}} */
void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
{
zend_ast *ast = *ast_ptr;
@ -6678,9 +6722,6 @@ void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */
case ZEND_AST_CONST:
zend_compile_const_expr_const(ast_ptr);
break;
case ZEND_AST_RESOLVE_CLASS_NAME:
zend_compile_const_expr_resolve_class_name(ast_ptr);
break;
case ZEND_AST_MAGIC_CONST:
zend_compile_const_expr_magic_const(ast_ptr);
break;
@ -6955,9 +6996,6 @@ void zend_compile_expr(znode *result, zend_ast *ast) /* {{{ */
case ZEND_AST_CLASS_CONST:
zend_compile_class_const(result, ast);
return;
case ZEND_AST_RESOLVE_CLASS_NAME:
zend_compile_resolve_class_name(result, ast);
return;
case ZEND_AST_ENCAPS_LIST:
zend_compile_encaps_list(result, ast);
return;
@ -7127,9 +7165,18 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
zend_ast *name_ast = ast->child[1];
zend_string *resolved_name;
if (zend_try_compile_const_expr_resolve_class_name(&result, class_ast, name_ast, 1)) {
break;
}
zend_eval_const_expr(&class_ast);
zend_eval_const_expr(&name_ast);
if (name_ast->kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "class")) {
zend_error_noreturn(E_COMPILE_ERROR,
"Dynamic class names are not allowed in compile-time ::class fetch");
}
if (class_ast->kind != ZEND_AST_ZVAL || name_ast->kind != ZEND_AST_ZVAL) {
return;
}

View file

@ -249,6 +249,12 @@ struct _zend_ini_scanner_globals {
int scanner_mode;
};
typedef enum {
ON_TOKEN,
ON_FEEDBACK,
ON_STOP
} zend_php_scanner_event;
struct _zend_php_scanner_globals {
zend_file_handle *yy_in;
zend_file_handle *yy_out;
@ -278,6 +284,9 @@ struct _zend_php_scanner_globals {
/* initial string length after scanning to first variable */
int scanned_string_len;
/* hooks */
void (* on_event)(zend_php_scanner_event event, int token, int line);
};
#endif /* ZEND_GLOBALS_H */

View file

@ -21,20 +21,13 @@
/* $Id$ */
/*
* LALR shift/reduce conflicts and how they are resolved:
*
* - 2 shift/reduce conflicts due to the dangling elseif/else ambiguity. Solved by shift.
*
*/
#include "zend_compile.h"
#include "zend.h"
#include "zend_list.h"
#include "zend_globals.h"
#include "zend_API.h"
#include "zend_constants.h"
#include "zend_language_scanner.h"
#define YYSIZE_T size_t
#define yytnamerr zend_yytnamerr
@ -51,7 +44,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%}
%pure_parser
%expect 2
%expect 0
%code requires {
}
@ -87,6 +80,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%right T_POW
%right '['
%nonassoc T_NEW T_CLONE
%left "if_without_else"
%left T_ELSEIF
%left T_ELSE
%left T_ENDIF
@ -243,8 +237,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> absolute_trait_method_reference trait_method_reference property echo_expr
%type <ast> new_expr anonymous_class class_name class_name_reference simple_variable
%type <ast> internal_functions_in_yacc
%type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name
%type <ast> variable_class_name dereferencable_scalar class_name_scalar constant dereferencable
%type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name property_name
%type <ast> variable_class_name dereferencable_scalar constant dereferencable
%type <ast> callable_expr callable_variable static_member new_variable
%type <ast> assignment_list_element array_pair encaps_var encaps_var_offset isset_variables
%type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt
@ -252,13 +246,14 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> echo_expr_list unset_variables catch_list parameter_list class_statement_list
%type <ast> implements_list case_list if_stmt_without_else
%type <ast> non_empty_parameter_list argument_list non_empty_argument_list property_list
%type <ast> class_const_list name_list trait_adaptations method_body non_empty_for_exprs
%type <ast> class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs
%type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars
%type <ast> lexical_var_list encaps_list array_pair_list non_empty_array_pair_list
%type <ast> assignment_list isset_variable type return_type
%type <ast> identifier
%type <num> returns_ref function is_reference is_variadic variable_modifiers
%type <num> method_modifiers trait_modifiers non_empty_member_modifiers member_modifier
%type <num> method_modifiers non_empty_member_modifiers member_modifier
%type <num> class_modifiers class_modifier use_type
%type <str> backup_doc_comment
@ -269,6 +264,29 @@ start:
top_statement_list { CG(ast) = $1; }
;
reserved_non_modifiers:
T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND
| T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE | T_ENDWHILE
| T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH | T_FINALLY
| T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
| T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT | T_BREAK
| T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
;
semi_reserved:
reserved_non_modifiers
| T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC
;
identifier:
T_STRING { $$ = $1; }
| semi_reserved {
zval zv;
zend_lex_tstring(&zv);
$$ = zend_ast_create_zval(&zv);
}
;
top_statement_list:
top_statement_list top_statement { $$ = zend_ast_list_add($1, $2); }
| /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
@ -561,7 +579,7 @@ if_stmt_without_else:
;
if_stmt:
if_stmt_without_else { $$ = $1; }
if_stmt_without_else %prec "if_without_else" { $$ = $1; }
| if_stmt_without_else T_ELSE statement
{ $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_IF_ELEM, NULL, $3)); }
;
@ -673,7 +691,7 @@ class_statement:
{ $$ = $2; RESET_DOC_COMMENT(); }
| T_USE name_list trait_adaptations
{ $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); }
| method_modifiers function returns_ref T_STRING '(' parameter_list ')'
| method_modifiers function returns_ref identifier '(' parameter_list ')'
return_type backup_doc_comment method_body
{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1, $2, $9,
zend_ast_get_str($4), $6, NULL, $10, $8); }
@ -708,28 +726,27 @@ trait_precedence:
;
trait_alias:
trait_method_reference T_AS trait_modifiers T_STRING
trait_method_reference T_AS T_STRING
{ $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, 0, $1, $3); }
| trait_method_reference T_AS reserved_non_modifiers
{ zval zv; zend_lex_tstring(&zv); $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, 0, $1, zend_ast_create_zval(&zv)); }
| trait_method_reference T_AS member_modifier identifier
{ $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, $4); }
| trait_method_reference T_AS member_modifier
| trait_method_reference T_AS member_modifier %prec '+'
{ $$ = zend_ast_create_ex(ZEND_AST_TRAIT_ALIAS, $3, $1, NULL); }
;
trait_method_reference:
T_STRING
identifier
{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, NULL, $1); }
| absolute_trait_method_reference { $$ = $1; }
;
absolute_trait_method_reference:
name T_PAAMAYIM_NEKUDOTAYIM T_STRING
name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
;
trait_modifiers:
/* empty */ { $$ = 0; }
| member_modifier { $$ = $1; }
;
method_body:
';' /* abstract method */ { $$ = NULL; }
| '{' inner_statement_list '}' { $$ = $2; }
@ -773,8 +790,12 @@ property:
;
class_const_list:
class_const_list ',' const_decl { $$ = zend_ast_list_add($1, $3); }
| const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1); }
class_const_list ',' class_const_decl { $$ = zend_ast_list_add($1, $3); }
| class_const_decl { $$ = zend_ast_create_list(1, ZEND_AST_CLASS_CONST_DECL, $1); }
;
class_const_decl:
identifier '=' expr { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3); }
;
const_decl:
@ -1028,15 +1049,14 @@ scalar:
| '"' encaps_list '"' { $$ = $2; }
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
| dereferencable_scalar { $$ = $1; }
| class_name_scalar { $$ = $1; }
| constant { $$ = $1; }
;
constant:
name { $$ = zend_ast_create(ZEND_AST_CONST, $1); }
| class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING
| class_name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create(ZEND_AST_CLASS_CONST, $1, $3); }
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create(ZEND_AST_CLASS_CONST, $1, $3); }
;
@ -1080,7 +1100,7 @@ callable_variable:
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| dereferencable '{' expr '}'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| dereferencable T_OBJECT_OPERATOR member_name argument_list
| dereferencable T_OBJECT_OPERATOR property_name argument_list
{ $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); }
| function_call { $$ = $1; }
;
@ -1090,7 +1110,7 @@ variable:
{ $$ = $1; }
| static_member
{ $$ = $1; }
| dereferencable T_OBJECT_OPERATOR member_name
| dereferencable T_OBJECT_OPERATOR property_name
{ $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
;
@ -1114,7 +1134,7 @@ new_variable:
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| new_variable '{' expr '}'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| new_variable T_OBJECT_OPERATOR member_name
| new_variable T_OBJECT_OPERATOR property_name
{ $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
| class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable
{ $$ = zend_ast_create(ZEND_AST_STATIC_PROP, $1, $3); }
@ -1123,7 +1143,13 @@ new_variable:
;
member_name:
T_STRING { $$ = $1; }
identifier { $$ = $1; }
| '{' expr '}' { $$ = $2; }
| simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
;
property_name:
T_STRING { $$ = $1; }
| '{' expr '}' { $$ = $2; }
| simple_variable { $$ = zend_ast_create(ZEND_AST_VAR, $1); }
;
@ -1226,11 +1252,6 @@ isset_variable:
expr { $$ = zend_ast_create(ZEND_AST_ISSET, $1); }
;
class_name_scalar:
class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS
{ $$ = zend_ast_create(ZEND_AST_RESOLVE_CLASS_NAME, $1); }
;
%%
/* Copy to YYRES the contents of YYSTR after stripping away unnecessary

File diff suppressed because it is too large Load diff

View file

@ -50,6 +50,9 @@ typedef struct _zend_lex_state {
zend_encoding_filter output_filter;
const zend_encoding *script_encoding;
/* hooks */
void (* on_event)(zend_php_scanner_event event, int token, int line);
zend_ast *ast;
zend_arena *ast_arena;
} zend_lex_state;
@ -66,6 +69,7 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state);
ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename);
ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter, const zend_encoding *old_encoding);
ZEND_API int zend_multibyte_set_filter(const zend_encoding *onetime_encoding);
ZEND_API void zend_lex_tstring(zval *zv);
END_EXTERN_C()

File diff suppressed because it is too large Load diff

View file

@ -54,10 +54,6 @@
# endif
#endif
#ifndef S_IFLNK
# define S_IFLNK 0120000
#endif
#ifdef NETWARE
#include <fsio.h>
#endif
@ -89,14 +85,6 @@ cwd_state main_cwd_state; /* True global */
#include <direct.h>
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) ((mode) & _S_IFREG)
#endif
#ifdef TSRM_WIN32
#include <tchar.h>
#define tsrm_strtok_r(a,b,c) _tcstok((a),(b))

View file

@ -337,4 +337,33 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(void);
#endif
/* Global stat declarations */
#ifndef _S_IFDIR
#define _S_IFDIR S_IFDIR
#endif
#ifndef _S_IFREG
#define _S_IFREG S_IFREG
#endif
#ifndef S_IFLNK
# define S_IFLNK 0120000
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#endif
#ifndef S_ISLNK
#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
#endif
#ifndef S_IXROOT
#define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
#endif
#endif /* VIRTUAL_CWD_H */

View file

@ -2986,7 +2986,8 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
} else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}

View file

@ -5647,7 +5647,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -9284,7 +9285,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -11009,7 +11011,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -23937,7 +23940,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -26350,7 +26354,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -27885,7 +27890,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -32184,7 +32190,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -37265,7 +37272,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -39845,7 +39853,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -41997,7 +42006,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -44066,7 +44076,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}
@ -45123,7 +45134,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
call_info = ZEND_CALL_NESTED_FUNCTION;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
obj = NULL;
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
/* CV may be changed indirectly (e.g. when it's a reference) */
call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(obj)++; /* For $this pointer */
}

View file

@ -4,11 +4,15 @@ strftime() and gmstrftime() tests
<?php
if (substr(PHP_OS, 0, 3) != 'WIN') die('skip only windows test.');
if (!function_exists('strftime')) die("skip, strftime not available");
if (false === setlocale(LC_TIME, "en-us")) die("skip, couldn't set the locale to en-us");
?>
--FILE--
<?php
date_default_timezone_set('Asia/Jerusalem');
$loc = setlocale(LC_TIME, "0");
setlocale(LC_TIME, "en-us");
$t = mktime(0,0,0, 6, 27, 2006);
var_dump(strftime());
@ -32,19 +36,21 @@ var_dump(gmstrftime("%%q %%a", $t));
var_dump(gmstrftime("blah", $t));
echo "Done\n";
setlocale(LC_TIME, $loc);
?>
--EXPECTF--
Warning: strftime() expects at least 1 parameter, 0 given in %s on line %d
bool(false)
bool(false)
string(%d) "Tue Tuesday Jun June 06/27/06 00:00:00 27 00 12 178 06 00 AM 00 26 26 2 06/27/06 00:00:00 06 2006 %s"
string(%d) "Tue Tuesday Jun June 6/27/2006 12:00:00 AM 27 00 12 178 06 00 AM 00 26 26 2 6/27/2006 12:00:00 AM 06 2006 %s"
string(5) "%q %a"
string(4) "blah"
Warning: gmstrftime() expects at least 1 parameter, 0 given in %s on line %d
bool(false)
bool(false)
string(%d) "Mon Monday Jun June 06/26/06 21:00:00 26 21 09 177 06 00 PM 00 26 26 1 06/26/06 21:00:00 06 2006 %s"
string(%d) "Mon Monday Jun June 6/26/2006 9:00:00 PM 26 21 09 177 06 00 PM 00 26 26 1 6/26/2006 9:00:00 PM 06 2006 %s"
string(5) "%q %a"
string(4) "blah"
Done

View file

@ -1,5 +1,5 @@
--TEST--
Test gmstrftime() function : usage variation - Checking month related formats which are not supported on Windows.
Test gmstrftime() function : usage variation - Checking month related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -32,6 +32,6 @@ var_dump( gmstrftime($format, $timestamp) );
*** Testing gmstrftime() : usage variation ***
-- Testing gmstrftime() function with Abbreviated month name format %h --
bool(false)
bool(false)
string(%d) "%s"
string(3) "Aug"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test gmstrftime() function : usage variation - Checking date related formats which are not supported on Windows.
Test gmstrftime() function : usage variation - Checking date related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -18,7 +18,7 @@ echo "*** Testing gmstrftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
$timestamp = gmmktime(8, 8, 8, 8, 8, 2008);
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
//array of values to iterate over
@ -43,18 +43,18 @@ foreach($inputs as $key =>$value) {
*** Testing gmstrftime() : usage variation ***
--Century number--
bool(false)
bool(false)
string(2) "%d"
string(2) "20"
--Month Date Year--
bool(false)
bool(false)
string(%d) "%d/%d/%d"
string(8) "08/08/08"
--Year with century--
bool(false)
bool(false)
string(%d) "%d"
string(4) "2008"
--Year without century--
bool(false)
bool(false)
string(2) "%d"
string(2) "08"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test gmstrftime() function : usage variation - Checking time related formats which are not supported on Windows.
Test gmstrftime() function : usage variation - Checking time related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -18,7 +18,7 @@ echo "*** Testing gmstrftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
$timestamp = gmmktime(8, 8, 8, 8, 8, 2008);
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
//array of values to iterate over
@ -42,14 +42,14 @@ foreach($inputs as $key =>$value) {
*** Testing gmstrftime() : usage variation ***
--Time in a.m/p.m notation--
bool(false)
bool(false)
string(%d) "%d:%d:%d %c%c"
string(11) "08:08:08 AM"
--Time in 24 hour notation--
bool(false)
bool(false)
string(%d) "%d:%d"
string(5) "08:08"
--Current time %H:%M:%S format--
bool(false)
bool(false)
string(%d) "%d:%d:%d"
string(8) "08:08:08"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test gmstrftime() function : usage variation - Checking day related formats which are not supported on Windows.
Test gmstrftime() function : usage variation - Checking day related formats which was not supported on Windows before vc14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -18,7 +18,7 @@ echo "*** Testing gmstrftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
$timestamp = gmmktime(8, 8, 8, 8, 8, 2008);
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
echo "\n-- Testing gmstrftime() function with Day of the month as decimal single digit format --\n";
@ -32,6 +32,6 @@ var_dump( gmstrftime($format, $timestamp) );
*** Testing gmstrftime() : usage variation ***
-- Testing gmstrftime() function with Day of the month as decimal single digit format --
bool(false)
bool(false)
string(2) "%A%d"
string(2) " 8"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test gmstrftime() function : usage variation - Checking newline and tab formats which are not supported on Windows.
Test gmstrftime() function : usage variation - Checking newline and tab formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -18,7 +18,7 @@ echo "*** Testing gmstrftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
$timestamp = gmmktime(8, 8, 8, 8, 8, 2008);
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
//array of values to iterate over
@ -41,10 +41,12 @@ foreach($inputs as $key =>$value) {
*** Testing gmstrftime() : usage variation ***
--Newline character--
bool(false)
bool(false)
string(1) "
"
string(1) "
"
--Tab character--
bool(false)
bool(false)
string(1) " "
string(1) " "
===DONE===

View file

@ -18,7 +18,7 @@ echo "*** Testing gmstrftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
$timestamp = gmmktime(8, 8, 8, 8, 8, 2008);
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
//array of values to iterate over
@ -42,8 +42,8 @@ foreach($inputs as $key =>$value) {
*** Testing gmstrftime() : usage variation ***
--Preferred date and time representation--
string(%d) "%d/%d/%d %d:%d:%d"
string(17) "08/08/08 08:08:08"
string(%d) "%s %s %d %d:%d:%d %d"
string(24) "Fri Aug 8 08:08:08 2008"
--Preferred date representation--
string(%d) "%d/%d/%d"

View file

@ -1,5 +1,5 @@
--TEST--
Test gmstrftime() function : usage variation - Checking week related formats which are not supported on Windows.
Test gmstrftime() function : usage variation - Checking week related formats which was not supported on Windows before vc14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -18,7 +18,7 @@ echo "*** Testing gmstrftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
$timestamp = gmmktime(8, 8, 8, 8, 8, 2008);
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
//array of values to iterate over
@ -41,10 +41,10 @@ foreach($inputs as $key =>$value) {
*** Testing gmstrftime() : usage variation ***
--The ISO 8601:1988 week number--
bool(false)
bool(false)
string(%d) "%d"
string(2) "32"
--Weekday as decimal--
bool(false)
bool(false)
string(1) "%d"
string(1) "5"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test strftime() function : usage variation - Checking month related formats which are not supported on Windows.
Test strftime() function : usage variation - Checking month related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -17,7 +17,7 @@ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
echo "*** Testing strftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
$timestamp = mktime(8, 8, 8, 8, 8, 2008);
@ -32,6 +32,6 @@ var_dump( strftime($format, $timestamp) );
*** Testing strftime() : usage variation ***
-- Testing strftime() function with Abbreviated month name format %h --
bool(false)
bool(false)
string(%d) "%s"
string(3) "Aug"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test strftime() function : usage variation - Checking date related formats which are not supported on Windows.
Test strftime() function : usage variation - Checking date related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -17,7 +17,7 @@ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
echo "*** Testing strftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
$timestamp = mktime(8, 8, 8, 8, 8, 2008);
@ -43,18 +43,18 @@ foreach($inputs as $key =>$value) {
*** Testing strftime() : usage variation ***
--Century number--
bool(false)
bool(false)
string(2) "20"
string(2) "20"
--Month Date Year--
bool(false)
bool(false)
string(%d) "%d/%d/%d"
string(8) "08/08/08"
--Year with century--
bool(false)
bool(false)
string(4) "%d"
string(4) "2008"
--Year without century--
bool(false)
bool(false)
string(2) "%d"
string(2) "08"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test strftime() function : usage variation - Checking time related formats which are not supported on Windows.
Test strftime() function : usage variation - Checking time related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -17,7 +17,7 @@ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
echo "*** Testing strftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
$timestamp = mktime(8, 8, 8, 8, 8, 2008);
@ -42,14 +42,14 @@ foreach($inputs as $key =>$value) {
*** Testing strftime() : usage variation ***
--Time in a.m/p.m notation--
bool(false)
bool(false)
string(%d) "%d:%d:%d %s"
string(11) "08:08:08 AM"
--Time in 24 hour notation--
bool(false)
bool(false)
string(%d) "%d:%d"
string(5) "08:08"
--Current time %H:%M:%S format--
bool(false)
bool(false)
string(%d) "%d:%d:%d"
string(8) "08:08:08"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test strftime() function : usage variation - Checking day related formats which are not supported on Windows.
Test strftime() function : usage variation - Checking day related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -17,7 +17,7 @@ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
echo "*** Testing strftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
$timestamp = mktime(8, 8, 8, 8, 8, 2008);
@ -31,6 +31,6 @@ var_dump( strftime($format, $timestamp) );
*** Testing strftime() : usage variation ***
-- Testing strftime() function with Day of the month as decimal single digit format --
bool(false)
bool(false)
string(%d) "%A%d"
string(2) " 8"
===DONE===

View file

@ -1,5 +1,5 @@
--TEST--
Test strftime() function : usage variation - Checking newline and tab formats which are not supported on Windows.
Test strftime() function : usage variation - Checking newline and tab formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -41,10 +41,12 @@ foreach($inputs as $key =>$value) {
*** Testing strftime() : usage variation ***
--Newline character--
bool(false)
bool(false)
string(1) "
"
string(1) "
"
--Tab character--
bool(false)
bool(false)
string(1) " "
string(1) " "
===DONE===

View file

@ -17,7 +17,7 @@ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
echo "*** Testing strftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
$timestamp = mktime(8, 8, 8, 8, 8, 2008);
@ -42,8 +42,8 @@ foreach($inputs as $key =>$value) {
*** Testing strftime() : usage variation ***
--Preferred date and time representation--
string(%d) "%d/%d/%d %d:%d:%d"
string(17) "08/08/08 08:08:08"
string(%d) "%s %s %d %d:%d:%d %d"
string(24) "Fri Aug 8 08:08:08 2008"
--Preferred date representation--
string(%d) "%d/%d/%d"

View file

@ -1,5 +1,5 @@
--TEST--
Test strftime() function : usage variation - Checking week related formats which are not supported on Windows.
Test strftime() function : usage variation - Checking week related formats which was not supported on Windows before VC14.
--SKIPIF--
<?php
if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
@ -17,7 +17,7 @@ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
echo "*** Testing strftime() : usage variation ***\n";
// Initialise function arguments not being substituted (if any)
setlocale(LC_ALL, "en_US");
setlocale(LC_ALL, "C");
date_default_timezone_set("Asia/Calcutta");
$timestamp = mktime(8, 8, 8, 8, 8, 2008);
@ -41,10 +41,10 @@ foreach($inputs as $key =>$value) {
*** Testing strftime() : usage variation ***
--The ISO 8601:1988 week number--
bool(false)
bool(false)
string(2) "%d"
string(2) "32"
--Weekday as decimal--
bool(false)
bool(false)
string(1) "%d"
string(1) "5"
===DONE===

View file

@ -39,10 +39,6 @@
#include "fopen_wrappers.h" /* needed for is_url */
#include "Zend/zend_exceptions.h"
#ifndef _S_IFDIR
# define _S_IFDIR S_IFDIR
#endif
/* {{{ macros and type definitions */
typedef struct _php_fileinfo {
zend_long options;

View file

@ -706,14 +706,14 @@ static WebPResult VPXEncode(const uint8* Y,
codec_ctl(&enc, VP8E_SET_STATIC_THRESHOLD, 0);
codec_ctl(&enc, VP8E_SET_TOKEN_PARTITIONS, 2);
vpx_img_wrap(&img, IMG_FMT_I420,
vpx_img_wrap(&img, VPX_IMG_FMT_I420,
y_width, y_height, 16, (uint8*)(Y));
img.planes[PLANE_Y] = (uint8*)(Y);
img.planes[PLANE_U] = (uint8*)(U);
img.planes[PLANE_V] = (uint8*)(V);
img.stride[PLANE_Y] = y_stride;
img.stride[PLANE_U] = uv_stride;
img.stride[PLANE_V] = uv_stride;
img.planes[VPX_PLANE_Y] = (uint8*)(Y);
img.planes[VPX_PLANE_U] = (uint8*)(U);
img.planes[VPX_PLANE_V] = (uint8*)(V);
img.stride[VPX_PLANE_Y] = y_stride;
img.stride[VPX_PLANE_U] = uv_stride;
img.stride[VPX_PLANE_V] = uv_stride;
res = vpx_codec_encode(&enc, &img, 0, 1, 0, VPX_DL_BEST_QUALITY);

View file

@ -243,10 +243,6 @@ static ZEND_INI_MH(OnEnable)
#ifdef HAVE_OPCACHE_FILE_CACHE
#ifndef S_ISDIR
# define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
static ZEND_INI_MH(OnUpdateFileCache)
{
if (new_value) {

View file

@ -429,18 +429,6 @@ skip_phar:
}
/* }}} */
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#endif
#ifndef S_ISLNK
#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
#endif
#define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
#define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)
#define IS_EXISTS_CHECK(__t) ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK)
#define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)

View file

@ -460,9 +460,7 @@ bail:
entry.flags = phar_tar_number(hdr->mode, sizeof(hdr->mode)) & PHAR_ENT_PERM_MASK;
entry.timestamp = phar_tar_number(hdr->mtime, sizeof(hdr->mtime));
entry.is_persistent = myphar->is_persistent;
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
if (old && entry.tar_type == TAR_FILE && S_ISDIR(entry.flags)) {
entry.tar_type = TAR_DIR;
}

View file

@ -122,9 +122,6 @@ php_file_globals file_globals;
# include <wchar.h>
#endif
#ifndef S_ISDIR
# define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
/* }}} */
#define PHP_STREAM_TO_ZVAL(stream, arg) \

View file

@ -85,18 +85,6 @@
#include "basic_functions.h"
#include "php_filestat.h"
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#endif
#ifndef S_ISLNK
#define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
#endif
#define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
PHP_RINIT_FUNCTION(filestat) /* {{{ */
{
BG(CurrentStatFile)=NULL;

View file

@ -1200,69 +1200,79 @@ PHP_FUNCTION(explode)
*/
PHPAPI void php_implode(const zend_string *delim, zval *arr, zval *return_value)
{
zval *tmp;
smart_str implstr = {0};
int numelems, i = 0;
zend_string *str;
zval *tmp;
int numelems;
zend_string *str;
char *cptr;
size_t len = 0;
zend_string **strings, **strptr;
numelems = zend_hash_num_elements(Z_ARRVAL_P(arr));
if (numelems == 0) {
RETURN_EMPTY_STRING();
} else if (numelems == 1) {
/* loop to search the first not undefined element... */
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), tmp) {
RETURN_STR(zval_get_string(tmp));
} ZEND_HASH_FOREACH_END();
}
strings = emalloc((sizeof(zend_long) + sizeof(zend_string *)) * numelems);
strptr = strings - 1;
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), tmp) {
again:
switch (Z_TYPE_P(tmp)) {
case IS_STRING:
smart_str_append(&implstr, Z_STR_P(tmp));
break;
case IS_LONG:
smart_str_append_long(&implstr, Z_LVAL_P(tmp));
break;
case IS_TRUE:
smart_str_appendl(&implstr, "1", sizeof("1")-1);
break;
case IS_NULL:
case IS_FALSE:
break;
case IS_DOUBLE: {
char *stmp;
size_t str_len = spprintf(&stmp, 0, "%.*G", (int) EG(precision), Z_DVAL_P(tmp));
smart_str_appendl(&implstr, stmp, str_len);
efree(stmp);
break;
if (Z_TYPE_P(tmp) == IS_LONG) {
double val = Z_LVAL_P(tmp);
*++strptr = NULL;
((zend_long *) (strings + numelems))[strptr - strings] = Z_LVAL_P(tmp);
if (val < 0) {
val = -10 * val;
}
case IS_REFERENCE:
tmp = Z_REFVAL_P(tmp);
goto again;
default:
str = zval_get_string(tmp);
smart_str_append(&implstr, str);
zend_string_release(str);
break;
}
if (++i != numelems) {
smart_str_append(&implstr, delim);
if (val < 10) {
len++;
} else {
len += (int) log10(10 * (double) val);
}
} else {
*++strptr = zval_get_string(tmp);
len += (*strptr)->len;
}
} ZEND_HASH_FOREACH_END();
smart_str_0(&implstr);
str = zend_string_alloc(len + (numelems - 1) * delim->len, 0);
cptr = str->val + str->len;
*cptr = 0;
if (implstr.s) {
RETURN_NEW_STR(implstr.s);
do {
if (*strptr) {
cptr -= (*strptr)->len;
memcpy(cptr, (*strptr)->val, (*strptr)->len);
zend_string_release(*strptr);
} else {
char *oldPtr = cptr;
char oldVal = *cptr;
zend_long val = ((zend_long *) (strings + numelems))[strptr - strings];
cptr = zend_print_long_to_buf(cptr, val);
*oldPtr = oldVal;
}
cptr -= delim->len;
memcpy(cptr, delim->val, delim->len);
} while (--strptr > strings);
if (*strptr) {
memcpy(str->val, (*strptr)->val, (*strptr)->len);
zend_string_release(*strptr);
} else {
smart_str_free(&implstr);
RETURN_EMPTY_STRING();
char *oldPtr = cptr;
char oldVal = *cptr;
zend_print_long_to_buf(cptr, ((zend_long *) (strings + numelems))[strptr - strings]);
*oldPtr = oldVal;
}
efree(strings);
RETURN_NEW_STR(str);
}
/* }}} */

View file

@ -1,5 +1,7 @@
--TEST--
Bug 67395: token_name() does not return name for T_POW and T_POW_EQUAL token
--SKIPIF--
<?php if (!extension_loaded("tokenizer")) print "skip"; ?>
--FILE--
<?php

View file

@ -0,0 +1,19 @@
--TEST--
Parse errors during token_get_all() with TOKEN_PARSE flag
--SKIPIF--
<?php if (!extension_loaded("tokenizer")) print "skip"; ?>
--FILE--
<?php
try {
token_get_all('<?php invalid code;', TOKEN_PARSE);
} catch (ParseException $e) {
echo $e->getMessage(), PHP_EOL;
}
echo "Done";
?>
--EXPECT--
syntax error, unexpected 'code' (T_STRING)
Done

View file

@ -0,0 +1,81 @@
--TEST--
Semi reserved words support: member access
--SKIPIF--
<?php if (!extension_loaded("tokenizer")) print "skip"; ?>
--FILE--
<?php
$tokens = token_get_all('<?php
X::continue;
X::$continue;
$x->$continue;
X::continue();
$x->continue();
X::class;
class X {
const CONTINUE = 1;
public $x = self::CONTINUE + 1;
}
', TOKEN_PARSE);
array_walk($tokens, function($tk) {
if(is_array($tk)) {
if(($t = token_name($tk[0])) == 'T_WHITESPACE') return;
echo "L{$tk[2]}: ".$t." {$tk[1]}", PHP_EOL;
}
else echo $tk, PHP_EOL;
});
echo "Done";
?>
--EXPECTF--
L1: T_OPEN_TAG <?php
L2: T_STRING X
L2: T_DOUBLE_COLON ::
L2: T_STRING continue
;
L3: T_STRING X
L3: T_DOUBLE_COLON ::
L3: T_VARIABLE $continue
;
L4: T_VARIABLE $x
L4: T_OBJECT_OPERATOR ->
L4: T_VARIABLE $continue
;
L5: T_STRING X
L5: T_DOUBLE_COLON ::
L5: T_STRING continue
(
)
;
L6: T_VARIABLE $x
L6: T_OBJECT_OPERATOR ->
L6: T_STRING continue
(
)
;
L7: T_STRING X
L7: T_DOUBLE_COLON ::
L7: T_STRING class
;
L9: T_CLASS class
L9: T_STRING X
{
L10: T_CONST const
L10: T_STRING CONTINUE
=
L10: T_LNUMBER 1
;
L11: T_PUBLIC public
L11: T_VARIABLE $x
=
L11: T_STRING self
L11: T_DOUBLE_COLON ::
L11: T_STRING CONTINUE
+
L11: T_LNUMBER 1
;
}
Done

View file

@ -0,0 +1,68 @@
--TEST--
Semi reserved words support: class const
--SKIPIF--
<?php if (!extension_loaded("tokenizer")) print "skip"; ?>
--FILE--
<?php
$tokens = token_get_all('<?php
class SomeClass {
const CONST = 1;
const CONTINUE = (self::CONST + 1);
const ARRAY = [1, self::CONTINUE => [3, 4], 5];
}
', TOKEN_PARSE);
array_walk($tokens, function($tk) {
if(is_array($tk)) {
if(($t = token_name($tk[0])) == 'T_WHITESPACE') return;
echo "L{$tk[2]}: ".$t." {$tk[1]}", PHP_EOL;
}
else echo $tk, PHP_EOL;
});
echo "Done";
?>
--EXPECTF--
L1: T_OPEN_TAG <?php
L2: T_CLASS class
L2: T_STRING SomeClass
{
L3: T_CONST const
L3: T_STRING CONST
=
L3: T_LNUMBER 1
;
L4: T_CONST const
L4: T_STRING CONTINUE
=
(
L4: T_STRING self
L4: T_DOUBLE_COLON ::
L4: T_STRING CONST
+
L4: T_LNUMBER 1
)
;
L5: T_CONST const
L5: T_STRING ARRAY
=
[
L5: T_LNUMBER 1
,
L5: T_STRING self
L5: T_DOUBLE_COLON ::
L5: T_STRING CONTINUE
L5: T_DOUBLE_ARROW =>
[
L5: T_LNUMBER 3
,
L5: T_LNUMBER 4
]
,
L5: T_LNUMBER 5
]
;
}
Done

View file

@ -19,7 +19,7 @@ var_dump( token_get_all());
echo "-- Testing token_get_all() function with more than expected no. of arguments --\n";
$source = '<?php ?>';
$extra_arg = 10;
var_dump( token_get_all($source, $extra_arg));
var_dump( token_get_all($source, true, $extra_arg));
echo "Done"
?>
@ -28,10 +28,10 @@ echo "Done"
-- Testing token_get_all() function with zero arguments --
Warning: token_get_all() expects exactly 1 parameter, 0 given in %s on line %d
Warning: token_get_all() expects at least 1 parameter, 0 given in %s on line 11
NULL
-- Testing token_get_all() function with more than expected no. of arguments --
Warning: token_get_all() expects exactly 1 parameter, 2 given in %s on line %d
Warning: token_get_all() expects at most 2 parameters, 3 given in %s on line 17
NULL
Done
Done

View file

@ -37,6 +37,12 @@
#define zendcursor LANG_SCNG(yy_cursor)
#define zendlimit LANG_SCNG(yy_limit)
#define TOKEN_PARSE 1
void tokenizer_token_get_all_register_constants(INIT_FUNC_ARGS) {
REGISTER_LONG_CONSTANT("TOKEN_PARSE", TOKEN_PARSE, CONST_CS|CONST_PERSISTENT);
}
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX(arginfo_token_get_all, 0, 0, 1)
ZEND_ARG_INFO(0, source)
@ -83,6 +89,7 @@ ZEND_GET_MODULE(tokenizer)
PHP_MINIT_FUNCTION(tokenizer)
{
tokenizer_register_constants(INIT_FUNC_ARGS_PASSTHRU);
tokenizer_token_get_all_register_constants(INIT_FUNC_ARGS_PASSTHRU);
return SUCCESS;
}
/* }}} */
@ -97,19 +104,33 @@ PHP_MINFO_FUNCTION(tokenizer)
}
/* }}} */
static void tokenize(zval *return_value)
static zend_bool tokenize(zval *return_value, zend_string *source)
{
zval source_zval;
zend_lex_state original_lex_state;
zval token;
zval keyword;
int token_type;
zend_bool destroy;
int token_line = 1;
int need_tokens = -1; // for __halt_compiler lexing. -1 = disabled
int need_tokens = -1; /* for __halt_compiler lexing. -1 = disabled */
ZVAL_STR_COPY(&source_zval, source);
zend_save_lexical_state(&original_lex_state);
if (zend_prepare_string_for_scanning(&source_zval, "") == FAILURE) {
zend_restore_lexical_state(&original_lex_state);
return 0;
}
LANG_SCNG(yy_state) = yycINITIAL;
array_init(return_value);
ZVAL_NULL(&token);
while ((token_type = lex_scan(&token))) {
if(token_type == T_ERROR) break;
destroy = 1;
switch (token_type) {
case T_CLOSE_TAG:
@ -123,8 +144,6 @@ static void tokenize(zval *return_value)
case T_DOC_COMMENT:
destroy = 0;
break;
case T_ERROR:
return;
}
if (token_type >= 256) {
@ -147,13 +166,13 @@ static void tokenize(zval *return_value)
}
ZVAL_NULL(&token);
// after T_HALT_COMPILER collect the next three non-dropped tokens
/* after T_HALT_COMPILER collect the next three non-dropped tokens */
if (need_tokens != -1) {
if (token_type != T_WHITESPACE && token_type != T_OPEN_TAG
&& token_type != T_COMMENT && token_type != T_DOC_COMMENT
&& --need_tokens == 0
&& token_type != T_COMMENT && token_type != T_DOC_COMMENT
&& --need_tokens == 0
) {
// fetch the rest into a T_INLINE_HTML
/* fetch the rest into a T_INLINE_HTML */
if (zendcursor != zendlimit) {
array_init(&keyword);
add_next_index_long(&keyword, T_INLINE_HTML);
@ -169,34 +188,113 @@ static void tokenize(zval *return_value)
token_line = CG(zend_lineno);
}
zval_dtor(&source_zval);
zend_restore_lexical_state(&original_lex_state);
return 1;
}
zval token_stream;
void on_event(zend_php_scanner_event event, int token, int line)
{
zval keyword;
HashTable *tokens_ht;
zval *token_zv;
switch(event) {
case ON_TOKEN:
if (token == T_ERROR || token == END) break;
if (token >= 256) {
array_init(&keyword);
add_next_index_long(&keyword, token);
add_next_index_stringl(&keyword, (char *)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
add_next_index_long(&keyword, line);
add_next_index_zval(&token_stream, &keyword);
} else {
add_next_index_stringl(&token_stream, (char *)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
}
break;
case ON_FEEDBACK:
tokens_ht = Z_ARRVAL(token_stream);
token_zv = zend_hash_index_find(tokens_ht, zend_hash_num_elements(tokens_ht) - 1);
if (token_zv && Z_TYPE_P(token_zv) == IS_ARRAY) {
ZVAL_LONG(zend_hash_index_find(Z_ARRVAL_P(token_zv), 0), token);
}
break;
case ON_STOP:
if (LANG_SCNG(yy_cursor) != LANG_SCNG(yy_limit)) {
array_init(&keyword);
add_next_index_long(&keyword, T_INLINE_HTML);
add_next_index_stringl(&keyword,
(char *)LANG_SCNG(yy_cursor), LANG_SCNG(yy_limit) - LANG_SCNG(yy_cursor));
add_next_index_long(&keyword, CG(zend_lineno));
add_next_index_zval(&token_stream, &keyword);
}
break;
}
}
static zend_bool tokenize_parse(zval *return_value, zend_string *source)
{
zval source_zval;
zend_lex_state original_lex_state;
zend_bool original_in_compilation;
zend_bool success;
ZVAL_STR_COPY(&source_zval, source);
original_in_compilation = CG(in_compilation);
CG(in_compilation) = 1;
zend_save_lexical_state(&original_lex_state);
if ((success = (zend_prepare_string_for_scanning(&source_zval, "") == SUCCESS))) {
CG(ast) = NULL;
CG(ast_arena) = zend_arena_create(1024 * 32);
LANG_SCNG(yy_state) = yycINITIAL;
LANG_SCNG(on_event) = on_event;
array_init(&token_stream);
if((success = (zendparse() == SUCCESS))) {
ZVAL_ZVAL(return_value, &token_stream, 1, 0);
}
zval_dtor(&token_stream);
zend_ast_destroy(CG(ast));
zend_arena_destroy(CG(ast_arena));
}
/* restore compiler and scanner global states */
zend_restore_lexical_state(&original_lex_state);
CG(in_compilation) = original_in_compilation;
zval_dtor(&source_zval);
return success;
}
/* }}} */
/* {{{ proto array token_get_all(string source)
*/
PHP_FUNCTION(token_get_all)
{
zend_string *source;
zval source_zval;
zend_lex_state original_lex_state;
zend_long flags = 0;
zend_bool success;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &source) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &source, &flags) == FAILURE) {
return;
}
ZVAL_STR_COPY(&source_zval, source);
zend_save_lexical_state(&original_lex_state);
if (zend_prepare_string_for_scanning(&source_zval, "") == FAILURE) {
zend_restore_lexical_state(&original_lex_state);
RETURN_FALSE;
if (flags & TOKEN_PARSE) {
success = tokenize_parse(return_value, source);
} else {
success = tokenize(return_value, source);
}
LANG_SCNG(yy_state) = yycINITIAL;
tokenize(return_value);
zend_restore_lexical_state(&original_lex_state);
zval_dtor(&source_zval);
if (!success) RETURN_FALSE;
}
/* }}} */

View file

@ -53,10 +53,6 @@
#include <sys/socket.h>
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#ifdef PHP_WIN32
#include <winsock2.h>
#elif defined(NETWARE) && defined(USE_WINSOCK)

View file

@ -114,10 +114,6 @@
#endif
/* }}} */
#ifndef S_ISREG
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_internal_extensions;
#ifndef ZTS

View file

@ -37,10 +37,6 @@
#include <dirent.h>
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#ifdef PHP_WIN32
#define TRANSLATE_SLASHES_LOWER(path) \
{ \

View file

@ -245,7 +245,6 @@ static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof)
{
char *ksep, *vsep, *val;
size_t klen, vlen;
/* FIXME: string-size_t */
size_t new_vlen;
if (var->ptr >= var->end) {

View file

@ -55,10 +55,6 @@
# define EWOULDBLOCK WSAEWOULDBLOCK
#endif
#ifndef S_ISREG
#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
#endif
/* This functions transforms the first char to 'w' if it's not 'r', 'a' or 'w'
* and strips any subsequent chars except '+' and 'b'.
* Use this to sanitize stream->mode if you call e.g. fdopen, fopencookie or

View file

@ -40,9 +40,6 @@ typedef char * caddr_t;
#define S_IFIFO _IFIFO
#define S_IFBLK _IFBLK
#define S_IFLNK _IFLNK
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#define chdir(path) _chdir(path)
#define mkdir(a, b) _mkdir(a)
#define rmdir(a) _rmdir(a)

View file

@ -91,10 +91,6 @@
# define SOCK_EADDRINUSE WSAEADDRINUSE
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
#endif
#include "ext/standard/file.h" /* for php_set_sock_blocking() :-( */
#include "zend_smart_str.h"
#include "ext/standard/html.h"

View file

@ -106,8 +106,7 @@ static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t
} break;
case IS_UNUSED:
asprintf(&decode, "<unused>");
break;
return NULL;
}
return decode;
} /* }}} */
@ -116,43 +115,72 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars) /*{
{
char *decode[4] = {NULL, NULL, NULL, NULL};
/* OP1 */
switch (op->opcode) {
case ZEND_JMP:
case ZEND_GOTO:
case ZEND_FAST_CALL:
asprintf(&decode[1], "J%ld", OP_JMP_ADDR(op, op->op1) - ops->opcodes);
goto format;
break;
case ZEND_JMPZNZ:
case ZEND_INIT_FCALL:
case ZEND_RECV:
case ZEND_RECV_INIT:
case ZEND_RECV_VARIADIC:
asprintf(&decode[1], "%" PRIu32, op->op1.num);
break;
default:
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
break;
}
/* OP2 */
switch (op->opcode) {
/* TODO: ZEND_FAST_CALL, ZEND_FAST_RET op2 */
case ZEND_JMPZNZ:
asprintf(&decode[2], "J%u or J%" PRIu32, op->op2.opline_num, op->extended_value);
goto result;
break;
case ZEND_JMPZ:
case ZEND_JMPNZ:
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
case ZEND_JMP_SET:
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
asprintf(&decode[2], "J%ld", OP_JMP_ADDR(op, op->op2) - ops->opcodes);
goto result;
break;
case ZEND_RECV_INIT:
goto result;
case ZEND_SEND_VAL:
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_EX:
case ZEND_SEND_USER:
asprintf(&decode[2], "%" PRIu32, op->op2.num);
break;
default:
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars);
decode[2] = phpdbg_decode_op(ops, &op->op2, op->op2_type, vars);
result:
decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type, vars);
format:
asprintf(&decode[0],
"%-20s %-20s %-20s",
decode[1] ? decode[1] : "",
decode[2] ? decode[2] : "",
decode[3] ? decode[3] : "");
break;
}
/* RESULT */
switch (op->opcode) {
case ZEND_CATCH:
asprintf(&decode[2], "%" PRIu32, op->result.num);
break;
default:
decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type, vars);
break;
}
asprintf(&decode[0],
"%-20s %-20s %-20s",
decode[1] ? decode[1] : "",
decode[2] ? decode[2] : "",
decode[3] ? decode[3] : "");
if (decode[1])
free(decode[1]);
if (decode[2])

View file

@ -6,14 +6,14 @@
#################################################
#[User Class: test (3 methods)]
#L%d-%d test::testMethod() %s - 0x%s + 1 ops
# L%d #0 RETURN null <unused> <unused>
# L%d #0 RETURN null
#L%d-%d test::testPrivateMethod() %s - 0x%s + 1 ops
# L%d #0 RETURN null <unused> <unused>
# L%d #0 RETURN null
#L%d-%d test::testProtectedMethod() %s - 0x%s + 1 ops
# L%d #0 RETURN null <unused> <unused>
# L%d #0 RETURN null
#[User Method testMethod (1 ops)]
#L%d-%d test::testMethod() %s - 0x%s + 1 ops
# L%d #0 RETURN null <unused> <unused>
# L%d #0 RETURN null
#################################################
<:
class test {

View file

@ -1,16 +0,0 @@
--TEST--
Bug #51709 (Can't use keywords as method names)
--FILE--
<?php
class foo {
static function for() {
echo "1";
}
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
Parse error: syntax error, unexpected %s, expecting %s in %sbug51709_1.php on line %d

View file

@ -1,16 +0,0 @@
--TEST--
Bug #51709 (Can't use keywords as method names)
--FILE--
<?php
class foo {
static function goto() {
echo "1";
}
}
?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
Parse error: syntax error, unexpected %s, expecting %s in %sbug51709_2.php on line %d

View file

@ -342,6 +342,22 @@ foreach ($ENCHANT_DLLS as $dll) {
}
}
$SASL_DLLS = $php_build_dir . "/bin/sasl2/sasl*.dll";
$fls = glob($SASL_DLLS);
if (!empty($fls)) {
$sasl_dest_dir = "$dist_dir/sasl2";
if (!file_exists($sasl_dest_dir) || !is_dir($sasl_dest_dir)) {
if (!mkdir("$sasl_dest_dir", 0777, true)) {
echo "WARNING: couldn't create '$sasl_dest_dir' for SASL2 auth plugins ";
}
}
foreach ($fls as $fl) {
if (!copy($fl, "$sasl_dest_dir/" . basename($fl))) {
echo "WARNING: couldn't copy $fl into the $sasl_dest_dir";
}
}
}
/* and those for pecl */
foreach ($pecl_dll_deps as $dll) {
if (in_array($dll, $extra_dll_deps)) {

View file

@ -71,12 +71,6 @@
# define ARG_MAX 14500
# endif
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR)
#endif
#ifndef S_ISLNK
#define S_ISLNK(m) (0)
#endif
#endif
#include "php.h"