Merge in master

This commit is contained in:
Anthony Ferrara 2015-02-18 10:35:39 -05:00
commit 9109e48749
367 changed files with 10624 additions and 33900 deletions

View File

@ -401,8 +401,8 @@ MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: json
PRIMARY MAINTAINER: Unknown
MAINTENANCE: Odd fixes
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.2
-------------------------------------------------------------------------------

14
NEWS
View File

@ -8,9 +8,9 @@
. Update the MIME type list from the one shipped by Apache HTTPD. (Adam)
- Core:
. Fixed #68933 (Invalid read of size 8 in zend_std_read_property).
. Fixed bug #68933 (Invalid read of size 8 in zend_std_read_property).
(Laruence, arjen at react dot com)
. Fixed #68868 (Segfault in clean_non_persistent_constants() in SugarCRM
. Fixed bug #68868 (Segfault in clean_non_persistent_constants() in SugarCRM
6.5.20). (Laruence)
. Fixed bug #68104 (Segfault while pre-evaluating a disabled function).
(Laruence)
@ -19,7 +19,7 @@
. Added PHP_INT_MIN constant. (Andrea)
. Added Closure::call() method. (Andrea)
. Implemented FR #38409 (parse_ini_file() looses the type of booleans). (Tjerk)
. Fixed #67959 (Segfault when calling phpversion('spl')). (Florian)
. Fixed bug #67959 (Segfault when calling phpversion('spl')). (Florian)
. Implemented the RFC `Catchable "Call to a member function bar() on a
non-object"`. (Timm)
. Added options parameter for unserialize allowing to specify acceptable
@ -45,6 +45,8 @@
. Invalid octal literals in source code now produce compile errors, fixes PHPSadness #31. (Andrea)
. Removed dl() function on fpm-fcgi. (Nikita)
. Removed support for hexadecimal numeric strings. (Nikita)
. Removed obsolete extensions and SAPIs. See the full list in UPGRADING. (Anatol)
. Added NULL byte protection to exec, system and passthru. (Yasuo)
- Curl:
. Fixed bug #68937 (Segfault in curl_multi_exec). (Laruence)
@ -94,7 +96,7 @@
+ Opcache). (Laruence)
- OpenSSL:
. Fix bug #61285, #68329, #68046, #41631: encrypted streams don't observe
. Fixed bug #61285, #68329, #68046, #41631: encrypted streams don't observe
socket timeouts (Brad Broerman)
- pcntl:
@ -131,12 +133,12 @@
. Fixed bug #68479 (Added escape parameter to SplFileObject::fputcsv). (Salathe)
- Sqlite3:
. Fix bug #68260 (SQLite3Result::fetchArray declares wrong
. Fixed bug #68260 (SQLite3Result::fetchArray declares wrong
required_num_args). (Julien)
- Standard:
. Removed call_user_method() and call_user_method_array() functions. (Kalle)
. Fix user session handlers (See rfc:session.user.return-value). (Sara)
. Fixed user session handlers (See rfc:session.user.return-value). (Sara)
. Added intdiv() function. (Andrea)
. Improved precision of log() function for base 2 and 10. (Marc Bennewitz)
. Remove string category support in setlocale(). (Nikita)

View File

@ -168,9 +168,13 @@ TSRM_API void *tsrm_get_ls_cache(void);
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
#define TSRMG_STATIC(id, type, element) (((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
#define TSRMLS_CACHE_EXTERN extern TSRM_TLS void *TSRMLS_CACHE
#define TSRMLS_CACHE_DEFINE TSRM_TLS void *TSRMLS_CACHE = NULL
#define TSRMLS_CACHE_UPDATE if (!TSRMLS_CACHE) TSRMLS_CACHE = tsrm_get_ls_cache()
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL
#if ZEND_DEBUG
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
#else
#define TSRMLS_CACHE_UPDATE() if (!TSRMLS_CACHE) TSRMLS_CACHE = tsrm_get_ls_cache()
#endif
#define TSRMLS_CACHE _tsrm_ls_cache
/* BC only */
@ -191,9 +195,9 @@ TSRM_API void *tsrm_get_ls_cache(void);
#define TSRMLS_SET_CTX(ctx)
#define TSRMG_STATIC(id, type, element)
#define TSRMLS_CACHE_EXTERN
#define TSRMLS_CACHE_DEFINE
#define TSRMLS_CACHE_UPDATE
#define TSRMLS_CACHE_EXTERN()
#define TSRMLS_CACHE_DEFINE()
#define TSRMLS_CACHE_UPDATE()
#define TSRMLS_CACHE
/* BC only */

View File

@ -43,7 +43,7 @@ static tsrm_win32_globals win32_globals;
static void tsrm_win32_ctor(tsrm_win32_globals *globals)
{
#ifdef ZTS
TSRMLS_CACHE_UPDATE;
TSRMLS_CACHE_UPDATE();
#endif
globals->process = NULL;
globals->shm = NULL;

View File

@ -72,7 +72,7 @@ typedef struct {
#ifdef ZTS
# define TWG(v) TSRMG_STATIC(win32_globals_id, tsrm_win32_globals *, v)
TSRMLS_CACHE_EXTERN;
TSRMLS_CACHE_EXTERN();
#else
# define TWG(v) (win32_globals.v)
#endif

376
UPGRADING
View File

@ -9,7 +9,7 @@ PHP X.Y UPGRADE NOTES
5. Changed Functions
6. New Functions
7. New Classes and Interfaces
8. Removed Extensions
8. Removed Extensions and SAPIs
9. Other Changes to Extensions
10. New Global Constants
11. Changes to INI File Handling
@ -21,58 +21,329 @@ PHP X.Y UPGRADE NOTES
1. Backward Incompatible Changes
========================================
- Core
. list() now always supports ArrayAccess and never supports strings.
Previously both were accepted in some situations and not in others.
(RFC: https://wiki.php.net/rfc/fix_list_behavior_inconsistency)
. Bitwise shifts by negative numbers of bits are disallowed (throws E_WARNING
and gives FALSE, like a division by zero).
. Left bitwise shifts by a number of bits beyond the bit width of an integer
will always result in 0, even on CPUs which wrap around.
. Right bitwise shifts by a number of bits beyond the bit width of an integer
will always result in 0 or -1 (depending on sign), even on CPUs which wrap
around.
Language changes
================
Changes to variable handling
----------------------------
* Indirect variable, property and method references are now interpreted with
left-to-right semantics. Some examples:
$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
$foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
$foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()
To restore the previous behavior add explicit curly braces:
${$foo['bar']['baz']}
$foo->{$bar['baz']}
$foo->{$bar['baz']}()
Foo::{$bar['baz']}()
* The global keyword now only accepts simple variables. Instead of
global $$foo->bar;
it is now required to write the following:
global ${$foo->bar};
* Parentheses around variables or function calls no longer have any influence
on behavior. For example the following code, where the result of a function
call is passed to a by-reference function
function getArray() { return [1, 2, 3]; }
$last = array_pop(getArray());
// Strict Standards: Only variables should be passed by reference
$last = array_pop((getArray()));
// Strict Standards: Only variables should be passed by reference
will now throw a strict standards error irregardless of whether parentheses
are used. Previously no notice was generated in the second case.
* Array elements or object properties that are automatically created during
by-reference assignments will now result in a different order. For example
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
now results in the array ["a" => 1, "b" => 1], while previously the result
was ["b" => 1, "a" => 1];
Relevant RFCs:
* https://wiki.php.net/rfc/uniform_variable_syntax
* https://wiki.php.net/rfc/abstract_syntax_tree
Changes to list()
-----------------
* list() will no longer assign variables in reverse order. For example
list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);
will now result in $array == [1, 2, 3] rather than [3, 2, 1]. Note that only
the **order** of the assignments changed, but the assigned values stay the
same. E.g. a normal usage like
list($a, $b, $c) = [1, 2, 3];
// $a = 1; $b = 2; $c = 3;
will retain its current behavior.
* Empty list() assignments are no longer allowed. As such all of the following
are invalid:
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
* list() no longer supports unpacking strings (while previously this was only
supported in some cases). The code
$string = "xy";
list($x, $y) = $string;
will now result in $x == null and $y == null (without notices) instead of
$x == "x" and $y == "y". Furthermore list() is now always guaranteed to
work with objects implementing ArrayAccess, e.g.
list($a, $b) = (object) new ArrayObject([0, 1]);
will now result in $a == 0 and $b == 1. Previously both $a and $b were null.
Relevant RFCs:
* https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list
* https://wiki.php.net/rfc/fix_list_behavior_inconsistency
Changes to foreach
------------------
* Iteration with foreach() no longer has any effect on the internal array
pointer, which can be accessed through the current()/next()/etc family of
functions. For example
$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}
will now print the value int(0) three times. Previously the output was int(1),
int(2) and bool(false).
* When iterating arrays by-value, foreach will now always operate on a copy of
the array, as such changes to the array during iteration will not influence
iteration behavior. For example
$array = [0, 1, 2];
$ref =& $array; // Necessary to trigger the old behavior
foreach ($array as $val) {
var_dump($val);
unset($array[1]);
}
will now print all three elements (0 1 2), while previously the second element
1 was skipped (0 2).
* When iterating arrays by-reference, modifications to the array will continue
to influence the iteration. However PHP will now do a better job of
maintaining a correct position in a number of cases. E.g. appending to an
array during by-reference iteration
$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
will now iterate over the appended element as well. As such the output of this
example will now be "int(0) int(1)", while previously it was only "int(0)".
* Iteration of plain (non-Traversable) objects by-value or by-reference will
behave like by-reference iteration of arrays. This matches the previous
behavior apart from the more accurate position management mentioned in the
previous point.
* Iteration of Traversable objects remains unchanged.
Relevant RFC: https://wiki.php.net/rfc/php7_foreach
Changes to parameter handling
-----------------------------
* It is no longer possible to define two function parameters with the same name.
For example, the following method will trigger a compile-time error:
public function foo($a, $b, $unused, $unused) {
// ...
}
Code like this should be changed to use distinct parameter names, for example:
public function foo($a, $b, $unused1, $unused2) {
// ...
}
* The func_get_arg() and func_get_args() functions will no longer return the
original value that was passed to a parameter and will instead provide the
current value (which might have been modified). For example
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);
will now print "2" instead of "1". This code should be changed to either
perform modifications only after calling func_get_arg(s)
function foo($x) {
var_dump(func_get_arg(0));
$x++;
}
or avoid modifying the parameters altogether:
function foo($x) {
$newX = $x + 1;
var_dump(func_get_arg(0));
}
* Similarly exception backtraces will no longer display the original value that
was passed to a function and show the modified value instead. For example
function foo($x) {
$x = 42;
throw new Exception;
}
foo("string");
will now result in the stack trace
Stack trace:
#0 file.php(4): foo(42)
#1 {main}
while previously it was:
Stack trace:
#0 file.php(4): foo('string')
#1 {main}
While this should not impact runtime behavior of your code, it is worthwhile
to be aware of this difference for debugging purposes.
The same limitation also applies to debug_backtrace() and other functions
inspecting function arguments.
Relevant RFC: https://wiki.php.net/phpng
Changes to integer handling
---------------------------
* Invalid octal literals (containing digits larger than 7) now produce compile
errors. For example, the following is no longer valid:
$i = 0781; // 8 is not a valid octal digit!
Previously the invalid digits (and any following valid digits) were simply
ignored. As such $i previously held the value 7, because the last two digits
were silently discarded.
* Bitwise shifts by negative numbers will now throw a warning and return false:
var_dump(1 >> -1); // bool(false)
// Warning: Bit shift by negative number
* Left bitwise shifts by a number of bits beyond the bit width of an integer
will always result in 0:
var_dump(1 << 64); // int(0)
Previously the behavior of this code was dependent on the used CPU
architecture. For example on x86 (including x86-64) the result was int(1),
because the shift operand was wrapped.
* Similarly right bitwise shifts by a number of bits beyond the bit width of an
integer will always result in 0 or -1 (depending on sign):
var_dump(1 >> 64); // int(0)
var_dump(-1 >> 64); // int(-1)
Relevant RFC: https://wiki.php.net/rfc/integer_semantics
Changes to string handling
--------------------------
* Strings that contain hexadecimal numbers are no longer considered to be
numeric and don't receive special treatment anymore. Some examples of the
new behavior:
var_dump("0x123" == "291"); // bool(false) (previously true)
var_dump(is_numeric("0x123")); // bool(false) (previously true)
var_dump("0xe" + "0x1"); // int(0) (previously 16)
var_dump(substr("foo", "0x1")); // string(3) "foo" (previously "oo")
// Notice: A non well formed numeric value encountered
filter_var() can be used to check if a string contains a hexadecimal number
or convert such a string into an integer:
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
throw new Exception("Invalid integer!");
}
var_dump($num); // int(65535)
* Due to the addition of the Unicode Codepoint Escape Syntax for double-quoted
strings and heredocs, "\u{" followed by an invalid sequence will now result in
an error:
$str = "\u{xyz}"; // Fatal error: Invalid UTF-8 codepoint escape sequence
To avoid this the leading backslash should be escaped:
$str = "\\u{xyz}"; // Works fine
However, "\u" without a following { is unaffected. As such the following code
won't error and will work the same as before:
$str = "\u202e"; // Works fine
Relevant RFCs:
* https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings
* https://wiki.php.net/rfc/unicode_escape
Other language changes
----------------------
. Removed ASP (<%) and script (<script language=php>) tags.
(RFC: https://wiki.php.net/rfc/remove_alternative_php_tags)
. call_user_method() and call_user_method_array() no longer exists.
. PHP 7 doesn't keep original values of arguments passed to user functions,
so func_get_arg() and func_get_args() will return current value of argument
instead of the actually passed. The following code is going to be affected:
function foo($x) { $x = 2; return func_get_arg(0);} var_dump(foo(1));
It will now produce 2, not 1.
. Function parameters with duplicate name are not allowed anymore. Definitions
like “function foo($x,$x) {}” will lead to compile time error.
. Indirect variable, property and method references are now interpreted with
left-to-right semantics. See details in:
https://wiki.php.net/rfc/uniform_variable_syntax#semantic_differences_in_existing_syntax
. The global keyword now only accepts simple variables. See details in:
https://wiki.php.net/rfc/uniform_variable_syntax#global_keyword_takes_only_simple_variables
. The addition of Unicode Codepoint Escape Syntax for double-quoted strings
and heredocs means that \u{ followed by an invalid sequence will now error.
However, \u without a following { is unaffected, so "\u202e" won't error and
will work the same as before.
. zend_function.common.num_args don't include the variadic argument anymore.
. ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an
output buffer is created in an output buffer handler.
. Removed support for assigning the result of new by reference.
. Removed support for scoped calls to non-static methods from an incompatible
$this context. See details in https://wiki.php.net/rfc/incompat_ctx.
. Removed support for #-style comments in ini files. Use ;-style comments
instead.
. Added zend_memnstr_ex, which is based on string matching sunday algo.
. Added zend_memnrstr, zend_memnrstr_ex.
. $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.
Standard library changes
========================
. call_user_method() and call_user_method_array() no longer exists.
. ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an
output buffer is created in an output buffer handler.
. Added hybrid sorting algo zend_sort for better performance.
. Added stable sorting algo zend_insert_sort.
. Invalid octal literals in source code now produce compile errors, fixing
PHPSadness #31. Previously, the invalid digits (and any following valid
digits) were simply ignored, such that 0781 became 7.
. Removed dl() function on fpm-fcgi.
. Removed support for hexadecimal numeric strings. This means that some
operations like == will no longer specially interpret strings containing
hexadecimal numbers. Furthermore is_numeric() will not consider hexadecimal
strings to be numeric (use FILTER_VALIDATE_INT instead).
(RFC: https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings)
. $HTTP_RAW_POST_DATA is no longer available. Use the php://input stream instead.
Other
=====
- Date:
. Removed $is_dst parameter from mktime() and gmmktime().
@ -170,9 +441,26 @@ PHP X.Y UPGRADE NOTES
========================================
8. Removed Extensions
8. Removed Extensions and SAPIs
========================================
- sapi/aolserver
- sapi/apache
- sapi/apache_hooks
- sapi/apache2filter
- sapi/caudium
- sapi/continuity
- sapi/isapi
- sapi/milter
- sapi/phttpd
- sapi/pi3web
- sapi/roxen
- sapi/thttpd
- sapi/tux
- sapi/webjames
- ext/mssql
- ext/sybase_ct
For more details see https://wiki.php.net/rfc/removal_of_dead_sapis_and_exts
========================================
9. Other Changes to Extensions

View File

@ -23,4 +23,4 @@ var_dump(key($arr["v"]));
int(0)
int(0)
int(0)
NULL
int(0)

View File

@ -23,4 +23,4 @@ int(0)
int(0)
int(1)
int(2)
NULL
int(0)

42
Zend/tests/bug69017.phpt Normal file
View File

@ -0,0 +1,42 @@
--TEST--
#69017 (Fail to push to the empty array with the constant value defined in class scope)
--FILE--
<?php
class c1
{
const ZERO = 0;
const ONE = 1;
const MAX = PHP_INT_MAX;
public static $a1 = array(self::ONE => 'one');
public static $a2 = array(self::ZERO => 'zero');
public static $a3 = array(self::MAX => 'zero');
}
c1::$a1[] = 1;
c1::$a2[] = 1;
c1::$a3[] = 1;
var_dump(c1::$a1);
var_dump(c1::$a2);
var_dump(c1::$a3);
?>
--EXPECTF--
Warning: Cannot add element to the array as the next element is already occupied in %sbug69017.php on line %d
array(2) {
[1]=>
string(3) "one"
[2]=>
int(1)
}
array(2) {
[0]=>
string(4) "zero"
[1]=>
int(1)
}
array(1) {
[%d]=>
string(4) "zero"
}

15
Zend/tests/bug69025.phpt Normal file
View File

@ -0,0 +1,15 @@
--TEST--
Bug #69025 (Invalid read of size 4 when calling __callStatic)
--FILE--
<?php
class A {
public static function __callStatic($method, $args)
{
}
}
A::init();
?>
OK
--EXPECT--
OK

View File

@ -0,0 +1,71 @@
--TEST--
Iterator exceptions in foreach by value
--FILE--
<?php
class IT implements Iterator {
private $n = 0;
private $count = 0;
private $trap = null;
function __construct($count, $trap = null) {
$this->count = $count;
$this->trap = $trap;
}
function trap($trap) {
if ($trap === $this->trap) {
throw new Exception($trap);
}
}
function rewind() {$this->trap(__FUNCTION__); $this->n = 0;}
function valid() {$this->trap(__FUNCTION__); return $this->n < $this->count;}
function key() {$this->trap(__FUNCTION__); return $this->n;}
function current() {$this->trap(__FUNCTION__); return $this->n;}
function next() {$this->trap(__FUNCTION__); $this->n++;}
}
foreach(['rewind', 'valid', 'key', 'current', 'next'] as $trap) {
$obj = new IT(3, $trap);
try {
// IS_CV
foreach ($obj as $key => $val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
unset($obj);
try {
// IS_VAR
foreach (new IT(3, $trap) as $key => $val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
try {
// IS_TMP_VAR
foreach ((object)new IT(2, $trap) as $key => $val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
}
?>
--EXPECT--
rewind
rewind
rewind
valid
valid
valid
key
key
key
current
current
current
0
next
0
next
0
next

View File

@ -0,0 +1,65 @@
--TEST--
Iterator exceptions in foreach by reference
--FILE--
<?php
class IT extends ArrayIterator {
private $n = 0;
function __construct($trap = null) {
parent::__construct([0, 1]);
$this->trap = $trap;
}
function trap($trap) {
if ($trap === $this->trap) {
throw new Exception($trap);
}
}
function rewind() {$this->trap(__FUNCTION__); return parent::rewind();}
function valid() {$this->trap(__FUNCTION__); return parent::valid();}
function key() {$this->trap(__FUNCTION__); return parent::key();}
function next() {$this->trap(__FUNCTION__); return parent::next();}
}
foreach(['rewind', 'valid', 'key', 'next'] as $trap) {
$obj = new IT($trap);
try {
// IS_CV
foreach ($obj as $key => &$val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
unset($obj);
try {
// IS_VAR
foreach (new IT($trap) as $key => &$val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
try {
// IS_TMP_VAR
foreach ((object)new IT($trap) as $key => &$val) echo "$val\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
}
?>
--EXPECT--
rewind
rewind
rewind
valid
valid
valid
key
key
key
0
next
0
next
0
next

View File

@ -0,0 +1,22 @@
--TEST--
Nested foreach by reference on the same array
--FILE--
<?php
$a = [1,2,3];
foreach($a as &$x) {
foreach($a as &$y) {
echo "$x-$y\n";
$y++;
}
}
?>
--EXPECT--
1-1
2-2
2-3
3-2
3-3
4-4
5-3
5-4
5-5

View File

@ -0,0 +1,20 @@
--TEST--
Foreach by reference on constant
--FILE--
<?php
for ($i = 0; $i < 3; $i++) {
foreach ([1,2,3] as &$val) {
echo "$val\n";
}
}
?>
--EXPECT--
1
2
3
1
2
3
1
2
3

View File

@ -0,0 +1,13 @@
--TEST--
Foreach by reference and inserting new element when we are already at the end
--FILE--
<?php
$a = [1];
foreach($a as &$v) {
echo "$v\n";
$a[1]=2;
}
?>
--EXPECT--
1
2

View File

@ -0,0 +1,21 @@
--TEST--
Nested foreach by reference and array modification
--FILE--
<?php
$a = [0, 1, 2, 3];
foreach ($a as &$x) {
foreach ($a as &$y) {
echo "$x - $y\n";
if ($x == 0 && $y == 1) {
unset($a[2]);
unset($a[1]);
}
}
}
?>
--EXPECT--
0 - 0
0 - 1
0 - 3
3 - 0
3 - 3

View File

@ -0,0 +1,40 @@
--TEST--
Nested foreach by reference and array modification with resize
--FILE--
<?php
$a = [0, 1, 2, 3, 4, 5, 6, 7];
unset($a[0], $a[1], $a[2], $a[3]);
foreach ($a as &$ref) {
foreach ($a as &$ref2) {
echo "$ref-$ref2\n";
if ($ref == 5 && $ref2 == 6) {
$a[42] = 8;
}
}
}
?>
--EXPECT--
4-4
4-5
4-6
4-7
5-4
5-5
5-6
5-7
5-8
6-4
6-5
6-6
6-7
6-8
7-4
7-5
7-6
7-7
7-8
8-4
8-5
8-6
8-7
8-8

View File

@ -0,0 +1,40 @@
--TEST--
Nested foreach by value over object and object modification with resize
--FILE--
<?php
$o = (object)['a'=>0, 'b'=>1, 'c'=>2, 'd'=>3, 'e'=>4, 'f'=>5, 'g'=>6, 'h'=>7];
unset($o->a, $o->b, $o->c, $o->d);
foreach ($o as $v1) {
foreach ($o as $v2) {
echo "$v1-$v2\n";
if ($v1 == 5 && $v2 == 6) {
$o->i = 8;
}
}
}
?>
--EXPECT--
4-4
4-5
4-6
4-7
5-4
5-5
5-6
5-7
5-8
6-4
6-5
6-6
6-7
6-8
7-4
7-5
7-6
7-7
7-8
8-4
8-5
8-6
8-7
8-8

View File

@ -0,0 +1,19 @@
--TEST--
sort() functions precerve foreach by reference iterator pointer
--FILE--
<?php
$a = [1,2,3,4,5,0];
foreach($a as &$v) {
echo "$v\n";
if ($v == 3) {
rsort($a);
}
}
?>
--EXPECT--
1
2
3
2
1
0

View File

@ -0,0 +1,18 @@
--TEST--
array_walk() function precerve foreach by reference iterator pointer
--FILE--
<?php
$a = [1,2,3,4,5];
foreach($a as &$v) {
echo "$v\n";
if ($v == 3) {
array_walk($a, function (&$x) {$x+=10;});
}
}
?>
--EXPECT--
1
2
3
14
15

View File

@ -0,0 +1,17 @@
--TEST--
array_push() function precerve foreach by reference iterator pointer
--FILE--
<?php
$a = [1,2,3];
foreach($a as &$v) {
echo "$v\n";
if ($v == 3) {
array_push($a, 4);
}
}
?>
--EXPECT--
1
2
3
4

View File

@ -0,0 +1,15 @@
--TEST--
array_pop() function precerve foreach by reference iterator pointer
--FILE--
<?php
$a = [1,2,3];
foreach($a as &$v) {
echo "$v\n";
if ($v == 2) {
array_pop($a);
}
}
?>
--EXPECT--
1
2

View File

@ -0,0 +1,18 @@
--TEST--
array_shift() function precerve foreach by reference iterator pointer
--FILE--
<?php
$a = [1,2,3,4];
foreach($a as &$v) {
echo "$v\n";
array_shift($a);
}
var_dump($a);
?>
--EXPECT--
1
2
3
4
array(0) {
}

View File

@ -0,0 +1,18 @@
--TEST--
array_unshift() function precerve foreach by reference iterator pointer
--FILE--
<?php
$a = [1,2,3];
foreach($a as &$v) {
echo "$v\n";
if ($v == 2) {
array_unshift($a, 0, 0, 0, 0, 0, 0, 0, 0);
}
}
var_dump(count($a));
?>
--EXPECT--
1
2
3
int(11)

111
Zend/tests/foreach_017.phpt Normal file
View File

@ -0,0 +1,111 @@
--TEST--
array_splice() function precerve foreach by reference iterator pointer
--FILE--
<?php
/* remove before */
$done = 0;
$a = [0,1,2,3,4];
foreach($a as &$v) {
echo "$v\n";
if (!$done && $v == 3) {
$done = 1;
array_splice($a, 1, 2);
}
}
echo "\n";
/* remove after */
$done = 0;
$a = [0,1,2,3,4];
foreach($a as &$v) {
echo "$v\n";
if (!$done && $v == 0) {
$done = 1;
array_splice($a, 2, 2);
}
}
echo "\n";
/* remove current */
$done = 0;
$a = [0,1,2,3,4];
foreach($a as &$v) {
echo "$v\n";
if (!$done && $v == 2) {
$done = 1;
array_splice($a, 1, 3);
}
}
echo "\n";
$replacement = ['x', 'y', 'z'];
/* replace before */
$done = 0;
$a = [0,1,2,3,4];
foreach($a as &$v) {
echo "$v\n";
if ($done && $v == 3) {
$done = 1;
array_splice($a, 1, 2, $replacement);
}
}
echo "\n";
/* replace after */
$done = 0;
$a = [0,1,2,3,4];
foreach($a as &$v) {
echo "$v\n";
if (!$done && $v == 0) {
$done = 1;
array_splice($a, 2, 2, $replacement);
}
}
echo "\n";
/* replace current */
$done = 0;
$a = [0,1,2,3,4];
foreach($a as &$v) {
echo "$v\n";
if (!$done && $v == 2) {
$done = 1;
array_splice($a, 1, 3, $replacement);
}
}
echo "\n";
?>
--EXPECT--
0
1
2
3
4
0
1
4
0
1
2
4
0
1
2
3
4
0
1
x
y
z
4
0
1
2
4

View File

@ -0,0 +1,27 @@
--TEST--
Const class member access with deference
--FILE--
<?php
class A {
const A = ['a' => ['b' => 'c']];
}
var_dump(A::A);
var_dump(A::A['a']);
var_dump(A::A['a']['b']);
?>
--EXPECT--
array(1) {
["a"]=>
array(1) {
["b"]=>
string(1) "c"
}
}
array(1) {
["b"]=>
string(1) "c"
}
string(1) "c"

View File

@ -120,7 +120,7 @@ static HashTable *global_class_table = NULL;
static HashTable *global_constants_table = NULL;
static HashTable *global_auto_globals_table = NULL;
static HashTable *global_persistent_list = NULL;
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_API zend_utility_values zend_uv;
@ -465,7 +465,7 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{
static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
{
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
zend_startup_constants();
zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
zend_init_rsrc_plist();
@ -550,8 +550,9 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
zval globals;
ZVAL_ARR(&globals, &EG(symbol_table));
Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT);
ZVAL_NEW_REF(&globals, &globals);
zend_hash_update(&EG(symbol_table).ht, name, &globals);
zend_hash_update(&EG(symbol_table), name, &globals);
return 0;
}
/* }}} */
@ -563,7 +564,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
zend_executor_globals *executor_globals;
extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
extern ZEND_API ts_rsrc_id language_scanner_globals_id;
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#else
extern zend_ini_scanner_globals ini_scanner_globals;
extern zend_php_scanner_globals language_scanner_globals;
@ -1129,8 +1130,7 @@ static void zend_error_va_list(int type, const char *format, va_list args)
if (!symbol_table) {
ZVAL_NULL(&params[4]);
} else {
ZVAL_NEW_ARR(&params[4]);
zend_array_dup(Z_ARRVAL(params[4]), &symbol_table->ht);
ZVAL_ARR(&params[4], zend_array_dup(symbol_table));
}
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));

View File

@ -62,19 +62,19 @@
#ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE
#define ZEND_TSRMG TSRMG_STATIC
#define ZEND_TSRMLS_CACHE_EXTERN TSRMLS_CACHE_EXTERN
#define ZEND_TSRMLS_CACHE_DEFINE TSRMLS_CACHE_DEFINE
#define ZEND_TSRMLS_CACHE_UPDATE TSRMLS_CACHE_UPDATE
#define ZEND_TSRMLS_CACHE_EXTERN() TSRMLS_CACHE_EXTERN()
#define ZEND_TSRMLS_CACHE_DEFINE() TSRMLS_CACHE_DEFINE()
#define ZEND_TSRMLS_CACHE_UPDATE() TSRMLS_CACHE_UPDATE()
#define ZEND_TSRMLS_CACHE TSRMLS_CACHE
#else
#define ZEND_TSRMG TSRMG
#define ZEND_TSRMLS_CACHE_EXTERN
#define ZEND_TSRMLS_CACHE_DEFINE
#define ZEND_TSRMLS_CACHE_UPDATE
#define ZEND_TSRMLS_CACHE_EXTERN()
#define ZEND_TSRMLS_CACHE_DEFINE()
#define ZEND_TSRMLS_CACHE_UPDATE()
#define ZEND_TSRMLS_CACHE
#endif
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
#ifdef HAVE_NORETURN
# ifdef ZEND_NORETRUN_ALIAS

View File

@ -911,7 +911,7 @@ ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this
/* }}} */
/* Argument parsing API -- andrei */
ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC) /* {{{ */
ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
{
ZVAL_NEW_ARR(arg);
_zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
@ -1110,11 +1110,14 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
* calling zend_merge_properties(). */
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC) /* {{{ */
{
if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
char *what = (class_type->ce_flags & ZEND_ACC_INTERFACE) ? "interface"
:((class_type->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) ? "trait"
: "abstract class";
zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name->val);
if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
if (class_type->ce_flags & ZEND_ACC_INTERFACE) {
zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", class_type->name->val);
} else if (class_type->ce_flags & ZEND_ACC_TRAIT) {
zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", class_type->name->val);
} else {
zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", class_type->name->val);
}
}
zend_update_class_constants(class_type);

View File

@ -372,7 +372,7 @@ ZEND_API char *zend_get_type_by_const(int type);
#define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC)
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC)
#define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC)
ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC);
ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC);
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC);
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC);
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC);

View File

@ -2388,7 +2388,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
return;
}
#endif
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
alloc_globals->mm_heap = zend_mm_init();
}

View File

@ -1140,8 +1140,7 @@ ZEND_FUNCTION(get_object_vars)
if (!zobj->ce->default_properties_count && properties == zobj->properties) {
/* fast copy */
ZVAL_NEW_ARR(return_value);
zend_array_dup(Z_ARRVAL_P(return_value), properties);
ZVAL_ARR(return_value, zend_array_dup(properties));
} else {
array_init_size(return_value, zend_hash_num_elements(properties));
@ -1378,14 +1377,15 @@ ZEND_FUNCTION(class_exists)
} else {
lc_name = zend_string_tolower(class_name);
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
zend_string_release(lc_name);
RETURN_BOOL(ce && !((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
} else {
ce = zend_lookup_class(class_name);
}
ce = zend_lookup_class(class_name);
if (ce) {
RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT - ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) == 0);
RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) == 0);
} else {
RETURN_FALSE;
}
@ -1462,14 +1462,15 @@ ZEND_FUNCTION(trait_exists)
} else {
lc_name = zend_string_tolower(trait_name);
}
ce = zend_hash_find_ptr(EG(class_table), lc_name);
zend_string_release(lc_name);
RETURN_BOOL(ce && ((ce->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
} else {
ce = zend_lookup_class(trait_name);
}
ce = zend_lookup_class(trait_name);
if (ce) {
RETURN_BOOL((ce->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
RETURN_BOOL((ce->ce_flags & ZEND_ACC_TRAIT) != 0);
} else {
RETURN_FALSE;
}
@ -1806,7 +1807,7 @@ ZEND_FUNCTION(get_declared_traits)
Returns an array of all declared classes. */
ZEND_FUNCTION(get_declared_classes)
{
uint32_t mask = ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
uint32_t mask = ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT;
uint32_t comply = 0;
if (zend_parse_parameters_none() == FAILURE) {
@ -1881,8 +1882,7 @@ ZEND_FUNCTION(get_defined_vars)
{
zend_array *symbol_table = zend_rebuild_symbol_table();
ZVAL_NEW_ARR(return_value);
zend_array_dup(Z_ARRVAL_P(return_value), &symbol_table->ht);
ZVAL_ARR(return_value, zend_array_dup(symbol_table));
}
/* }}} */

View File

@ -349,8 +349,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{
if (closure->debug_info->u.v.nApplyCount == 0) {
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
HashTable *static_variables = closure->func.op_array.static_variables;
ZVAL_NEW_ARR(&val);
zend_array_dup(Z_ARRVAL(val), static_variables);
ZVAL_ARR(&val, zend_array_dup(static_variables));
zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val);
}

View File

@ -895,7 +895,7 @@ static int generate_free_loop_var(znode *var) /* {{{ */
{
zend_op *opline = get_next_op(CG(active_op_array));
opline->opcode = ZEND_FREE;
opline->opcode = var->flag ? ZEND_FE_FREE : ZEND_FREE;
SET_NODE(opline->op1, var);
SET_UNUSED(opline->op2);
}
@ -931,10 +931,7 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */
(*op_array->refcount)++;
if (op_array->static_variables) {
HashTable *static_variables = op_array->static_variables;
ALLOC_HASHTABLE(op_array->static_variables);
zend_array_dup(op_array->static_variables, static_variables);
op_array->static_variables = zend_array_dup(op_array->static_variables);
}
op_array->run_time_cache = NULL;
} else if (function->type == ZEND_INTERNAL_FUNCTION) {
@ -1048,12 +1045,6 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array
return NULL;
}
if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val);
} else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val);
}
zend_do_inheritance(ce, parent_ce);
ce->refcount++;
@ -1235,13 +1226,14 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i
{
zend_constant *c;
if (!(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
/* Substitute case-sensitive (or lowercase) persistent constants */
c = zend_hash_find_ptr(EG(zend_constants), name);
if (c && (c->flags & CONST_PERSISTENT)) {
ZVAL_DUP(zv, &c->value);
return 1;
}
/* Substitute case-sensitive (or lowercase) constants */
c = zend_hash_find_ptr(EG(zend_constants), name);
if (c && (
((c->flags & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION))
|| (Z_TYPE(c->value) < IS_OBJECT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION))
)) {
ZVAL_DUP(zv, &c->value);
return 1;
}
{
@ -1264,6 +1256,38 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i
}
/* }}} */
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);
zval *c;
if (CG(active_class_entry) && (fetch_type == ZEND_FETCH_CLASS_SELF || (fetch_type == ZEND_FETCH_CLASS_DEFAULT && zend_string_equals_ci(class_name, CG(active_class_entry)->name)))) {
c = zend_hash_find(&CG(active_class_entry)->constants_table, name);
} else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), class_name->val, class_name->len);
if (ce) {
c = zend_hash_find(&ce->constants_table, name);
} else {
return 0;
}
} else {
return 0;
}
if (CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) {
return 0;
}
/* Substitute case-sensitive (or lowercase) persistent class constants */
if (c && Z_TYPE_P(c) < IS_OBJECT) {
ZVAL_DUP(zv, c);
return 1;
}
return 0;
}
/* }}} */
void zend_init_list(void *result, void *item) /* {{{ */
{
void** list = emalloc(sizeof(void*) * 2);
@ -1343,6 +1367,19 @@ void zend_do_extended_fcall_end(void) /* {{{ */
}
/* }}} */
zend_bool zend_is_auto_global_str(char *name, size_t len) /* {{{ */ {
zend_auto_global *auto_global;
if ((auto_global = zend_hash_str_find_ptr(CG(auto_globals), name, len)) != NULL) {
if (auto_global->armed) {
auto_global->armed = auto_global->auto_global_callback(auto_global->name);
}
return 1;
}
return 0;
}
/* }}} */
zend_bool zend_is_auto_global(zend_string *name) /* {{{ */
{
zend_auto_global *auto_global;
@ -1695,13 +1732,6 @@ ZEND_API size_t zend_dirname(char *path, size_t len)
}
/* }}} */
static inline zend_bool zend_string_equals_str_ci(zend_string *str1, zend_string *str2) /* {{{ */
{
return str1->len == str2->len
&& !zend_binary_strcasecmp(str1->val, str1->len, str2->val, str2->len);
}
/* }}} */
static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
{
switch (type & BP_VAR_MASK) {
@ -3494,32 +3524,19 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
}
opnum_reset = get_next_op_number(CG(active_op_array));
opline = zend_emit_op(&reset_node, ZEND_FE_RESET, &expr_node, NULL);
if (by_ref && is_variable) {
opline->extended_value = ZEND_FE_FETCH_BYREF;
}
opline = zend_emit_op(&reset_node, by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R, &expr_node, NULL);
reset_node.flag = 1; /* generate FE_FREE */
zend_stack_push(&CG(loop_var_stack), &reset_node);
opnum_fetch = get_next_op_number(CG(active_op_array));
opline = zend_emit_op(&value_node, ZEND_FE_FETCH, &reset_node, NULL);
if (by_ref) {
opline->extended_value |= ZEND_FE_FETCH_BYREF;
}
opline = zend_emit_op(&value_node, by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R, &reset_node, NULL);
if (key_ast) {
opline->extended_value |= ZEND_FE_FETCH_WITH_KEY;
opline->extended_value = 1;
}
opline = zend_emit_op(NULL, ZEND_OP_DATA, NULL, NULL);
/* Allocate enough space to keep HashPointer on VM stack */
opline->op1_type = IS_TMP_VAR;
opline->op1.var = get_temporary_variable(CG(active_op_array));
if (sizeof(HashPointer) > sizeof(zval)) {
/* Make sure 1 zval is enough for HashPointer (2 must be enough) */
get_temporary_variable(CG(active_op_array));
}
if (key_ast) {
zend_make_tmp_result(&key_node, opline);
}
@ -3610,6 +3627,7 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
zend_compile_expr(&expr_node, expr_ast);
expr_node.flag = 0;
zend_stack_push(&CG(loop_var_stack), &expr_node);
zend_begin_loop();
@ -4011,9 +4029,13 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_
"Variadic parameter cannot have a default value");
}
} else if (default_ast) {
/* we cannot substitute constants here or it will break ReflectionParameter::getDefaultValueConstantName() and ReflectionParameter::isDefaultValueConstant() */
uint32_t cops = CG(compiler_options);
CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
opcode = ZEND_RECV_INIT;
default_node.op_type = IS_CONST;
zend_const_expr_to_zval(&default_node.u.constant, default_ast);
CG(compiler_options) = cops;
} else {
opcode = ZEND_RECV;
default_node.op_type = IS_UNUSED;
@ -4128,7 +4150,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
{
zend_class_entry *ce = CG(active_class_entry);
zend_bool in_interface = (ce->ce_flags & ZEND_ACC_INTERFACE) != 0;
zend_bool in_trait = ZEND_CE_IS_TRAIT(ce);
zend_bool in_trait = (ce->ce_flags & ZEND_ACC_TRAIT) != 0;
zend_bool is_public = (op_array->fn_flags & ZEND_ACC_PUBLIC) != 0;
zend_bool is_static = (op_array->fn_flags & ZEND_ACC_STATIC) != 0;
@ -4221,7 +4243,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
}
}
} else {
if (!in_trait && zend_string_equals_str_ci(lcname, ce->name)) {
if (!in_trait && zend_string_equals_ci(lcname, ce->name)) {
if (!ce->constructor) {
ce->constructor = (zend_function *) op_array;
}
@ -4313,7 +4335,7 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
if (CG(current_import_function)) {
zend_string *import_name = zend_hash_find_ptr(CG(current_import_function), lcname);
if (import_name && !zend_string_equals_str_ci(lcname, import_name)) {
if (import_name && !zend_string_equals_ci(lcname, import_name)) {
zend_error(E_COMPILE_ERROR, "Cannot declare function %s "
"because the name is already in use", name->val);
}
@ -4490,7 +4512,7 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
zend_string *name = zend_ast_get_str(name_ast);
zval value_zv;
if (ZEND_CE_IS_TRAIT(ce)) {
if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
return;
}
@ -4709,7 +4731,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
zend_string_addref(name);
}
if (import_name && !zend_string_equals_str_ci(lcname, import_name)) {
if (import_name && !zend_string_equals_ci(lcname, import_name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
"because the name is already in use", name->val);
}
@ -4887,7 +4909,7 @@ static char *zend_get_use_type_str(uint32_t type) /* {{{ */
static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend_string *new_name, zend_string *check_name) /* {{{ */
{
if (zend_string_equals_str_ci(old_name, check_name)) {
if (zend_string_equals_ci(old_name, check_name)) {
return;
}
@ -5200,7 +5222,7 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
break;
case T_CLASS_C:
if (ce) {
if (ZEND_CE_IS_TRAIT(ce)) {
if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
return 0;
} else {
ZVAL_STR_COPY(zv, ce->name);
@ -5210,7 +5232,7 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
}
break;
case T_TRAIT_C:
if (ce && ZEND_CE_IS_TRAIT(ce)) {
if (ce && (ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
ZVAL_STR_COPY(zv, ce->name);
} else {
ZVAL_EMPTY_STRING(zv);
@ -5942,31 +5964,33 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
zend_ast *const_ast = ast->child[1];
znode class_node, const_node;
zend_op *opline, *class_op = NULL;
zend_op *opline;
zend_string *resolved_name;
if (zend_is_const_default_class_ref(class_ast)) {
class_node.op_type = IS_CONST;
ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast));
} else {
class_op = zend_compile_class_ref(&class_node, class_ast);
}
zend_compile_expr(&const_node, const_ast);
if (class_op && const_node.op_type == IS_CONST && class_op->extended_value == ZEND_FETCH_CLASS_SELF && Z_TYPE(const_node.u.constant) == IS_STRING && CG(active_class_entry)) {
zval *const_zv = zend_hash_find(&CG(active_class_entry)->constants_table, Z_STR(const_node.u.constant));
if (const_zv && Z_TYPE_P(const_zv) < IS_CONSTANT) {
CG(active_op_array)->last--;
CG(active_op_array)->T--;
zend_eval_const_expr(&class_ast);
zend_eval_const_expr(&const_ast);
if (class_ast->kind == ZEND_AST_ZVAL) {
resolved_name = zend_resolve_class_name_ast(class_ast);
if (const_ast->kind == ZEND_AST_ZVAL && zend_try_ct_eval_class_const(&result->u.constant, resolved_name, zend_ast_get_str(const_ast))) {
result->op_type = IS_CONST;
ZVAL_COPY(&result->u.constant, const_zv);
zend_string_release(Z_STR(const_node.u.constant));
zend_string_release(resolved_name);
return;
}
}
if (zend_is_const_default_class_ref(class_ast)) {
class_node.op_type = IS_CONST;
ZVAL_STR(&class_node.u.constant, resolved_name);
} else {
if (class_ast->kind == ZEND_AST_ZVAL) {
zend_string_release(resolved_name);
}
zend_compile_class_ref(&class_node, class_ast);
}
zend_compile_expr(&const_node, const_ast);
opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, &const_node);
zend_set_class_name_op1(opline, &class_node);
@ -6006,8 +6030,8 @@ void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
ZVAL_STR_COPY(&result->u.constant, CG(active_class_entry)->name);
}
break;
case ZEND_FETCH_CLASS_STATIC:
case ZEND_FETCH_CLASS_PARENT:
case ZEND_FETCH_CLASS_STATIC:
case ZEND_FETCH_CLASS_PARENT:
if (!CG(active_class_entry)) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot access %s::class when no class scope is active",
@ -6097,7 +6121,7 @@ void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
ZEND_ASSERT(ast->attr == T_CLASS_C &&
CG(active_class_entry) &&
ZEND_CE_IS_TRAIT(CG(active_class_entry)));
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
{
zend_ast *const_ast = zend_ast_create(ZEND_AST_CONST,
@ -6232,7 +6256,7 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
/* Other cases already resolved by constant folding */
ZEND_ASSERT(ast->attr == T_CLASS_C &&
CG(active_class_entry) &&
ZEND_CE_IS_TRAIT(CG(active_class_entry)));
(CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
{
zval const_zv;
@ -6684,6 +6708,30 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
zend_string_release(resolved_name);
break;
}
case ZEND_AST_CLASS_CONST:
{
zend_ast *class_ast = ast->child[0];
zend_ast *name_ast = ast->child[1];
zend_string *resolved_name;
zend_eval_const_expr(&class_ast);
zend_eval_const_expr(&name_ast);
if (class_ast->kind != ZEND_AST_ZVAL || name_ast->kind != ZEND_AST_ZVAL) {
return;
}
resolved_name = zend_resolve_class_name_ast(class_ast);
if (!zend_try_ct_eval_class_const(&result, resolved_name, zend_ast_get_str(name_ast))) {
zend_string_release(resolved_name);
return;
}
zend_string_release(resolved_name);
break;
}
default:
return;
}

View File

@ -95,7 +95,8 @@ typedef union _znode_op {
} znode_op;
typedef struct _znode { /* used only during compilation */
int op_type;
zend_uchar op_type;
zend_uchar flag;
union {
znode_op op;
zval constant; /* replaced by literal/zv */
@ -190,8 +191,8 @@ typedef struct _zend_try_catch_element {
/* ZEND_ACC_EXPLICIT_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */
#define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS 0x10
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS 0x20
#define ZEND_ACC_INTERFACE 0x80
#define ZEND_ACC_TRAIT 0x120
#define ZEND_ACC_INTERFACE 0x40
#define ZEND_ACC_TRAIT 0x80
/* method flags (visibility) */
/* The order of those must be kept - public < protected < private */
@ -257,8 +258,6 @@ typedef struct _zend_try_catch_element {
/* Function has a return type hint (or class has such non-private function) */
#define ZEND_ACC_HAS_RETURN_TYPE 0x40000000
#define ZEND_CE_IS_TRAIT(ce) (((ce)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)
char *zend_visibility_string(uint32_t fn_flags);
typedef struct _zend_property_info {
@ -732,6 +731,7 @@ typedef struct _zend_auto_global {
ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback);
ZEND_API void zend_activate_auto_globals(void);
ZEND_API zend_bool zend_is_auto_global(zend_string *name);
ZEND_API zend_bool zend_is_auto_global_str(char *name, size_t len);
ZEND_API size_t zend_dirname(char *path, size_t len);
int zendlex(zend_parser_stack_elem *elem);
@ -834,9 +834,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_FETCH_ARG_MASK 0x000fffff
#define ZEND_FE_FETCH_BYREF 1
#define ZEND_FE_FETCH_WITH_KEY 2
#define EXT_TYPE_FREE_ON_RETURN (1<<2)
#define ZEND_MEMBER_FUNC_CALL 1<<0
@ -930,6 +927,9 @@ END_EXTERN_C()
/* disable usage of builtin instruction for strlen() */
#define ZEND_COMPILE_NO_BUILTIN_STRLEN (1<<6)
/* disable substitution of persistent constants at compile-time */
#define ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION (1<<7)
/* The default value for CG(compiler_options) */
#define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY

View File

@ -1226,7 +1226,7 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
ht = &EG(symbol_table).ht;
ht = &EG(symbol_table);
} else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
ht = EX(func)->op_array.static_variables;
@ -1235,7 +1235,7 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
if (!EX(symbol_table)) {
zend_rebuild_symbol_table();
}
ht = &EX(symbol_table)->ht;
ht = EX(symbol_table);
}
return ht;
}
@ -1692,6 +1692,14 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
}
}
}
array_offset = jmp_to->parent;
@ -1743,12 +1751,12 @@ ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_val
ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */
{
if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
zend_array_destroy(&symbol_table->ht);
zend_array_destroy(symbol_table);
efree_size(symbol_table, sizeof(zend_array));
} else {
/* clean before putting into the cache, since clean
could call dtors, which could use cached hash */
zend_symtable_clean(&symbol_table->ht);
zend_symtable_clean(symbol_table);
*(++EG(symtable_cache_ptr)) = symbol_table;
}
}

View File

@ -152,9 +152,7 @@ void init_executor(void) /* {{{ */
zend_vm_stack_init();
zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0);
GC_REFCOUNT(&EG(symbol_table)) = 1;
GC_TYPE_INFO(&EG(symbol_table)) = IS_ARRAY;
zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
EG(valid_symbol_table) = 1;
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
@ -183,6 +181,11 @@ void init_executor(void) /* {{{ */
EG(scope) = NULL;
EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
EG(ht_iterators_used) = 0;
EG(ht_iterators) = EG(ht_iterators_slots);
memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));
EG(active) = 1;
}
/* }}} */
@ -213,14 +216,14 @@ static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
void shutdown_destructors(void) /* {{{ */
{
if (CG(unclean_shutdown)) {
EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
}
zend_try {
uint32_t symbols;
do {
symbols = zend_hash_num_elements(&EG(symbol_table).ht);
zend_hash_reverse_apply(&EG(symbol_table).ht, (apply_func_t) zval_call_destructor);
} while (symbols != zend_hash_num_elements(&EG(symbol_table).ht));
symbols = zend_hash_num_elements(&EG(symbol_table));
zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
} while (symbols != zend_hash_num_elements(&EG(symbol_table)));
zend_objects_store_call_destructors(&EG(objects_store));
} zend_catch {
/* if we couldn't destruct cleanly, mark all objects as destructed anyway */
@ -254,9 +257,9 @@ void shutdown_executor(void) /* {{{ */
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
if (CG(unclean_shutdown)) {
EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
}
zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht);
zend_hash_graceful_reverse_destroy(&EG(symbol_table));
} zend_end_try();
EG(valid_symbol_table) = 0;
@ -344,7 +347,7 @@ void shutdown_executor(void) /* {{{ */
}
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
zend_hash_destroy(&(*EG(symtable_cache_ptr))->ht);
zend_hash_destroy(*EG(symtable_cache_ptr));
FREE_HASHTABLE(*EG(symtable_cache_ptr));
EG(symtable_cache_ptr)--;
}
@ -373,6 +376,11 @@ void shutdown_executor(void) /* {{{ */
zend_shutdown_fpu();
EG(ht_iterators_used) = 0;
if (EG(ht_iterators) != EG(ht_iterators_slots)) {
efree(EG(ht_iterators));
}
EG(active) = 0;
}
/* }}} */
@ -1385,7 +1393,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
zend_function *func;
zend_abstract_info ai;
if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & (ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
memset(&ai, 0, sizeof(ai));
ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
@ -1407,7 +1415,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
ZEND_API int zend_delete_global_variable(zend_string *name) /* {{{ */
{
return zend_hash_del_ind(&EG(symbol_table).ht, name);
return zend_hash_del_ind(&EG(symbol_table), name);
}
/* }}} */
@ -1434,17 +1442,14 @@ ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
symbol_table = ex->symbol_table = *(EG(symtable_cache_ptr)--);
} else {
symbol_table = ex->symbol_table = emalloc(sizeof(zend_array));
GC_REFCOUNT(symbol_table) = 0;
GC_TYPE_INFO(symbol_table) = IS_ARRAY;
zend_hash_init(&symbol_table->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_init(symbol_table, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
/*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
}
for (i = 0; i < ex->func->op_array.last_var; i++) {
zval zv;
ZVAL_INDIRECT(&zv, ZEND_CALL_VAR_NUM(ex, i));
zend_hash_add_new(&symbol_table->ht,
ex->func->op_array.vars[i], &zv);
zend_hash_add_new(symbol_table, ex->func->op_array.vars[i], &zv);
}
return symbol_table;
}
@ -1454,7 +1459,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ *
{
int i;
zend_op_array *op_array = &execute_data->func->op_array;
HashTable *ht = &execute_data->symbol_table->ht;
HashTable *ht = execute_data->symbol_table;
/* copy real values from symbol table into CV slots and create
INDIRECT references to CV in symbol table */
@ -1482,7 +1487,7 @@ ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ *
{
int i;
zend_op_array *op_array = &execute_data->func->op_array;
HashTable *ht = &execute_data->symbol_table->ht;
HashTable *ht = execute_data->symbol_table;
/* copy real values from CV slots into symbol table */
for (i = 0; i < op_array->last_var; i++) {
@ -1521,11 +1526,11 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force) /* {{
if (force) {
zend_array *symbol_table = zend_rebuild_symbol_table();
if (symbol_table) {
return zend_hash_update(&symbol_table->ht, name, value) ? SUCCESS : FAILURE;;
return zend_hash_update(symbol_table, name, value) ? SUCCESS : FAILURE;;
}
}
} else {
return (zend_hash_update_ind(&execute_data->symbol_table->ht, name, value) != NULL) ? SUCCESS : FAILURE;
return (zend_hash_update_ind(execute_data->symbol_table, name, value) != NULL) ? SUCCESS : FAILURE;
}
}
return FAILURE;
@ -1559,11 +1564,11 @@ ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, i
if (force) {
zend_array *symbol_table = zend_rebuild_symbol_table();
if (symbol_table) {
return zend_hash_str_update(&symbol_table->ht, name, len, value) ? SUCCESS : FAILURE;;
return zend_hash_str_update(symbol_table, name, len, value) ? SUCCESS : FAILURE;;
}
}
} else {
return (zend_hash_str_update_ind(&execute_data->symbol_table->ht, name, len, value) != NULL) ? SUCCESS : FAILURE;
return (zend_hash_str_update_ind(execute_data->symbol_table, name, len, value) != NULL) ? SUCCESS : FAILURE;
}
}
return FAILURE;

View File

@ -231,9 +231,7 @@ tail_call:
for (i = 0; i < n; i++) {
if (Z_REFCOUNTED(table[i])) {
ref = Z_COUNTED(table[i]);
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
GC_REFCOUNT(ref)++;
}
GC_REFCOUNT(ref)++;
if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
if (!props && i == n - 1) {
goto tail_call;
@ -250,14 +248,12 @@ tail_call:
}
} else if (GC_TYPE(ref) == IS_ARRAY) {
if ((zend_array*)ref != &EG(symbol_table)) {
ht = &((zend_array*)ref)->ht;
ht = (zend_array*)ref;
}
} else if (GC_TYPE(ref) == IS_REFERENCE) {
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
ref = Z_COUNTED(((zend_reference*)ref)->val);
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
GC_REFCOUNT(ref)++;
}
GC_REFCOUNT(ref)++;
if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
goto tail_call;
}
@ -269,9 +265,7 @@ tail_call:
p = ht->arData + idx;
if (!Z_REFCOUNTED(p->val)) continue;
ref = Z_COUNTED(p->val);
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
GC_REFCOUNT(ref)++;
}
GC_REFCOUNT(ref)++;
if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
if (idx == ht->nNumUsed-1) {
goto tail_call;
@ -312,9 +306,7 @@ tail_call:
for (i = 0; i < n; i++) {
if (Z_REFCOUNTED(table[i])) {
ref = Z_COUNTED(table[i]);
if (GC_TYPE(ref) != IS_ARRAY || ((zend_array*)ref) != &EG(symbol_table)) {
GC_REFCOUNT(ref)--;
}
GC_REFCOUNT(ref)--;
if (!props && i == n - 1) {
goto tail_call;
} else {
@ -331,7 +323,7 @@ tail_call:
if (((zend_array*)ref) == &EG(symbol_table)) {
GC_SET_BLACK(GC_INFO(ref));
} else {
ht = &((zend_array*)ref)->ht;
ht = (zend_array*)ref;
}
} else if (GC_TYPE(ref) == IS_REFERENCE) {
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
@ -341,9 +333,7 @@ tail_call:
return;
}
ref = Z_COUNTED(((zend_reference*)ref)->val);
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
GC_REFCOUNT(ref)--;
}
GC_REFCOUNT(ref)--;
goto tail_call;
}
return;
@ -358,9 +348,7 @@ tail_call:
continue;
}
ref = Z_COUNTED(p->val);
if (GC_TYPE(ref) != IS_ARRAY || ((zend_array*)ref) != &EG(symbol_table)) {
GC_REFCOUNT(ref)--;
}
GC_REFCOUNT(ref)--;
if (idx == ht->nNumUsed-1) {
goto tail_call;
} else {
@ -428,7 +416,7 @@ tail_call:
if ((zend_array*)ref == &EG(symbol_table)) {
GC_SET_BLACK(GC_INFO(ref));
} else {
ht = &((zend_array*)ref)->ht;
ht = (zend_array*)ref;
}
} else if (GC_TYPE(ref) == IS_REFERENCE) {
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
@ -529,9 +517,7 @@ tail_call:
for (i = 0; i < n; i++) {
if (Z_REFCOUNTED(table[i])) {
ref = Z_COUNTED(table[i]);
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
GC_REFCOUNT(ref)++;
}
GC_REFCOUNT(ref)++;
if (!props && i == n - 1) {
goto tail_call;
} else {
@ -548,13 +534,11 @@ tail_call:
ht = props;
}
} else if (GC_TYPE(ref) == IS_ARRAY) {
ht = &((zend_array*)ref)->ht;
ht = (zend_array*)ref;
} else if (GC_TYPE(ref) == IS_REFERENCE) {
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
ref = Z_COUNTED(((zend_reference*)ref)->val);
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
GC_REFCOUNT(ref)++;
}
GC_REFCOUNT(ref)++;
goto tail_call;
}
return count;
@ -571,9 +555,7 @@ tail_call:
continue;
}
ref = Z_COUNTED(p->val);
if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
GC_REFCOUNT(ref)++;
}
GC_REFCOUNT(ref)++;
if (idx == ht->nNumUsed-1) {
goto tail_call;
} else {
@ -681,7 +663,7 @@ tail_call:
ht = props;
}
} else if (GC_TYPE(ref) == IS_ARRAY) {
ht = &((zend_array*)ref)->ht;
ht = (zend_array*)ref;
} else if (GC_TYPE(ref) == IS_REFERENCE) {
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
ref = Z_COUNTED(((zend_reference*)ref)->val);
@ -802,8 +784,9 @@ ZEND_API int zend_gc_collect_cycles(void)
} else if (GC_TYPE(p) == IS_ARRAY) {
zend_array *arr = (zend_array*)p;
GC_REFCOUNT(arr) = 0;
GC_TYPE(arr) = IS_NULL;
zend_hash_destroy(&arr->ht);
zend_hash_destroy(arr);
}
current = GC_G(next_to_free);
}

View File

@ -60,6 +60,12 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
if (brk_opline->opcode == ZEND_FREE) {
zval *var = EX_VAR(brk_opline->op1.var);
zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_FE_FREE) {
zval *var = EX_VAR(brk_opline->op1.var);
if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
}
}
}

View File

@ -226,6 +226,11 @@ struct _zend_executor_globals {
zend_bool active;
zend_bool valid_symbol_table;
uint32_t ht_iterators_count; /* number of allocatd slots */
uint32_t ht_iterators_used; /* number of used slots */
HashTableIterator *ht_iterators;
HashTableIterator ht_iterators_slots[16];
void *saved_fpu_cw_ptr;
#if XPFPA_HAVE_CW
XPFPA_CW_DATATYPE saved_fpu_cw;

View File

@ -23,6 +23,13 @@
#include "zend_globals.h"
#include "zend_variables.h"
#define HT_DEBUG 0
#if HT_DEBUG
# define HT_ASSERT(c) ZEND_ASSERT(c)
#else
# define HT_ASSERT(c)
#endif
#if ZEND_DEBUG
/*
#define HASH_MASK_CONSISTENCY 0x60
@ -82,42 +89,26 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin
static void zend_hash_do_resize(HashTable *ht);
#define CHECK_INIT(ht, packed) do { \
if (UNEXPECTED(!((ht)->u.flags & HASH_FLAG_INITIALIZED))) { \
if (packed) { \
(ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED; \
(ht)->arData = (Bucket *) safe_pemalloc((ht)->nTableSize, sizeof(Bucket), 0, (ht)->u.flags & HASH_FLAG_PERSISTENT); \
} else { \
(ht)->u.flags |= HASH_FLAG_INITIALIZED; \
(ht)->nTableMask = (ht)->nTableSize - 1; \
(ht)->arData = (Bucket *) safe_pemalloc((ht)->nTableSize, sizeof(Bucket) + sizeof(uint32_t), 0, (ht)->u.flags & HASH_FLAG_PERSISTENT); \
(ht)->arHash = (uint32_t*)((ht)->arData + (ht)->nTableSize); \
memset((ht)->arHash, INVALID_IDX, (ht)->nTableSize * sizeof(uint32_t)); \
} \
} \
} while (0)
static const uint32_t uninitialized_bucket = {INVALID_IDX};
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
static uint32_t zend_always_inline zend_hash_check_size(uint32_t nSize)
{
#if defined(ZEND_WIN32)
unsigned long index;
#endif
/* Use big enough power of 2 */
/* size should be between 8 and 0x80000000 */
nSize = (nSize <= 8 ? 8 : (nSize >= 0x80000000 ? 0x80000000 : nSize));
/* size should be between HT_MIN_SIZE and HT_MAX_SIZE */
nSize = (nSize <= HT_MIN_SIZE ? HT_MIN_SIZE : (nSize >= HT_MAX_SIZE ? HT_MAX_SIZE : nSize));
#if defined(ZEND_WIN32)
if (BitScanReverse(&index, nSize - 1)) {
ht->nTableSize = 0x2 << ((31 - index) ^ 0x1f);
return 0x2 << ((31 - index) ^ 0x1f);
} else {
/* nSize is ensured to be in the valid range, fall back to it
rather than using an undefined bis scan result. */
ht->nTableSize = nSize;
return nSize;
}
#elif defined(__GNUC__)
ht->nTableSize = 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f);
return 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f);
#else
nSize -= 1;
nSize |= (nSize >> 1);
@ -125,9 +116,37 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
nSize |= (nSize >> 4);
nSize |= (nSize >> 8);
nSize |= (nSize >> 16);
ht->nTableSize = nSize + 1;
return nSize + 1;
#endif
}
static void zend_always_inline zend_hash_check_init(HashTable *ht, int packed)
{
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (UNEXPECTED(!((ht)->u.flags & HASH_FLAG_INITIALIZED))) {
if (packed) {
(ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED;
(ht)->arData = (Bucket *) pemalloc((ht)->nTableSize * sizeof(Bucket), (ht)->u.flags & HASH_FLAG_PERSISTENT);
} else {
(ht)->u.flags |= HASH_FLAG_INITIALIZED;
(ht)->nTableMask = (ht)->nTableSize - 1;
(ht)->arData = (Bucket *) pemalloc((ht)->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), (ht)->u.flags & HASH_FLAG_PERSISTENT);
(ht)->arHash = (uint32_t*)((ht)->arData + (ht)->nTableSize);
memset((ht)->arHash, INVALID_IDX, (ht)->nTableSize * sizeof(uint32_t));
}
}
}
#define CHECK_INIT(ht, packed) \
zend_hash_check_init(ht, packed)
static const uint32_t uninitialized_bucket = {INVALID_IDX};
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
{
GC_REFCOUNT(ht) = 1;
GC_TYPE_INFO(ht) = IS_ARRAY;
ht->nTableSize = zend_hash_check_size(nSize);
ht->nTableMask = 0;
ht->nNumUsed = 0;
ht->nNumOfElements = 0;
@ -141,9 +160,13 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
static void zend_hash_packed_grow(HashTable *ht)
{
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->nTableSize >= HT_MAX_SIZE) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
}
HANDLE_BLOCK_INTERRUPTIONS();
ht->arData = (Bucket *) safe_perealloc(ht->arData, (ht->nTableSize << 1), sizeof(Bucket), 0, ht->u.flags & HASH_FLAG_PERSISTENT);
ht->nTableSize = (ht->nTableSize << 1);
ht->nTableSize += ht->nTableSize;
ht->arData = (Bucket *) perealloc(ht->arData, ht->nTableSize * sizeof(Bucket), ht->u.flags & HASH_FLAG_PERSISTENT);
HANDLE_UNBLOCK_INTERRUPTIONS();
}
@ -151,15 +174,17 @@ ZEND_API void zend_hash_real_init(HashTable *ht, zend_bool packed)
{
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
CHECK_INIT(ht, packed);
}
ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
{
HT_ASSERT(GC_REFCOUNT(ht) == 1);
HANDLE_BLOCK_INTERRUPTIONS();
ht->u.flags &= ~HASH_FLAG_PACKED;
ht->nTableMask = ht->nTableSize - 1;
ht->arData = (Bucket *) safe_perealloc(ht->arData, ht->nTableSize, sizeof(Bucket) + sizeof(uint32_t), 0, ht->u.flags & HASH_FLAG_PERSISTENT);
ht->arData = (Bucket *) perealloc(ht->arData, ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), ht->u.flags & HASH_FLAG_PERSISTENT);
ht->arHash = (uint32_t*)(ht->arData + ht->nTableSize);
zend_hash_rehash(ht);
HANDLE_UNBLOCK_INTERRUPTIONS();
@ -167,6 +192,7 @@ ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
ZEND_API void zend_hash_to_packed(HashTable *ht)
{
HT_ASSERT(GC_REFCOUNT(ht) == 1);
HANDLE_BLOCK_INTERRUPTIONS();
ht->u.flags |= HASH_FLAG_PACKED;
ht->nTableMask = 0;
@ -193,6 +219,139 @@ ZEND_API void zend_hash_set_apply_protection(HashTable *ht, zend_bool bApplyProt
}
}
ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht, HashPosition pos)
{
HashTableIterator *iter = EG(ht_iterators);
HashTableIterator *end = iter + EG(ht_iterators_count);
uint32_t idx;
if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
ht->u.v.nIteratorsCount++;
}
while (iter != end) {
if (iter->ht == NULL) {
iter->ht = ht;
iter->pos = pos;
idx = iter - EG(ht_iterators);
if (idx + 1 > EG(ht_iterators_used)) {
EG(ht_iterators_used) = idx + 1;
}
return idx;
}
iter++;
}
if (EG(ht_iterators) == EG(ht_iterators_slots)) {
EG(ht_iterators) = emalloc(sizeof(HashTableIterator) * (EG(ht_iterators_count) + 8));
memcpy(EG(ht_iterators), EG(ht_iterators_slots), sizeof(HashTableIterator) * EG(ht_iterators_count));
} else {
EG(ht_iterators) = erealloc(EG(ht_iterators), sizeof(HashTableIterator) * (EG(ht_iterators_count) + 8));
}
iter = EG(ht_iterators) + EG(ht_iterators_count);
EG(ht_iterators_count) += 8;
iter->ht = ht;
iter->pos = pos;
memset(iter + 1, 0, sizeof(HashTableIterator) * 7);
idx = iter - EG(ht_iterators);
EG(ht_iterators_used) = idx + 1;
return idx;
}
ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht)
{
HashTableIterator *iter = EG(ht_iterators) + idx;
ZEND_ASSERT(idx != (uint32_t)-1);
if (iter->pos == INVALID_IDX) {
return INVALID_IDX;
} else if (UNEXPECTED(iter->ht != ht)) {
if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
iter->ht->u.v.nIteratorsCount--;
}
if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
ht->u.v.nIteratorsCount++;
}
iter->ht = ht;
iter->pos = ht->nInternalPointer;
}
return iter->pos;
}
ZEND_API void zend_hash_iterator_del(uint32_t idx)
{
HashTableIterator *iter = EG(ht_iterators) + idx;
ZEND_ASSERT(idx != (uint32_t)-1);
if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
iter->ht->u.v.nIteratorsCount--;
}
iter->ht = NULL;
if (idx == EG(ht_iterators_used) - 1) {
while (idx > 0 && EG(ht_iterators)[idx - 1].ht == NULL) {
idx--;
}
EG(ht_iterators_used) = idx;
}
}
static zend_never_inline void _zend_hash_iterators_remove(HashTable *ht)
{
HashTableIterator *iter = EG(ht_iterators);
HashTableIterator *end = iter + EG(ht_iterators_used);
uint32_t idx;
while (iter != end) {
if (iter->ht == ht) {
iter->ht = NULL;
}
iter++;
}
idx = EG(ht_iterators_used);
while (idx > 0 && EG(ht_iterators)[idx - 1].ht == NULL) {
idx--;
}
EG(ht_iterators_used) = idx;
}
static zend_always_inline void zend_hash_iterators_remove(HashTable *ht)
{
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
_zend_hash_iterators_remove(ht);
}
}
ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start)
{
HashTableIterator *iter = EG(ht_iterators);
HashTableIterator *end = iter + EG(ht_iterators_used);
HashPosition res = INVALID_IDX;
while (iter != end) {
if (iter->ht == ht) {
if (iter->pos >= start && iter->pos < res) {
res = iter->pos;
}
}
iter++;
}
return res;
}
ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
{
HashTableIterator *iter = EG(ht_iterators);
HashTableIterator *end = iter + EG(ht_iterators_used);
while (iter != end) {
if (iter->ht == ht && iter->pos == from) {
iter->pos = to;
}
iter++;
}
}
static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zend_string *key)
{
zend_ulong h;
@ -266,6 +425,7 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
Bucket *p;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
CHECK_INIT(ht, 0);
@ -305,6 +465,7 @@ add_to_hash:
if (ht->nInternalPointer == INVALID_IDX) {
ht->nInternalPointer = idx;
}
zend_hash_iterators_update(ht, INVALID_IDX, idx);
p = ht->arData + idx;
p->h = h = zend_string_hash_val(key);
p->key = key;
@ -417,6 +578,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
Bucket *p;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
CHECK_INIT(ht, h < ht->nTableSize);
@ -472,6 +634,7 @@ add_to_packed:
if (ht->nInternalPointer == INVALID_IDX) {
ht->nInternalPointer = h;
}
zend_hash_iterators_update(ht, INVALID_IDX, h);
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
}
@ -514,6 +677,7 @@ add_to_hash:
if (ht->nInternalPointer == INVALID_IDX) {
ht->nInternalPointer = idx;
}
zend_hash_iterators_update(ht, INVALID_IDX, idx);
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
}
@ -563,19 +727,22 @@ static void zend_hash_do_resize(HashTable *ht)
{
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->nNumUsed > ht->nNumOfElements) {
HANDLE_BLOCK_INTERRUPTIONS();
zend_hash_rehash(ht);
HANDLE_UNBLOCK_INTERRUPTIONS();
} else if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
} else if (ht->nTableSize < HT_MAX_SIZE) { /* Let's double the table size */
HANDLE_BLOCK_INTERRUPTIONS();
ht->arData = (Bucket *) safe_perealloc(ht->arData, (ht->nTableSize << 1), sizeof(Bucket) + sizeof(uint32_t), 0, ht->u.flags & HASH_FLAG_PERSISTENT);
ht->arHash = (uint32_t*)(ht->arData + (ht->nTableSize << 1));
ht->nTableSize = (ht->nTableSize << 1);
ht->nTableSize += ht->nTableSize;
ht->arData = (Bucket *) perealloc(ht->arData, ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), ht->u.flags & HASH_FLAG_PERSISTENT);
ht->arHash = (uint32_t*)(ht->arData + ht->nTableSize);
ht->nTableMask = ht->nTableSize - 1;
zend_hash_rehash(ht);
HANDLE_UNBLOCK_INTERRUPTIONS();
} else {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
}
}
@ -594,19 +761,42 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
}
memset(ht->arHash, INVALID_IDX, ht->nTableSize * sizeof(uint32_t));
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
p = ht->arData + i;
if (Z_TYPE(p->val) == IS_UNDEF) continue;
if (i != j) {
ht->arData[j] = ht->arData[i];
if (ht->nInternalPointer == i) {
ht->nInternalPointer = j;
if (EXPECTED(ht->u.v.nIteratorsCount == 0)) {
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
p = ht->arData + i;
if (Z_TYPE(p->val) == IS_UNDEF) continue;
if (i != j) {
ht->arData[j] = ht->arData[i];
if (ht->nInternalPointer == i) {
ht->nInternalPointer = j;
}
}
nIndex = ht->arData[j].h & ht->nTableMask;
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
ht->arHash[nIndex] = j;
j++;
}
} else {
uint32_t iter_pos = zend_hash_iterators_lower_pos(ht, 0);
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
p = ht->arData + i;
if (Z_TYPE(p->val) == IS_UNDEF) continue;
if (i != j) {
ht->arData[j] = ht->arData[i];
if (ht->nInternalPointer == i) {
ht->nInternalPointer = j;
}
if (i == iter_pos) {
zend_hash_iterators_update(ht, i, j);
iter_pos = zend_hash_iterators_lower_pos(ht, iter_pos + 1);
}
}
nIndex = ht->arData[j].h & ht->nTableMask;
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
ht->arHash[nIndex] = j;
j++;
}
nIndex = ht->arData[j].h & ht->nTableMask;
Z_NEXT(ht->arData[j].val) = ht->arHash[nIndex];
ht->arHash[nIndex] = j;
j++;
}
ht->nNumUsed = j;
return SUCCESS;
@ -628,17 +818,22 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx,
} while (ht->nNumUsed > 0 && (Z_TYPE(ht->arData[ht->nNumUsed-1].val) == IS_UNDEF));
}
ht->nNumOfElements--;
if (ht->nInternalPointer == idx) {
if (ht->nInternalPointer == idx || UNEXPECTED(ht->u.v.nIteratorsCount)) {
uint32_t new_idx = idx;
while (1) {
idx++;
if (idx >= ht->nNumUsed) {
ht->nInternalPointer = INVALID_IDX;
new_idx++;
if (new_idx >= ht->nNumUsed) {
new_idx = INVALID_IDX;
break;
} else if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
ht->nInternalPointer = idx;
} else if (Z_TYPE(ht->arData[new_idx].val) != IS_UNDEF) {
break;
}
}
if (ht->nInternalPointer == idx) {
ht->nInternalPointer = new_idx;
}
zend_hash_iterators_update(ht, idx, new_idx);
}
if (p->key) {
zend_string_release(p->key);
@ -683,6 +878,7 @@ ZEND_API int zend_hash_del(HashTable *ht, zend_string *key)
Bucket *prev = NULL;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_string_hash_val(key);
nIndex = h & ht->nTableMask;
@ -713,6 +909,7 @@ ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key)
Bucket *prev = NULL;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_string_hash_val(key);
nIndex = h & ht->nTableMask;
@ -756,6 +953,7 @@ ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, size_t len)
Bucket *prev = NULL;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_inline_hash_func(str, len);
nIndex = h & ht->nTableMask;
@ -798,6 +996,7 @@ ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, size_t len)
Bucket *prev = NULL;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_inline_hash_func(str, len);
nIndex = h & ht->nTableMask;
@ -826,6 +1025,7 @@ ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h)
Bucket *prev = NULL;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->u.flags & HASH_FLAG_PACKED) {
if (h < ht->nNumUsed) {
@ -857,6 +1057,7 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
Bucket *p, *end;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) <= 1);
if (ht->nNumUsed) {
p = ht->arData;
@ -893,6 +1094,7 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
} while (++p != end);
}
}
zend_hash_iterators_remove(ht);
} else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
return;
}
@ -904,6 +1106,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
Bucket *p, *end;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) <= 1);
if (ht->nNumUsed) {
@ -933,7 +1136,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
}
} while (++p != end);
}
zend_hash_iterators_remove(ht);
SET_INCONSISTENT(HT_DESTROYED);
} else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
return;
@ -946,6 +1149,7 @@ ZEND_API void zend_hash_clean(HashTable *ht)
Bucket *p, *end;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->nNumUsed) {
p = ht->arData;
@ -993,6 +1197,7 @@ ZEND_API void zend_symtable_clean(HashTable *ht)
Bucket *p, *end;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->nNumUsed) {
p = ht->arData;
@ -1021,6 +1226,7 @@ ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
Bucket *p;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
@ -1040,6 +1246,7 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
Bucket *p;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
idx = ht->nNumUsed;
while (idx > 0) {
@ -1072,6 +1279,7 @@ ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func)
int result;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
for (idx = 0; idx < ht->nNumUsed; idx++) {
@ -1098,6 +1306,7 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t appl
int result;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
for (idx = 0; idx < ht->nNumUsed; idx++) {
@ -1126,6 +1335,7 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t ap
int result;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
@ -1159,6 +1369,7 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func)
int result;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
idx = ht->nNumUsed;
@ -1189,6 +1400,7 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
IS_CONSISTENT(source);
IS_CONSISTENT(target);
HT_ASSERT(GC_REFCOUNT(target) == 1);
setTargetPointer = (target->nInternalPointer == INVALID_IDX);
for (idx = 0; idx < source->nNumUsed; idx++) {
@ -1225,15 +1437,20 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
}
ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
ZEND_API HashTable *zend_array_dup(HashTable *source)
{
uint32_t idx, target_idx;
uint32_t nIndex;
Bucket *p, *q;
zval *data;
HashTable *target;
IS_CONSISTENT(source);
ALLOC_HASHTABLE(target);
GC_REFCOUNT(target) = 1;
GC_TYPE_INFO(target) = IS_ARRAY;
target->nTableMask = source->nTableMask;
target->nTableSize = source->nTableSize;
target->pDestructor = source->pDestructor;
@ -1246,7 +1463,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
target->nNumUsed = source->nNumUsed;
target->nNumOfElements = source->nNumOfElements;
target->nNextFreeElement = source->nNextFreeElement;
target->arData = (Bucket *) safe_pemalloc(target->nTableSize, sizeof(Bucket), 0, 0);
target->arData = (Bucket *) pemalloc(target->nTableSize * sizeof(Bucket), 0);
target->arHash = (uint32_t*)&uninitialized_bucket;
target->nInternalPointer = source->nInternalPointer;
@ -1289,7 +1506,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
}
} else {
target->nNextFreeElement = source->nNextFreeElement;
target->arData = (Bucket *) safe_pemalloc(target->nTableSize, sizeof(Bucket) + sizeof(uint32_t), 0, 0);
target->arData = (Bucket *) pemalloc(target->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)), 0);
target->arHash = (uint32_t*)(target->arData + target->nTableSize);
memset(target->arHash, INVALID_IDX, target->nTableSize * sizeof(uint32_t));
@ -1343,6 +1560,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
target->arData = NULL;
target->arHash = (uint32_t*)&uninitialized_bucket;
}
return target;
}
@ -1355,6 +1573,7 @@ ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_f
IS_CONSISTENT(source);
IS_CONSISTENT(target);
HT_ASSERT(GC_REFCOUNT(target) == 1);
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
@ -1401,6 +1620,7 @@ ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor
IS_CONSISTENT(source);
IS_CONSISTENT(target);
HT_ASSERT(GC_REFCOUNT(target) == 1);
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
@ -1516,6 +1736,8 @@ ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *p
uint32_t idx;
IS_CONSISTENT(ht);
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
for (idx = 0; idx < ht->nNumUsed; idx++) {
if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
*pos = idx;
@ -1534,6 +1756,7 @@ ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos
uint32_t idx;
IS_CONSISTENT(ht);
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
idx = ht->nNumUsed;
while (idx > 0) {
@ -1552,6 +1775,7 @@ ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
uint32_t idx = *pos;
IS_CONSISTENT(ht);
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
if (idx != INVALID_IDX) {
while (1) {
@ -1575,6 +1799,7 @@ ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
uint32_t idx = *pos;
IS_CONSISTENT(ht);
HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
if (idx != INVALID_IDX) {
while (idx > 0) {
@ -1708,6 +1933,7 @@ ZEND_API int zend_hash_sort_ex(HashTable *ht, sort_func_t sort, compare_func_t c
uint32_t i, j;
IS_CONSISTENT(ht);
HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (!(ht->nNumOfElements>1) && !(renumber && ht->nNumOfElements>0)) { /* Doesn't require sorting */
return SUCCESS;

View File

@ -50,8 +50,6 @@ typedef struct _zend_hash_key {
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam);
typedef uint32_t HashPosition;
BEGIN_EXTERN_C()
/* startup/shutdown */
@ -171,13 +169,6 @@ ZEND_API zval *zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
typedef struct _HashPointer {
HashPosition pos;
HashTable *ht;
zend_ulong h;
zend_string *key;
} HashPointer;
#define zend_hash_has_more_elements(ht) \
zend_hash_has_more_elements_ex(ht, &(ht)->nInternalPointer)
#define zend_hash_move_forward(ht) \
@ -222,7 +213,7 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint
ZEND_API int zend_hash_rehash(HashTable *ht);
ZEND_API void zend_array_dup(HashTable *target, HashTable *source);
ZEND_API HashTable *zend_array_dup(HashTable *source);
ZEND_API void zend_array_destroy(HashTable *ht);
ZEND_API void zend_symtable_clean(HashTable *ht);
@ -234,6 +225,21 @@ void zend_hash_display(const HashTable *ht);
ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx);
ZEND_API uint32_t zend_hash_iterator_add(HashTable *ht, HashPosition pos);
ZEND_API HashPosition zend_hash_iterator_pos(uint32_t idx, HashTable *ht);
ZEND_API void zend_hash_iterator_del(uint32_t idx);
ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start);
ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to);
static zend_always_inline void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
{
if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
_zend_hash_iterators_update(ht, from, to);
}
}
END_EXTERN_C()
#define ZEND_INIT_SYMTABLE(ht) \

View File

@ -767,15 +767,27 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
zend_string *key;
zval *zv;
if ((ce->ce_flags & ZEND_ACC_INTERFACE)
&& !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name->val, parent_ce->name->val);
}
if (parent_ce->ce_flags & ZEND_ACC_FINAL) {
zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name->val, parent_ce->name->val);
if (ce->ce_flags & ZEND_ACC_INTERFACE) {
/* Interface can only inherit other interfaces */
if (!(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name->val, parent_ce->name->val);
}
} else {
/* Class declaration must not extend traits or interfaces */
if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val);
} else if (parent_ce->ce_flags & ZEND_ACC_TRAIT) {
zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val);
}
/* Class must not extend a final class */
if (parent_ce->ce_flags & ZEND_ACC_FINAL) {
zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name->val, parent_ce->name->val);
}
}
ce->parent = parent_ce;
/* Copy serialize/unserialize callbacks */
if (!ce->serialize) {
ce->serialize = parent_ce->serialize;
@ -1126,7 +1138,7 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
zend_get_function_declaration(existing_fn)->val);
}
return;
} else if ((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
} else if (existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) {
/* two traits can't define the same non-abstract method */
#if 1
zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s",

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -150,9 +150,7 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp) /* {{{ *
if (Z_TYPE(retval) == IS_ARRAY) {
if (Z_IMMUTABLE(retval)) {
*is_temp = 1;
ALLOC_HASHTABLE(ht);
zend_array_dup(ht, Z_ARRVAL(retval));
return ht;
return zend_array_dup(Z_ARRVAL(retval));
} else if (Z_REFCOUNT(retval) <= 1) {
*is_temp = 1;
ALLOC_HASHTABLE(ht);
@ -936,6 +934,7 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
/* destruct the function also, then - we have allocated it in get_method */
efree_size(func, sizeof(zend_internal_function));
execute_data->func = NULL;
}
/* }}} */
@ -1156,6 +1155,7 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{
/* destruct the function also, then - we have allocated it in get_method */
efree_size(func, sizeof(zend_internal_function));
execute_data->func = NULL;
}
/* }}} */

View File

@ -766,8 +766,10 @@ ZEND_API int pass_two(zend_op_array *op_array)
case ZEND_JMP_SET:
case ZEND_COALESCE:
case ZEND_NEW:
case ZEND_FE_RESET:
case ZEND_FE_FETCH:
case ZEND_FE_RESET_R:
case ZEND_FE_RESET_RW:
case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW:
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
break;
case ZEND_VERIFY_RETURN_TYPE:
@ -861,6 +863,8 @@ ZEND_API binary_op_type get_binary_op(int opcode)
return (binary_op_type) is_smaller_function;
case ZEND_IS_SMALLER_OR_EQUAL:
return (binary_op_type) is_smaller_or_equal_function;
case ZEND_SPACESHIP:
return (binary_op_type) compare_function;
case ZEND_BW_OR:
case ZEND_ASSIGN_BW_OR:
return (binary_op_type) bitwise_or_function;

View File

@ -566,8 +566,7 @@ ZEND_API void convert_to_array(zval *op) /* {{{ */
HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op);
if (obj_ht) {
zval arr;
ZVAL_NEW_ARR(&arr);
zend_array_dup(Z_ARRVAL(arr), obj_ht);
ZVAL_ARR(&arr, zend_array_dup(obj_ht));
zval_dtor(op);
ZVAL_COPY_VALUE(op, &arr);
return;

View File

@ -106,7 +106,7 @@ static zend_string *zend_new_interned_string_int(zend_string *str)
GC_FLAGS(str) |= IS_STR_INTERNED;
if (CG(interned_strings).nNumUsed >= CG(interned_strings).nTableSize) {
if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */
if (CG(interned_strings).nTableSize < HT_MAX_SIZE) { /* Let's double the table size */
Bucket *d = (Bucket *) perealloc_recoverable(CG(interned_strings).arData, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket), 1);
uint32_t *h = (uint32_t *) perealloc_recoverable(CG(interned_strings).arHash, (CG(interned_strings).nTableSize << 1) * sizeof(uint32_t), 1);

View File

@ -209,11 +209,15 @@ static zend_always_inline void zend_string_release(zend_string *s)
}
}
static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_string *s2)
{
return s1 == s2 || (s1->len == s2->len && !memcmp(s1->val, s2->val, s1->len));
}
#define zend_string_equals_ci(s1, s2) \
((s1)->len == (s2)->len && !zend_binary_strcasecmp((s1)->val, (s1)->len, (s2)->val, (s2)->len))
#define zend_string_equals_literal_ci(str, c) \
((str)->len == sizeof(c) - 1 && !zend_binary_strcasecmp((str)->val, (str)->len, (c), sizeof(c) - 1))

View File

@ -128,6 +128,8 @@ struct _zval_struct {
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
} u2;
};
@ -157,13 +159,17 @@ typedef struct _Bucket {
zend_string *key; /* string key or NULL for numerics */
} Bucket;
typedef struct _HashTable {
typedef struct _zend_array HashTable;
struct _zend_array {
zend_refcounted gc;
union {
struct {
ZEND_ENDIAN_LOHI_3(
ZEND_ENDIAN_LOHI_4(
zend_uchar flags,
zend_uchar nApplyCount,
uint16_t reserve)
zend_uchar nIteratorsCount,
zend_uchar reserve)
} v;
uint32_t flags;
} u;
@ -176,13 +182,25 @@ typedef struct _HashTable {
Bucket *arData;
uint32_t *arHash;
dtor_func_t pDestructor;
} HashTable;
struct _zend_array {
zend_refcounted gc;
HashTable ht;
};
#define HT_MIN_SIZE 8
#if SIZEOF_SIZE_T == 4
# define HT_MAX_SIZE 0x04000000 /* small enough to avoid overflow checks */
#elif SIZEOF_SIZE_T == 8
# define HT_MAX_SIZE 0x80000000
#else
# error "Unknown SIZEOF_SIZE_T"
#endif
typedef uint32_t HashPosition;
typedef struct _HashTableIterator {
HashTable *ht;
HashPosition pos;
} HashTableIterator;
struct _zend_object {
zend_refcounted gc;
uint32_t handle; // TODO: may be removed ???
@ -265,6 +283,12 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_CACHE_SLOT(zval) (zval).u2.cache_slot
#define Z_CACHE_SLOT_P(zval_p) Z_CACHE_SLOT(*(zval_p))
#define Z_FE_POS(zval) (zval).u2.fe_pos
#define Z_FE_POS_P(zval_p) Z_FE_POS(*(zval_p))
#define Z_FE_ITER(zval) (zval).u2.fe_iter_idx
#define Z_FE_ITER_P(zval_p) Z_FE_ITER(*(zval_p))
#define Z_COUNTED(zval) (zval).value.counted
#define Z_COUNTED_P(zval_p) Z_COUNTED(*(zval_p))
@ -295,6 +319,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define IS_TYPE_REFCOUNTED (1<<2)
#define IS_TYPE_COLLECTABLE (1<<3)
#define IS_TYPE_COPYABLE (1<<4)
#define IS_TYPE_SYMBOLTABLE (1<<5)
/* extended types */
#define IS_INTERNED_STRING_EX IS_STRING
@ -367,6 +392,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_IMMUTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_IMMUTABLE) != 0)
#define Z_IMMUTABLE_P(zval_p) Z_IMMUTABLE(*(zval_p))
#define Z_SYMBOLTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_SYMBOLTABLE) != 0)
#define Z_SYMBOLTABLE_P(zval_p) Z_SYMBOLTABLE(*(zval_p))
/* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */
#define Z_OPT_TYPE(zval) (Z_TYPE_INFO(zval) & 0xff)
#define Z_OPT_TYPE_P(zval_p) Z_OPT_TYPE(*(zval_p))
@ -416,7 +444,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_ARR(zval) (zval).value.arr
#define Z_ARR_P(zval_p) Z_ARR(*(zval_p))
#define Z_ARRVAL(zval) (&Z_ARR(zval)->ht)
#define Z_ARRVAL(zval) Z_ARR(zval)
#define Z_ARRVAL_P(zval_p) Z_ARRVAL(*(zval_p))
#define Z_OBJ(zval) (zval).value.obj
@ -555,8 +583,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define ZVAL_NEW_ARR(z) do { \
zval *__z = (z); \
zend_array *_arr = emalloc(sizeof(zend_array)); \
GC_REFCOUNT(_arr) = 1; \
GC_TYPE_INFO(_arr) = IS_ARRAY; \
Z_ARR_P(__z) = _arr; \
Z_TYPE_INFO_P(__z) = IS_ARRAY_EX; \
} while (0)
@ -564,8 +590,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define ZVAL_NEW_PERSISTENT_ARR(z) do { \
zval *__z = (z); \
zend_array *_arr = malloc(sizeof(zend_array)); \
GC_REFCOUNT(_arr) = 1; \
GC_TYPE_INFO(_arr) = IS_ARRAY; \
Z_ARR_P(__z) = _arr; \
Z_TYPE_INFO_P(__z) = IS_ARRAY_EX; \
} while (0)
@ -688,7 +712,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z))
static zend_always_inline uint32_t zval_refcount_p(zval* pz) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz));
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz) || Z_SYMBOLTABLE_P(pz));
return GC_REFCOUNT(Z_COUNTED_P(pz));
}

View File

@ -40,15 +40,13 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
case IS_ARRAY: {
zend_array *arr = (zend_array*)p;
if (arr != &EG(symbol_table)) {
ZEND_ASSERT(GC_REFCOUNT(arr) <= 1);
ZEND_ASSERT(GC_REFCOUNT(arr) <= 1);
/* break possible cycles */
GC_TYPE(arr) = IS_NULL;
GC_REMOVE_FROM_BUFFER(arr);
zend_array_destroy(&arr->ht);
efree_size(arr, sizeof(zend_array));
}
/* break possible cycles */
GC_TYPE(arr) = IS_NULL;
GC_REMOVE_FROM_BUFFER(arr);
zend_array_destroy(arr);
efree_size(arr, sizeof(zend_array));
break;
}
case IS_CONSTANT_AST: {
@ -100,13 +98,11 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC)
case IS_ARRAY: {
zend_array *arr = (zend_array*)p;
if (arr != &EG(symbol_table)) {
/* break possible cycles */
GC_TYPE(arr) = IS_NULL;
GC_REMOVE_FROM_BUFFER(arr);
zend_array_destroy(&arr->ht);
efree_size(arr, sizeof(zend_array));
}
/* break possible cycles */
GC_TYPE(arr) = IS_NULL;
GC_REMOVE_FROM_BUFFER(arr);
zend_array_destroy(arr);
efree_size(arr, sizeof(zend_array));
break;
}
case IS_CONSTANT_AST: {
@ -237,16 +233,8 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0);
break;
case IS_ARRAY: {
HashTable *ht;
if (Z_ARR_P(zvalue) == &EG(symbol_table)) {
return; /* do nothing */
}
ht = Z_ARRVAL_P(zvalue);
ZVAL_NEW_ARR(zvalue);
zend_array_dup(Z_ARRVAL_P(zvalue), ht);
}
case IS_ARRAY:
ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue)));
break;
case IS_CONSTANT_AST: {
zend_ast_ref *ast = emalloc(sizeof(zend_ast_ref));
@ -315,13 +303,13 @@ ZEND_API int zval_copy_static_var(zval *p, int num_args, va_list args, zend_hash
is_ref = Z_CONST_FLAGS_P(p) & IS_LEXICAL_REF;
symbol_table = zend_rebuild_symbol_table();
p = zend_hash_find(&symbol_table->ht, key->key);
p = zend_hash_find(symbol_table, key->key);
if (!p) {
p = &tmp;
ZVAL_NULL(&tmp);
if (is_ref) {
ZVAL_NEW_REF(&tmp, &tmp);
zend_hash_add_new(&symbol_table->ht, key->key, &tmp);
zend_hash_add_new(symbol_table, key->key, &tmp);
Z_ADDREF_P(p);
} else {
zend_error(E_NOTICE,"Undefined variable: %s", key->key->val);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
#include <stdio.h>
#include <zend.h>
const char *zend_vm_opcodes_map[170] = {
const char *zend_vm_opcodes_map[171] = {
"ZEND_NOP",
"ZEND_ADD",
"ZEND_SUB",
@ -99,8 +99,8 @@ const char *zend_vm_opcodes_map[170] = {
"ZEND_UNSET_VAR",
"ZEND_UNSET_DIM",
"ZEND_UNSET_OBJ",
"ZEND_FE_RESET",
"ZEND_FE_FETCH",
"ZEND_FE_RESET_R",
"ZEND_FE_FETCH_R",
"ZEND_EXIT",
"ZEND_FETCH_R",
"ZEND_FETCH_DIM_R",
@ -147,9 +147,9 @@ const char *zend_vm_opcodes_map[170] = {
"ZEND_DEFINED",
"ZEND_TYPE_CHECK",
"ZEND_VERIFY_RETURN_TYPE",
NULL,
NULL,
NULL,
"ZEND_FE_RESET_RW",
"ZEND_FE_FETCH_RW",
"ZEND_FE_FREE",
NULL,
NULL,
NULL,
@ -192,6 +192,7 @@ const char *zend_vm_opcodes_map[170] = {
"ZEND_ASSIGN_POW",
"ZEND_BIND_GLOBAL",
"ZEND_COALESCE",
"ZEND_SPACESHIP",
};
ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {

View File

@ -101,8 +101,8 @@ END_EXTERN_C()
#define ZEND_UNSET_VAR 74
#define ZEND_UNSET_DIM 75
#define ZEND_UNSET_OBJ 76
#define ZEND_FE_RESET 77
#define ZEND_FE_FETCH 78
#define ZEND_FE_RESET_R 77
#define ZEND_FE_FETCH_R 78
#define ZEND_EXIT 79
#define ZEND_FETCH_R 80
#define ZEND_FETCH_DIM_R 81
@ -149,6 +149,9 @@ END_EXTERN_C()
#define ZEND_DEFINED 122
#define ZEND_TYPE_CHECK 123
#define ZEND_VERIFY_RETURN_TYPE 124
#define ZEND_FE_RESET_RW 125
#define ZEND_FE_FETCH_RW 126
#define ZEND_FE_FREE 127
#define ZEND_PRE_INC_OBJ 132
#define ZEND_PRE_DEC_OBJ 133
#define ZEND_POST_INC_OBJ 134
@ -182,5 +185,6 @@ END_EXTERN_C()
#define ZEND_ASSIGN_POW 167
#define ZEND_BIND_GLOBAL 168
#define ZEND_COALESCE 169
#define ZEND_SPACESHIP 170
#endif

View File

@ -128,7 +128,7 @@ zend_module_entry bcmath_module_entry = {
#ifdef COMPILE_DL_BCMATH
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(bcmath)
#endif
@ -144,7 +144,7 @@ PHP_INI_END()
static PHP_GINIT_FUNCTION(bcmath)
{
#if defined(COMPILE_DL_BCMATH) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
bcmath_globals->bc_precision = 0;
bc_init_numbers();

View File

@ -51,7 +51,7 @@ ZEND_END_MODULE_GLOBALS(bcmath)
#ifdef ZTS
# define BCG(v) ZEND_TSRMG(bcmath_globals_id, zend_bcmath_globals *, v)
# ifdef COMPILE_DL_BCMATH
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
# endif
#else
# define BCG(v) (bcmath_globals.v)

View File

@ -255,7 +255,7 @@ zend_module_entry com_dotnet_module_entry = {
#ifdef COMPILE_DL_COM_DOTNET
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(com_dotnet)
#endif
@ -341,7 +341,7 @@ PHP_INI_END()
static PHP_GINIT_FUNCTION(com_dotnet)
{
#if defined(COMPILE_DL_COM_DOTNET) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
memset(com_dotnet_globals, 0, sizeof(*com_dotnet_globals));
com_dotnet_globals->code_page = CP_ACP;

View File

@ -55,7 +55,7 @@ ZEND_END_MODULE_GLOBALS(com_dotnet)
#ifdef ZTS
# define COMG(v) ZEND_TSRMG(com_dotnet_globals_id, zend_com_dotnet_globals *, v)
# ifdef COMPILE_DL_COM_DOTNET
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
# endif
#else
# define COMG(v) (com_dotnet_globals.v)

View File

@ -2004,12 +2004,13 @@ PHP_FUNCTION(curl_copy_handle)
static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ */
{
CURLcode error = CURLE_OK;
zend_long lval;
switch (option) {
/* Long options */
case CURLOPT_SSL_VERIFYHOST:
convert_to_long(zvalue);
if (Z_LVAL_P(zvalue) == 1) {
lval = zval_get_long(zvalue);
if (lval == 1) {
#if LIBCURL_VERSION_NUM <= 0x071c00 /* 7.28.0 */
php_error_docref(NULL, E_NOTICE, "CURLOPT_SSL_VERIFYHOST with value 1 is deprecated and will be removed as of libcurl 7.28.1. It is recommended to use value 2 instead");
#else
@ -2163,19 +2164,19 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
#if CURLOPT_MUTE != 0
case CURLOPT_MUTE:
#endif
convert_to_long_ex(zvalue);
lval = zval_get_long(zvalue);
#if LIBCURL_VERSION_NUM >= 0x71304
if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) &&
(PG(open_basedir) && *PG(open_basedir)) && (Z_LVAL_P(zvalue) & CURLPROTO_FILE)) {
(PG(open_basedir) && *PG(open_basedir)) && (lval & CURLPROTO_FILE)) {
php_error_docref(NULL, E_WARNING, "CURLPROTO_FILE cannot be activated when an open_basedir is set");
return 1;
}
#endif
error = curl_easy_setopt(ch->cp, option, Z_LVAL_P(zvalue));
error = curl_easy_setopt(ch->cp, option, lval);
break;
case CURLOPT_SAFE_UPLOAD:
convert_to_long_ex(zvalue);
ch->safe_upload = (Z_LVAL_P(zvalue) != 0);
lval = zval_get_long(zvalue);
ch->safe_upload = (lval != 0);
break;
/* String options */
@ -2236,8 +2237,10 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
case CURLOPT_MAIL_AUTH:
#endif
{
convert_to_string_ex(zvalue);
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 0);
zend_string *str = zval_get_string(zvalue);
int ret = php_curl_option_str(ch, option, str->val, str->len, 0);
zend_string_release(str);
return ret;
}
/* Curl nullable string options */
@ -2259,21 +2262,31 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
if (Z_ISNULL_P(zvalue)) {
error = curl_easy_setopt(ch->cp, option, NULL);
} else {
convert_to_string_ex(zvalue);
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 0);
zend_string *str = zval_get_string(zvalue);
int ret = php_curl_option_str(ch, option, str->val, str->len, 0);
zend_string_release(str);
return ret;
}
break;
}
/* Curl private option */
case CURLOPT_PRIVATE:
convert_to_string_ex(zvalue);
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 1);
{
zend_string *str = zval_get_string(zvalue);
int ret = php_curl_option_str(ch, option, str->val, str->len, 1);
zend_string_release(str);
return ret;
}
/* Curl url option */
case CURLOPT_URL:
convert_to_string_ex(zvalue);
return php_curl_option_url(ch, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue));
{
zend_string *str = zval_get_string(zvalue);
int ret = php_curl_option_url(ch, str->val, str->len);
zend_string_release(str);
return ret;
}
/* Curl file handle options */
case CURLOPT_FILE:
@ -2450,16 +2463,16 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
break;
case CURLOPT_FOLLOWLOCATION:
convert_to_long_ex(zvalue);
lval = zval_get_long(zvalue);
#if LIBCURL_VERSION_NUM < 0x071304
if (PG(open_basedir) && *PG(open_basedir)) {
if (Z_LVAL_P(zvalue) != 0) {
if (lval != 0) {
php_error_docref(NULL, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set");
return FAILURE;
}
}
#endif
error = curl_easy_setopt(ch->cp, option, Z_LVAL_P(zvalue));
error = curl_easy_setopt(ch->cp, option, lval);
break;
case CURLOPT_HEADERFUNCTION:
@ -2593,19 +2606,21 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
error = curl_easy_setopt(ch->cp, CURLOPT_HTTPPOST, first);
} else {
#if LIBCURL_VERSION_NUM >= 0x071101
convert_to_string_ex(zvalue);
zend_string *str = zval_get_string(zvalue);
/* with curl 7.17.0 and later, we can use COPYPOSTFIELDS, but we have to provide size before */
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_P(zvalue));
error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, Z_STRVAL_P(zvalue));
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, str->len);
error = curl_easy_setopt(ch->cp, CURLOPT_COPYPOSTFIELDS, str->val);
zend_string_release(str);
#else
char *post = NULL;
zend_string *str = zval_get_string(zvalue);
convert_to_string_ex(zvalue);
post = estrndup(Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue));
post = estrndup(str->val, str->len);
zend_llist_add_element(&ch->to_free->str, &post);
curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, post);
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, Z_STRLEN_P(zvalue));
error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, str->len);
zend_string_release(str);
#endif
}
break;
@ -2633,8 +2648,8 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
break;
case CURLOPT_RETURNTRANSFER:
convert_to_long_ex(zvalue);
if (Z_LVAL_P(zvalue)) {
lval = zval_get_long(zvalue);
if (lval) {
ch->handlers->write->method = PHP_CURL_RETURN;
} else {
ch->handlers->write->method = PHP_CURL_STDOUT;
@ -2653,15 +2668,15 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
#if LIBCURL_VERSION_NUM >= 0x070f05 /* Available since 7.15.5 */
case CURLOPT_MAX_RECV_SPEED_LARGE:
case CURLOPT_MAX_SEND_SPEED_LARGE:
convert_to_long_ex(zvalue);
error = curl_easy_setopt(ch->cp, option, (curl_off_t)Z_LVAL_P(zvalue));
lval = zval_get_long(zvalue);
error = curl_easy_setopt(ch->cp, option, (curl_off_t)lval);
break;
#endif
#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
case CURLOPT_POSTREDIR:
convert_to_long_ex(zvalue);
error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, Z_LVAL_P(zvalue) & CURL_REDIR_POST_ALL);
lval = zval_get_long(zvalue);
error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, lval & CURL_REDIR_POST_ALL);
break;
#endif
@ -2696,18 +2711,22 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
case CURLOPT_SSH_KNOWNHOSTS:
#endif
{
convert_to_string_ex(zvalue);
zend_string *str = zval_get_string(zvalue);
int ret;
if (Z_STRLEN_P(zvalue) && php_check_open_basedir(Z_STRVAL_P(zvalue))) {
if (str->len && php_check_open_basedir(str->val)) {
zend_string_release(str);
return FAILURE;
}
return php_curl_option_str(ch, option, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue), 0);
ret = php_curl_option_str(ch, option, str->val, str->len, 0);
zend_string_release(str);
return ret;
}
case CURLINFO_HEADER_OUT:
convert_to_long_ex(zvalue);
if (Z_LVAL_P(zvalue) == 1) {
lval = zval_get_long(zvalue);
if (lval == 1) {
curl_easy_setopt(ch->cp, CURLOPT_DEBUGFUNCTION, curl_debug);
curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *)ch);
curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 1);

View File

@ -2720,15 +2720,11 @@ static int php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *myht
php_timezone_obj *tzobj;
z_date = zend_hash_str_find(myht, "date", sizeof("data")-1);
if (z_date) {
convert_to_string(z_date);
if (z_date && Z_TYPE_P(z_date) == IS_STRING) {
z_timezone_type = zend_hash_str_find(myht, "timezone_type", sizeof("timezone_type")-1);
if (z_timezone_type) {
convert_to_long(z_timezone_type);
if (z_timezone_type && Z_TYPE_P(z_timezone_type) == IS_LONG) {
z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone")-1);
if (z_timezone) {
convert_to_string(z_timezone);
if (z_timezone && Z_TYPE_P(z_timezone) == IS_STRING) {
switch (Z_LVAL_P(z_timezone_type)) {
case TIMELIB_ZONETYPE_OFFSET:
case TIMELIB_ZONETYPE_ABBR: {
@ -2742,7 +2738,6 @@ static int php_date_initialize_from_hash(php_date_obj **dateobj, HashTable *myht
case TIMELIB_ZONETYPE_ID: {
int ret;
convert_to_string(z_timezone);
tzi = php_date_parse_tzfile(Z_STRVAL_P(z_timezone), DATE_TIMEZONEDB);
@ -3657,7 +3652,9 @@ static int php_date_timezone_initialize_from_hash(zval **return_value, php_timez
if ((z_timezone_type = zend_hash_str_find(myht, "timezone_type", sizeof("timezone_type")-1)) != NULL) {
if ((z_timezone = zend_hash_str_find(myht, "timezone", sizeof("timezone")-1)) != NULL) {
convert_to_long(z_timezone_type);
if(Z_TYPE_P(z_timezone_type) != IS_LONG) {
return FAILURE;
}
if (SUCCESS == timezone_initialize(*tzobj, Z_STRVAL_P(z_timezone))) {
return SUCCESS;
}
@ -3682,7 +3679,9 @@ PHP_METHOD(DateTimeZone, __set_state)
php_date_instantiate(date_ce_timezone, return_value);
tzobj = Z_PHPTIMEZONE_P(return_value);
php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht);
if(php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht) != SUCCESS) {
php_error_docref(NULL, E_ERROR, "Timezone initialization failed");
}
}
/* }}} */
@ -3698,7 +3697,9 @@ PHP_METHOD(DateTimeZone, __wakeup)
myht = Z_OBJPROP_P(object);
php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht);
if(php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht) != SUCCESS) {
php_error_docref(NULL, E_ERROR, "Timezone initialization failed");
}
}
/* }}} */

View File

@ -0,0 +1,9 @@
--TEST--
Bug #68942 (Use after free vulnerability in unserialize() with DateTimeZone).
--FILE--
<?php
$data = unserialize('a:2:{i:0;O:12:"DateTimeZone":2:{s:13:"timezone_type";a:2:{i:0;i:1;i:1;i:2;}s:8:"timezone";s:1:"A";}i:1;R:4;}');
var_dump($data);
?>
--EXPECTF--
Fatal error: DateTimeZone::__wakeup(): Timezone initialization failed in %s/bug68942.php on line %d

View File

@ -0,0 +1,9 @@
--TEST--
Bug #68942 (Use after free vulnerability in unserialize() with DateTime).
--FILE--
<?php
$data = unserialize('a:2:{i:0;O:8:"DateTime":3:{s:4:"date";s:26:"2000-01-01 00:00:00.000000";s:13:"timezone_type";a:2:{i:0;i:1;i:1;i:2;}s:8:"timezone";s:1:"A";}i:1;R:5;}');
var_dump($data);
?>
--EXPECTF--
Fatal error: Invalid serialization data for DateTime object in %s/bug68942_2.php on line %d

View File

@ -418,16 +418,14 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ *
HashTable *debug_info,
*prop_handlers = obj->prop_handler,
*std_props;
HashPosition pos;
zend_string *string_key;
dom_prop_handler *entry;
zval object_value;
*is_temp = 1;
ALLOC_HASHTABLE(debug_info);
std_props = zend_std_get_properties(object);
zend_array_dup(debug_info, std_props);
debug_info = zend_array_dup(std_props);
if (!prop_handlers) {
return debug_info;
@ -435,19 +433,10 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ *
ZVAL_STRING(&object_value, "(object value omitted)");
for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos);
(entry = zend_hash_get_current_data_ptr_ex(prop_handlers, &pos)) != NULL;
zend_hash_move_forward_ex(prop_handlers, &pos)) {
ZEND_HASH_FOREACH_STR_KEY_PTR(prop_handlers, string_key, entry) {
zval value;
zend_string *string_key;
zend_ulong num_key;
if (entry->read_func(obj, &value) == FAILURE) {
continue;
}
if (zend_hash_get_current_key_ex(prop_handlers, &string_key,
&num_key, &pos) != HASH_KEY_IS_STRING) {
if (entry->read_func(obj, &value) == FAILURE || !string_key) {
continue;
}
@ -457,7 +446,7 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ *
}
zend_hash_add(debug_info, string_key, &value);
}
} ZEND_HASH_FOREACH_END();
zval_dtor(&object_value);

View File

@ -520,14 +520,12 @@ PHP_FUNCTION(dom_xpath_register_php_functions)
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "a", &array_value) == SUCCESS) {
intern = Z_XPATHOBJ_P(id);
zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(array_value)))) {
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array_value), entry) {
zend_string *str = zval_get_string(entry);
ZVAL_LONG(&new_string,1);
zend_hash_update(intern->registered_phpfunctions, str, &new_string);
zend_hash_move_forward(Z_ARRVAL_P(array_value));
zend_string_release(str);
}
} ZEND_HASH_FOREACH_END();
intern->registerPhpFunctions = 2;
RETURN_TRUE;

View File

@ -552,13 +552,12 @@ PHP_FUNCTION(enchant_broker_request_dict)
d = enchant_broker_request_dict(pbroker->pbroker, (const char *)tag);
if (d) {
pos = pbroker->dictcnt++;
if (pbroker->dictcnt) {
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
pos = pbroker->dictcnt++;
} else {
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
pos = 0;
pbroker->dictcnt++;
}
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
@ -604,14 +603,14 @@ PHP_FUNCTION(enchant_broker_request_pwl_dict)
d = enchant_broker_request_pwl_dict(pbroker->pbroker, (const char *)pwl);
if (d) {
pos = pbroker->dictcnt++;
if (pbroker->dictcnt) {
pos = pbroker->dictcnt++;
pbroker->dict = (enchant_dict **)erealloc(pbroker->dict, sizeof(enchant_dict *) * pbroker->dictcnt);
} else {
pbroker->dict = (enchant_dict **)emalloc(sizeof(enchant_dict *));
pos = 0;
pbroker->dictcnt++;
}
dict = pbroker->dict[pos] = (enchant_dict *)emalloc(sizeof(enchant_dict));
dict->id = pos;
dict->pbroker = pbroker;

View File

@ -158,7 +158,7 @@ ZEND_DECLARE_MODULE_GLOBALS(exif)
#ifdef ZTS
#define EXIF_G(v) ZEND_TSRMG(exif_globals_id, zend_exif_globals *, v)
#ifdef COMPILE_DL_EXIF
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
#else
#define EXIF_G(v) (exif_globals.v)
@ -212,7 +212,7 @@ PHP_INI_END()
static PHP_GINIT_FUNCTION(exif)
{
#if defined(COMPILE_DL_EXIF) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
exif_globals->encode_unicode = NULL;
exif_globals->decode_unicode_be = NULL;

View File

@ -2192,7 +2192,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
+ zval_ptr_dtor(&patt);
+
+ ZVAL_STRING(&repl, rep);
+ res = php_pcre_replace_impl(pce, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
+ res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
+
+ zval_ptr_dtor(&repl);
+ if (NULL == res) {

View File

@ -457,7 +457,7 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
zval_ptr_dtor(&patt);
ZVAL_STRING(&repl, rep);
res = php_pcre_replace_impl(pce, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), &repl, 0, -1, &rep_cnt);
zval_ptr_dtor(&repl);
if (NULL == res) {

View File

@ -154,7 +154,7 @@ zend_module_entry filter_module_entry = {
#ifdef COMPILE_DL_FILTER
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(filter)
#endif
@ -196,7 +196,7 @@ PHP_INI_END()
static void php_filter_init_globals(zend_filter_globals *filter_globals) /* {{{ */
{
#if defined(COMPILE_DL_FILTER) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
ZVAL_UNDEF(&filter_globals->post_array);
ZVAL_UNDEF(&filter_globals->get_array);
@ -534,17 +534,13 @@ static zval *php_filter_get_storage(zend_long arg)/* {{{ */
break;
case PARSE_SERVER:
if (PG(auto_globals_jit)) {
zend_string *name = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
zend_is_auto_global(name);
zend_string_release(name);
zend_is_auto_global_str(ZEND_STRL("_SERVER"));
}
array_ptr = &IF_G(server_array);
break;
case PARSE_ENV:
if (PG(auto_globals_jit)) {
zend_string *name = zend_string_init("_ENV", sizeof("_ENV") - 1, 0);
zend_is_auto_global(name);
zend_string_release(name);
zend_is_auto_global_str(ZEND_STRL("_ENV"));
}
array_ptr = &IF_G(env_array) ? &IF_G(env_array) : &PG(http_globals)[TRACK_VARS_ENV];
break;

View File

@ -65,7 +65,7 @@ ZEND_END_MODULE_GLOBALS(filter)
#ifdef ZTS
#define IF_G(v) ZEND_TSRMG(filter_globals_id, zend_filter_globals *, v)
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
#else
#define IF_G(v) (filter_globals.v)
#endif

View File

@ -215,7 +215,7 @@ zend_module_entry gmp_module_entry = {
#ifdef COMPILE_DL_GMP
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(gmp)
#endif
@ -433,8 +433,7 @@ static HashTable *gmp_get_debug_info(zval *obj, int *is_temp) /* {{{ */
zval zv;
*is_temp = 1;
ALLOC_HASHTABLE(ht);
zend_array_dup(ht, props);
ht = zend_array_dup(props);
gmp_strval(&zv, gmpnum, 10);
zend_hash_str_update(ht, "num", sizeof("num")-1, &zv);
@ -560,7 +559,6 @@ static int gmp_serialize(zval *object, unsigned char **buffer, size_t *buf_len,
smart_str buf = {0};
zval zv;
php_serialize_data_t serialize_data = (php_serialize_data_t) data;
zend_array tmp_arr;
PHP_VAR_SERIALIZE_INIT(serialize_data);
@ -568,8 +566,7 @@ static int gmp_serialize(zval *object, unsigned char **buffer, size_t *buf_len,
php_var_serialize(&buf, &zv, &serialize_data);
zval_dtor(&zv);
ZVAL_ARR(&zv, &tmp_arr);
tmp_arr.ht = *zend_std_get_properties(object);
ZVAL_ARR(&zv, zend_std_get_properties(object));
php_var_serialize(&buf, &zv, &serialize_data);
PHP_VAR_SERIALIZE_DESTROY(serialize_data);
@ -633,7 +630,7 @@ exit:
static ZEND_GINIT_FUNCTION(gmp)
{
#if defined(COMPILE_DL_GMP) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
gmp_globals->rand_initialized = 0;
}

View File

@ -95,7 +95,7 @@ ZEND_END_MODULE_GLOBALS(gmp)
#ifdef ZTS
#define GMPG(v) ZEND_TSRMG(gmp_globals_id, zend_gmp_globals *, v)
#ifdef COMPILE_DL_GMP
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
#endif
#else
#define GMPG(v) (gmp_globals.v)

View File

@ -165,7 +165,7 @@ zend_module_entry iconv_module_entry = {
#ifdef COMPILE_DL_ICONV
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(iconv)
#endif
@ -174,7 +174,7 @@ ZEND_GET_MODULE(iconv)
static PHP_GINIT_FUNCTION(iconv)
{
#if defined(COMPILE_DL_ICONV) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
iconv_globals->input_encoding = NULL;
iconv_globals->output_encoding = NULL;

View File

@ -75,7 +75,7 @@ ZEND_END_MODULE_GLOBALS(iconv)
#ifdef ZTS
# define ICONVG(v) ZEND_TSRMG(iconv_globals_id, zend_iconv_globals *, v)
# ifdef COMPILE_DL_ICONV
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
# endif
#else
# define ICONVG(v) (iconv_globals.v)

View File

@ -229,8 +229,8 @@ PHP_FUNCTION(ibase_blob_create)
RETURN_FALSE;
}
ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(ib_blob, le_blob));
Z_TRY_ADDREF_P(return_value);
}
/* }}} */
@ -280,8 +280,8 @@ PHP_FUNCTION(ibase_blob_open)
break;
}
ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(ib_blob, le_blob));
Z_TRY_ADDREF_P(return_value);
return;
} while (0);
@ -300,11 +300,11 @@ PHP_FUNCTION(ibase_blob_add)
RESET_ERRMSG;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &string_arg) == FAILURE) {
WRONG_PARAM_COUNT;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &blob_arg, &string_arg)) {
return;
}
ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
ib_blob = (ibase_blob *)zend_fetch_resource_ex(blob_arg, "Interbase blob", le_blob);
if (ib_blob->type != BLOB_INPUT) {
_php_ibase_module_error("BLOB is not open for input");
@ -321,25 +321,24 @@ PHP_FUNCTION(ibase_blob_add)
Get len bytes data from open blob */
PHP_FUNCTION(ibase_blob_get)
{
zval *blob_arg, *len_arg;
zval *blob_arg;
unsigned long len_arg;
ibase_blob *ib_blob;
RESET_ERRMSG;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &blob_arg, &len_arg) == FAILURE) {
WRONG_PARAM_COUNT;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &blob_arg, &len_arg)) {
return;
}
ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
ib_blob = (ibase_blob *)zend_fetch_resource_ex(blob_arg, "Interbase blob", le_blob);
if (ib_blob->type != BLOB_OUTPUT) {
_php_ibase_module_error("BLOB is not open for output");
RETURN_FALSE;
}
convert_to_long_ex(len_arg);
if (_php_ibase_blob_get(return_value, ib_blob, Z_LVAL_P(len_arg)) != SUCCESS) {
if (_php_ibase_blob_get(return_value, ib_blob, len_arg) != SUCCESS) {
RETURN_FALSE;
}
}
@ -353,11 +352,11 @@ static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{
RESET_ERRMSG;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &blob_arg) == FAILURE) {
WRONG_PARAM_COUNT;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &blob_arg)) {
return;
}
ZEND_FETCH_RESOURCE(ib_blob, ibase_blob *, blob_arg, -1, "Interbase blob", le_blob);
ib_blob = (ibase_blob *)zend_fetch_resource_ex(blob_arg, "Interbase blob", le_blob);
if (bl_end == BLOB_CLOSE) { /* return id here */

View File

@ -142,7 +142,7 @@ PHP_FUNCTION(ibase_wait_event)
}
if (Z_TYPE(args[0]) == IS_RESOURCE) {
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, &args[0], -1, "InterBase link", le_link, le_plink)) {
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(&args[0], "InterBase link", le_link, le_plink)) == NULL) {
efree(args);
RETURN_FALSE;
}
@ -152,7 +152,7 @@ PHP_FUNCTION(ibase_wait_event)
efree(args);
WRONG_PARAM_COUNT;
}
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink)) {
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), "InterBase link", le_link, le_plink)) == NULL) {
efree(args);
RETURN_FALSE;
}
@ -293,7 +293,7 @@ PHP_FUNCTION(ibase_set_event_handler)
cb_arg = &args[1];
i = 2;
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, &args[0], -1, "InterBase link", le_link, le_plink)) {
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(&args[0], "InterBase link", le_link, le_plink)) == NULL) {
RETURN_FALSE;
}
@ -310,7 +310,7 @@ PHP_FUNCTION(ibase_set_event_handler)
cb_arg = &args[0];
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink)) {
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), "InterBase link", le_link, le_plink)) == NULL) {
RETURN_FALSE;
}
link_res_id = IBG(default_link);
@ -356,8 +356,8 @@ PHP_FUNCTION(ibase_set_event_handler)
event->event_next = ib_link->event_head;
ib_link->event_head = event;
ZEND_REGISTER_RESOURCE(return_value, event, le_event);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(event, le_event));
Z_TRY_ADDREF_P(return_value);
}
/* }}} */
@ -372,7 +372,7 @@ PHP_FUNCTION(ibase_free_event_handler)
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "r", &event_arg)) {
ibase_event *event;
ZEND_FETCH_RESOURCE(event, ibase_event *, event_arg, -1, "Interbase event", le_event);
event = (ibase_event *)zend_fetch_resource_ex(event_arg, "Interbase event", le_event);
event->state = DEAD;

View File

@ -910,8 +910,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul
(*l)->trans = trans;
(*l)->next = NULL;
ZEND_REGISTER_RESOURCE(return_value, trans, le_trans);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(trans, le_trans));
Z_TRY_ADDREF_P(return_value);
return SUCCESS;
@ -1080,8 +1080,8 @@ PHP_FUNCTION(ibase_query)
if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 3, "rrs",
&zlink, &ztrans, &query, &query_len)) {
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link*, zlink, -1, LE_LINK, le_link, le_plink);
ZEND_FETCH_RESOURCE(trans, ibase_trans*, ztrans, -1, LE_TRANS, le_trans);
ib_link = (ibase_db_link*)zend_fetch_resource2_ex(zlink, LE_LINK, le_link, le_plink);
trans = (ibase_trans*)zend_fetch_resource_ex(ztrans, LE_TRANS, le_trans);
trans_res_id = Z_RES_P(ztrans)->handle;
bind_i = 3;
@ -1131,8 +1131,8 @@ PHP_FUNCTION(ibase_query)
ib_link->tr_list = NULL;
ib_link->event_head = NULL;
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(ib_link, le_link));
Z_TRY_ADDREF_P(return_value);
IBG(default_link) = Z_RES_P(return_value)->handle;
++IBG(num_links);
}
@ -1142,7 +1142,7 @@ PHP_FUNCTION(ibase_query)
case 0:
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() ? 1 : 0, "s", &query,
&query_len)) {
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK,
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK,
le_link, le_plink);
bind_i = 1;
@ -1186,8 +1186,8 @@ PHP_FUNCTION(ibase_query)
if (ib_query.statement_type != isc_info_sql_stmt_exec_procedure) {
ib_query.stmt = NULL; /* keep stmt when free query */
}
ZEND_REGISTER_RESOURCE(return_value, result, le_result);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(result, le_result));
Z_TRY_ADDREF_P(return_value);
}
} while (0);
@ -1211,7 +1211,7 @@ PHP_FUNCTION(ibase_affected_rows)
}
if (!arg) {
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink);
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
RETURN_FALSE;
}
@ -1220,7 +1220,7 @@ PHP_FUNCTION(ibase_affected_rows)
/* one id was passed, could be db or trans id */
_php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, arg, &ib_link, &trans);
if (trans == NULL) {
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, arg, -1, LE_LINK, le_link, le_plink);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(arg, LE_LINK, le_link, le_plink);
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
RETURN_FALSE;
@ -1268,7 +1268,7 @@ PHP_FUNCTION(ibase_num_rows)
return;
}
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, &result_arg, -1, LE_RESULT, le_result);
ib_result = (ibase_result *)zend_fetch_resource_ex(&result_arg, LE_RESULT, le_result);
if (isc_dsql_sql_info(IB_STATUS, &ib_result->stmt, sizeof(info_count), info_count, sizeof(result), result)) {
_php_ibase_error();
@ -1335,7 +1335,7 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
#else
if (scale == 0) {
l = slprintf(string_data, sizeof(string_data), "%" LL_MASK "d", *(ISC_INT64 *) data);
ZVAL_STRINGL(val,string_data,l,1);
ZVAL_STRINGL(val,string_data,l);
} else {
ISC_INT64 n = *(ISC_INT64 *) data, f = scales[-scale];
@ -1346,7 +1346,7 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
} else {
l = slprintf(string_data, sizeof(string_data), "-0.%0*" LL_MASK "d", -scale, -n % f);
}
ZVAL_STRINGL(val,string_data,l,1);
ZVAL_STRINGL(val,string_data,l);
}
break;
#endif
@ -1482,7 +1482,7 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type)
return;
}
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
if (ib_result->out_sqlda == NULL || !ib_result->has_more_rows) {
RETURN_FALSE;
@ -1698,7 +1698,7 @@ PHP_FUNCTION(ibase_name_result)
return;
}
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
if (isc_dsql_set_cursor_name(IB_STATUS, &ib_result->stmt, name_arg, 0)) {
_php_ibase_error();
@ -1722,7 +1722,7 @@ PHP_FUNCTION(ibase_free_result)
return;
}
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
zend_list_delete(Z_RES_P(result_arg));
RETURN_TRUE;
}
@ -1745,7 +1745,7 @@ PHP_FUNCTION(ibase_prepare)
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query, &query_len) == FAILURE) {
return;
}
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink);
} else if (ZEND_NUM_ARGS() == 2) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &link_arg, &query, &query_len) == FAILURE) {
return;
@ -1759,8 +1759,8 @@ PHP_FUNCTION(ibase_prepare)
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrs", &link_arg, &trans_arg, &query, &query_len) == FAILURE) {
return;
}
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, -1, LE_LINK, le_link, le_plink);
ZEND_FETCH_RESOURCE(trans, ibase_trans *, trans_arg, -1, LE_TRANS, le_trans);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_arg, LE_LINK, le_link, le_plink);
trans = (ibase_trans *)zend_fetch_resource_ex(trans_arg, LE_TRANS, le_trans);
trans_res_id = Z_RES_P(trans_arg)->handle;
}
@ -1774,8 +1774,8 @@ PHP_FUNCTION(ibase_prepare)
efree(ib_query);
RETURN_FALSE;
}
ZEND_REGISTER_RESOURCE(return_value, ib_query, le_query);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(ib_query, le_query));
Z_TRY_ADDREF_P(return_value);
}
/* }}} */
@ -1796,7 +1796,7 @@ PHP_FUNCTION(ibase_execute)
return;
}
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, query, -1, LE_QUERY, le_query);
ib_query = (ibase_query *)zend_fetch_resource_ex(query, LE_QUERY, le_query);
do {
int expected_n = ib_query->in_sqlda ? ib_query->in_sqlda->sqld : 0;
@ -1849,8 +1849,8 @@ PHP_FUNCTION(ibase_execute)
ret = zend_list_insert(result, le_result);
ib_query->result_res_id = Z_RES_HANDLE_P(ret);
ZVAL_COPY_VALUE(return_value, ret);
Z_ADDREF_P(return_value);
Z_ADDREF_P(return_value);
Z_TRY_ADDREF_P(return_value);
Z_TRY_ADDREF_P(return_value);
}
} while (0);
}
@ -1869,7 +1869,7 @@ PHP_FUNCTION(ibase_free_query)
return;
}
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, query_arg, -1, LE_QUERY, le_query);
ib_query = (ibase_query *)zend_fetch_resource_ex(query_arg, LE_QUERY, le_query);
zend_list_close(Z_RES_P(query_arg));
RETURN_TRUE;
}
@ -1893,13 +1893,13 @@ PHP_FUNCTION(ibase_num_fields)
if (type == le_query) {
ibase_query *ib_query;
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result, -1, LE_QUERY, le_query);
ib_query = (ibase_query *)zend_fetch_resource_ex(result, LE_QUERY, le_query);
sqlda = ib_query->out_sqlda;
} else {
ibase_result *ib_result;
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result, -1, LE_RESULT, le_result);
ib_result = (ibase_result *)zend_fetch_resource_ex(result, LE_RESULT, le_result);
sqlda = ib_result->out_sqlda;
}
@ -2018,12 +2018,12 @@ PHP_FUNCTION(ibase_field_info)
if (type == le_query) {
ibase_query *ib_query;
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result_arg, -1, LE_QUERY, le_query);
ib_query= (ibase_query *)zend_fetch_resource_ex(result_arg, LE_QUERY, le_query);
sqlda = ib_query->out_sqlda;
} else {
ibase_result *ib_result;
ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result);
ib_result = (ibase_result *)zend_fetch_resource_ex(result_arg, LE_RESULT, le_result);
sqlda = ib_result->out_sqlda;
}
@ -2052,7 +2052,7 @@ PHP_FUNCTION(ibase_num_params)
return;
}
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result, -1, LE_QUERY, le_query);
ib_query = (ibase_query *)zend_fetch_resource_ex(result, LE_QUERY, le_query);
if (ib_query->in_sqlda == NULL) {
RETURN_LONG(0);
@ -2076,7 +2076,7 @@ PHP_FUNCTION(ibase_param_info)
return;
}
ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result_arg, -1, LE_QUERY, le_query);
ib_query = (ibase_query *)zend_fetch_resource_ex(result_arg, LE_QUERY, le_query);
if (ib_query->in_sqlda == NULL) {
RETURN_FALSE;

View File

@ -151,7 +151,7 @@ static void _php_ibase_user(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{
RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1, "Interbase service manager handle",
svm = (ibase_service *)zend_fetch_resource_ex(res, "Interbase service manager handle",
le_service);
buf[0] = operation;
@ -245,8 +245,8 @@ PHP_FUNCTION(ibase_service_attach)
svm->hostname = estrdup(host);
svm->username = estrdup(user);
ZEND_REGISTER_RESOURCE(return_value, svm, le_service);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(svm, le_service));
Z_TRY_ADDREF_P(return_value);
svm->res = Z_RES_P(return_value);
}
/* }}} */
@ -437,7 +437,7 @@ static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operati
RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1,
svm = (ibase_service *)zend_fetch_resource_ex(res,
"Interbase service manager handle", le_service);
/* fill the param buffer */
@ -500,7 +500,7 @@ static void _php_ibase_service_action(INTERNAL_FUNCTION_PARAMETERS, char svc_act
RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1,
svm = (ibase_service *)zend_fetch_resource_ex(res,
"Interbase service manager handle", le_service);
if (svc_action == isc_action_svc_db_stats) {
@ -606,7 +606,7 @@ PHP_FUNCTION(ibase_server_info)
RETURN_FALSE;
}
ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1,
svm = (ibase_service *)zend_fetch_resource_ex(res,
"Interbase service manager handle", le_service);
_php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, (char)action);

View File

@ -505,11 +505,11 @@ PHP_FUNCTION(ibase_errcode)
void _php_ibase_error(void) /* {{{ */
{
char *s = IBG(errmsg);
ISC_STATUS *statusp = IB_STATUS;
const ISC_STATUS *statusp = IB_STATUS;
IBG(sql_code) = isc_sqlcode(IB_STATUS);
while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) {
while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && fb_interpret(s, MAX_ERRMSG, &statusp)) {
strcat(IBG(errmsg), " ");
s = IBG(errmsg) + strlen(IBG(errmsg));
}
@ -553,7 +553,7 @@ void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
/* Transaction resource: make sure it refers to one link only, then
fetch it; database link is stored in ib_trans->db_link[]. */
IBDEBUG("Type is le_trans");
ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans);
*trans = (ibase_trans *)zend_fetch_resource_ex(link_id, LE_TRANS, le_trans);
if ((*trans)->link_cnt > 1) {
_php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections."
);
@ -565,7 +565,7 @@ void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
IBDEBUG("Type is le_[p]link or id not found");
/* Database link resource, use default transaction. */
*trans = NULL;
ZEND_FETCH_RESOURCE2(*ib_link, ibase_db_link *, link_id, -1, LE_LINK, le_link, le_plink);
*ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_id, LE_LINK, le_link, le_plink);
}
/* }}} */
@ -941,7 +941,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
xlink->gc.refcount++;
xlink->gc.refcount++;
IBG(default_link) = xlink->handle;
RETURN_RES(xlink);
RETVAL_RES(xlink);
} else {
zend_hash_str_del(&EG(regular_list), hash, sizeof(hash)-1);
}
@ -961,7 +961,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
/* check if connection has timed out */
ib_link = (ibase_db_link *) le->ptr;
if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) {
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
RETVAL_RES(zend_register_resource(ib_link, le_plink));
break;
}
zend_hash_str_del(&EG(persistent_list), hash, sizeof(hash)-1);
@ -982,7 +982,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
/* use non-persistent if allowed number of persistent links is exceeded */
if (!persistent || ((l = INI_INT("ibase.max_persistent") != -1) && IBG(num_persistent) >= l)) {
ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
RETVAL_RES(zend_register_resource(ib_link, le_link));
} else {
zend_resource new_le;
@ -999,7 +999,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
free(ib_link);
RETURN_FALSE;
}
ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
RETVAL_RES(zend_register_resource(ib_link, le_plink));
++IBG(num_persistent);
}
ib_link->handle = db_handle;
@ -1024,8 +1024,8 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
}
}
IBG(default_link) = Z_RES_P(return_value)->handle;
Z_ADDREF_P(return_value);
Z_ADDREF_P(return_value);
Z_TRY_ADDREF_P(return_value);
Z_TRY_ADDREF_P(return_value);
}
/* }}} */
@ -1067,7 +1067,7 @@ PHP_FUNCTION(ibase_close)
link_id = Z_RES_P(link_arg)->handle;
}
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, link_id, LE_LINK, le_link, le_plink);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_arg, LE_LINK, le_link, le_plink);
if (!link_arg) {
link_arg = zend_hash_index_find(&EG(regular_list), link_id);
zend_list_delete(Z_RES_P(link_arg));
@ -1105,7 +1105,7 @@ PHP_FUNCTION(ibase_drop_db)
link_id = Z_RES_P(link_arg)->handle;
}
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, link_id, LE_LINK, le_link, le_plink);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_arg, LE_LINK, le_link, le_plink);
if (isc_drop_database(IB_STATUS, &ib_link->handle)) {
_php_ibase_error();
@ -1168,7 +1168,7 @@ PHP_FUNCTION(ibase_trans)
if (Z_TYPE(args[i]) == IS_RESOURCE) {
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, &args[i], -1, LE_LINK, le_link, le_plink)) {
if ((ib_link[link_cnt] = (ibase_db_link *)zend_fetch_resource2_ex(&args[i], LE_LINK, le_link, le_plink)) == NULL) {
efree(teb);
efree(tpb);
efree(ib_link);
@ -1236,7 +1236,7 @@ PHP_FUNCTION(ibase_trans)
if (link_cnt == 0) {
link_cnt = 1;
if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[0], ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink)) {
if ((ib_link[0] = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink)) == NULL) {
efree(ib_link);
RETURN_FALSE;
}
@ -1273,8 +1273,8 @@ PHP_FUNCTION(ibase_trans)
(*l)->next = NULL;
}
efree(ib_link);
ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);
Z_ADDREF_P(return_value);
RETVAL_RES(zend_register_resource(ib_trans, le_trans));
Z_TRY_ADDREF_P(return_value);
}
/* }}} */
@ -1330,7 +1330,7 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{
}
if (ZEND_NUM_ARGS() == 0) {
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), LE_LINK, le_link, le_plink);
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
/* this link doesn't have a default transaction */
_php_ibase_module_error("Default link has no default transaction");
@ -1340,10 +1340,10 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{
} else {
/* one id was passed, could be db or trans id */
if (Z_RES_P(arg)->type == le_trans) {
ZEND_FETCH_RESOURCE(trans, ibase_trans *, arg, -1, LE_TRANS, le_trans);
trans = (ibase_trans *)zend_fetch_resource_ex(arg, LE_TRANS, le_trans);
res_id = Z_RES_P(arg)->handle;
} else {
ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, arg, -1, LE_LINK, le_link, le_plink);
ib_link = (ibase_db_link *)zend_fetch_resource2_ex(arg, LE_LINK, le_link, le_plink);
if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
/* this link doesn't have a default transaction */
@ -1467,7 +1467,7 @@ PHP_FUNCTION(ibase_gen_id)
int l;
l = spprintf(&res, 0, "%" LL_MASK "d", result);
RETURN_STRINGL(res, l, 0);
RETURN_STRINGL(res, l);
}
#endif
RETURN_LONG((long)result);

View File

@ -101,7 +101,7 @@ typedef struct event {
char **events;
char *event_buffer, *result_buffer;
zval callback;
void **thread_ctx;
void *thread_ctx;
struct event *event_next;
enum event_state { NEW, ACTIVE, DEAD } state;
} ibase_event;
@ -128,7 +128,14 @@ enum php_interbase_option {
};
#ifdef ZTS
#define IBG(v) TSRMG(ibase_globals_id, zend_ibase_globals *, v)
#else
#endif
#ifdef ZTS
# define IBG(v) ZEND_TSRMG(ibase_globals_id, zend_ibase_globals *, v)
# ifdef COMPILE_DL_INTERBASE
ZEND_TSRMLS_CACHE_EXTERN();
# endif
#else
#define IBG(v) (ibase_globals.v)
#endif
@ -155,9 +162,9 @@ void _php_ibase_module_error(char *, ...)
/* determine if a resource is a link or transaction handle */
#define PHP_IBASE_LINK_TRANS(zv, lh, th) \
do { if (!zv) { \
ZEND_FETCH_RESOURCE2(lh, ibase_db_link *, NULL, IBG(default_link), \
"InterBase link", le_link, le_plink) } \
do { if (!zv) { \
lh = (ibase_db_link *)zend_fetch_resource2(IBG(default_link), \
"InterBase link", le_link, le_plink); } \
else \
_php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, zv, &lh, &th); \
if (SUCCESS != _php_ibase_def_trans(lh, &th)) { RETURN_FALSE; } \

View File

@ -148,30 +148,20 @@ U_CFUNC PHP_FUNCTION(breakiter_get_text)
U_CFUNC PHP_FUNCTION(breakiter_set_text)
{
char *text;
size_t text_len;
UText *ut = NULL;
zval *textzv;
zend_string *text;
BREAKITER_METHOD_INIT_VARS;
object = getThis();
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s",
&text, &text_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &text) == FAILURE) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"breakiter_set_text: bad arguments", 0);
RETURN_FALSE;
}
int res = zend_get_parameters_ex(1, &textzv);
assert(res == SUCCESS);
BREAKITER_METHOD_FETCH_OBJECT;
/* assert it's safe to use text and text_len because zpp changes the
* arguments in the stack */
assert(text == Z_STRVAL_P(textzv));
ut = utext_openUTF8(ut, text, text_len, BREAKITER_ERROR_CODE_P(bio));
ut = utext_openUTF8(ut, text->val, text->len, BREAKITER_ERROR_CODE_P(bio));
INTL_CTOR_CHECK_STATUS(bio, "breakiter_set_text: error opening UText");
bio->biter->setText(ut, BREAKITER_ERROR_CODE(bio));
@ -183,7 +173,7 @@ U_CFUNC PHP_FUNCTION(breakiter_set_text)
* keep the string buffer around by holding a reference to its zval. This
* also allows a faste implementation of getText() */
zval_ptr_dtor(&bio->text);
ZVAL_COPY(&bio->text, textzv);
ZVAL_STR_COPY(&bio->text, text);
RETURN_TRUE;
}
@ -272,7 +262,7 @@ U_CFUNC PHP_FUNCTION(breakiter_next)
no_arg_version = true;
} else if (ZEND_NUM_ARGS() == 1) {
zval *arg;
int res = zend_get_parameters_ex(1, &arg);
int res = zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg);
assert(res == SUCCESS);
if (Z_TYPE_P(arg) == IS_NULL) {
no_arg_version = true;

View File

@ -86,8 +86,9 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
//nothing
} else if (Z_TYPE_P(format) == IS_ARRAY) {
HashTable *ht = Z_ARRVAL_P(format);
HashPosition pos = {0};
uint32_t idx;
zval *z;
if (zend_hash_num_elements(ht) != 2) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"datefmt_format_object: bad format; if array, it must have "
@ -95,9 +96,15 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
RETURN_FALSE;
}
zend_hash_internal_pointer_reset_ex(ht, &pos);
z = zend_hash_get_current_data_ex(ht, &pos);
if (!valid_format(z)) {
idx = 0;
while (idx < ht->nNumUsed) {
z = &ht->arData[idx].val;
if (Z_TYPE_P(z) != IS_UNDEF) {
break;
}
idx++;
}
if (idx >= ht->nNumUsed || !valid_format(z)) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"datefmt_format_object: bad format; the date format (first "
"element of the array) is not valid", 0);
@ -105,9 +112,15 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
}
dateStyle = (DateFormat::EStyle)Z_LVAL_P(z);
zend_hash_move_forward_ex(ht, &pos);
z = zend_hash_get_current_data_ex(ht, &pos);
if (!valid_format(z)) {
idx++;
while (idx < ht->nNumUsed) {
z = &ht->arData[idx].val;
if (Z_TYPE_P(z) != IS_UNDEF) {
break;
}
idx++;
}
if (idx >= ht->nNumUsed || !valid_format(z)) {
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"datefmt_format_object: bad format; the time format ("
"second element of the array) is not valid", 0);

View File

@ -895,7 +895,7 @@ zend_module_entry intl_module_entry = {
#ifdef COMPILE_DL_INTL
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE( intl )
#endif
@ -904,7 +904,7 @@ ZEND_GET_MODULE( intl )
static PHP_GINIT_FUNCTION(intl)
{
#if defined(COMPILE_DL_INTL) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
memset( intl_globals, 0, sizeof(zend_intl_globals) );
}

View File

@ -58,7 +58,7 @@ ZEND_END_MODULE_GLOBALS(intl)
#ifdef ZTS
#define INTL_G(v) ZEND_TSRMG(intl_globals_id, zend_intl_globals *, v)
#ifdef COMPILE_DL_INTL
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
#endif
#else
#define INTL_G(v) (intl_globals.v)

View File

@ -1,76 +1,16 @@
json 1.2.0
JSON
==========
This extension implements the JavaScript Object Notation (JSON)
data-interchange format as specified in [0].
data-interchange format as specified in RFC 7159
Two functions are implemented: encoding and decoding. The decoding
is handled by a parser based on JSON_checker[1] by Douglas Crockford.
The parser is implemented using re2c and Bison. The used versions
of both tools for generating files in the repository are following:
re2c 0.13.7.5
Bison 3.0.4
Function overview
-----------------
string json_encode ( mixed value )
json_encode returns a string containing the JSON representation of value.
value can be any type except a resource.
mixed json_decode ( string json, [bool assoc] )
json_decode takes a JSON string and converts it into a PHP variable.
When assoc is given, and evaluates to TRUE, json_decode() will return
any objects as associative arrays.
Example usage
-------------
$arr = array("a"=>1,"b"=>2,"c"=>3,"d"=>4,"e"=>5);
echo json_encode($arr);
---> {"a":1,"b":2,"c":3,"d":4,"e":5}
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
---> object(stdClass)#1 (5) {
["a"]=>
int(1)
["b"]=>
int(2)
["c"]=>
int(3)
["d"]=>
int(4)
["e"]=>
int(5)
}
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json, true));
---> array(5) {
["a"]=>
int(1)
["b"]=>
int(2)
["c"]=>
int(3)
["d"]=>
int(4)
["e"]=>
int(5)
}
Authors
-------
Omar Kilani <omar@php.net>
---
[0] http://www.crockford.com/JSON/draft-jsonorg-json-00.txt
[1] http://www.crockford.com/JSON/JSON_checker/
It is recommended to do all contributions to the JSON extension
through the Github Pull Requests and preferably ping @bukka
who maintains the extension.

View File

@ -134,7 +134,7 @@ static PHP_MINIT_FUNCTION(json)
static PHP_GINIT_FUNCTION(json)
{
#if defined(COMPILE_DL_JSON) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
json_globals->encoder_depth = 0;
json_globals->error_code = 0;
@ -165,7 +165,7 @@ zend_module_entry json_module_entry = {
#ifdef COMPILE_DL_JSON
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(json)
#endif

1860
ext/json/json_parser.tab.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED
# define YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int php_json_yydebug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
PHP_JSON_T_NUL = 258,
PHP_JSON_T_TRUE = 259,
PHP_JSON_T_FALSE = 260,
PHP_JSON_T_INT = 261,
PHP_JSON_T_DOUBLE = 262,
PHP_JSON_T_STRING = 263,
PHP_JSON_T_ESTRING = 264,
PHP_JSON_T_EOI = 265,
PHP_JSON_T_ERROR = 266
};
#endif
/* Tokens. */
#define PHP_JSON_T_NUL 258
#define PHP_JSON_T_TRUE 259
#define PHP_JSON_T_FALSE 260
#define PHP_JSON_T_INT 261
#define PHP_JSON_T_DOUBLE 262
#define PHP_JSON_T_STRING 263
#define PHP_JSON_T_ESTRING 264
#define PHP_JSON_T_EOI 265
#define PHP_JSON_T_ERROR 266
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
zval value;
struct {
zval key;
zval val;
} pair;
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
int php_json_yyparse (php_json_parser *parser);
#endif /* !YY_PHP_JSON_YY_HOME_JAKUB_PROG_PHP_MASTER_EXT_JSON_JSON_PARSER_TAB_H_INCLUDED */

View File

@ -67,7 +67,6 @@ int json_yydebug = 1;
%type <pair> pair
%destructor { zval_dtor(&$$); } <value>
%destructor { zend_hash_destroy($$); FREE_HASHTABLE($$); } <ht>
%destructor { zval_dtor(&$$.key); zval_dtor(&$$.val); } <pair>
%code {

File diff suppressed because it is too large Load Diff

View File

@ -81,7 +81,7 @@ static int php_json_ucs2_to_int(php_json_scanner *s, int size)
return php_json_ucs2_to_int_ex(s, size, 1);
}
void php_json_scanner_init(php_json_scanner *s, char *str, int str_len, long options)
void php_json_scanner_init(php_json_scanner *s, char *str, size_t str_len, int options)
{
s->cursor = (php_json_ctype *) str;
s->limit = (php_json_ctype *) str + str_len;
@ -171,7 +171,7 @@ std:
}
}
if (!bigint) {
ZVAL_LONG(&s->value, strtol((char *) s->token, NULL, 10));
ZVAL_LONG(&s->value, ZEND_STRTOL((char *) s->token, NULL, 10));
return PHP_JSON_T_INT;
} else if (s->options & PHP_JSON_BIGINT_AS_STRING) {
ZVAL_STRINGL(&s->value, (char *) s->token, s->cursor - s->token);

View File

@ -1,152 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE package SYSTEM "../pear/package.dtd">
<package>
<dep type="php" rel="ge" version="4.3.0" optional="no"/>
<name>json</name>
<summary>JavaScript Object Notation</summary>
<maintainers>
<maintainer>
<user>omar</user>
<name>Omar Kilani</name>
<email>omar@php.net</email>
<role>lead</role>
</maintainer>
</maintainers>
<description>
Support for JSON (JavaScript Object Notation) serialization.
</description>
<license>PHP 3.01</license>
<release>
<state>stable</state>
<version>1.2.1</version>
<date>2006-03-18</date>
<notes>
Fix PECL bug #7147 - rework handling of comma insertion while encoding.
Add tests to package.xml
</notes>
</release>
<configureoptions>
</configureoptions>
<filelist>
<file role="doc" name="README" />
<file role="src" name="config.m4" />
<file role="src" name="config.w32" />
<file role="src" name="json.dsp" />
<file role="src" name="json.c" />
<file role="src" name="JSON_parser.c" />
<file role="src" name="JSON_parser.h" />
<file role="src" name="php_json.h" />
<file role="src" name="utf8_decode.c" />
<file role="src" name="utf8_decode.h" />
<file role="src" name="utf8_to_utf16.c" />
<file role="src" name="utf8_to_utf16.h" />
<dir role="test" name="tests">
<file role="test" name="fail001.phpt" />
<file role="test" name="pass001.phpt" />
<file role="test" name="pass001.1.phpt" />
<file role="test" name="pass002.phpt" />
<file role="test" name="pass003.phpt" />
</dir>
</filelist>
<changelog>
<release>
<state>stable</state>
<version>1.0.0</version>
<date>2005-04-01</date>
<notes>
Initial release.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.1</version>
<date>2005-06-10</date>
<notes>
Fixed non-linear and mixed type array index issues, fixed issues with escaping \\, forked json-c and added Unicode support.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.2</version>
<date>2005-06-11</date>
<notes>
Fixed issues with object reference counts under PHP4.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.3</version>
<date>2005-06-15</date>
<notes>
Fixed json-c string corruption issues under Mac OS X and FreeBSD.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.4</version>
<date>2005-06-15</date>
<notes>
Changes in 1.0.4 released with 1.0.5.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.5</version>
<date>2005-06-16</date>
<notes>
Changed spacing in json-c encoding, added optional assoc (boolean) parameter to json_decode to decode as associative array instead of object, fixed issues with escaping /.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.6</version>
<date>2005-08-05</date>
<notes>
Fixed issues with exporting private and protected class members.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.7</version>
<date>2005-09-07</date>
<notes>
Fixed issues with negative array keys, modified json-c to return an error on unquoted object key names instead of going into an infinite loop.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.8</version>
<date>2005-12-01</date>
<notes>
Changed license to LGPL, modified build system to allow static compilation into PHP, added strndup check for json-c.
</notes>
</release>
<release>
<state>stable</state>
<version>1.1.0</version>
<date>2005-12-04</date>
<notes>
Port to Win32.
</notes>
</release>
<release>
<state>stable</state>
<version>1.1.1</version>
<date>2006-01-12</date>
<notes>
Cleanup and TSRM performance fixes by rasmus.
</notes>
</release>
<release>
<state>stable</state>
<version>1.2.0</version>
<date>2006-03-15</date>
<notes>
Complete rewrite using JSON_checker as the base for the parser. Implements the JSON specification. 3-8x faster on encodes and 1.2x-4x faster on decodes.
</notes>
</release>
</changelog>
</package>
<!--
vim:et:ts=1:sw=1
-->

View File

@ -22,7 +22,7 @@
#ifndef PHP_JSON_H
#define PHP_JSON_H
#define PHP_JSON_VERSION "1.2.1"
#define PHP_JSON_VERSION "1.4.0"
#include "zend_smart_str_public.h"
extern zend_module_entry json_module_entry;

View File

@ -32,15 +32,15 @@ typedef struct _php_json_scanner {
php_json_ctype *ctxmarker; /* marker position for context backtracking */
php_json_ctype *str_start; /* start position of the string */
php_json_ctype *pstr; /* string pointer for escapes conversion */
zval value; /* value */
int str_esc; /* number of extra characters for escaping */
int state; /* condition state */
zval value; /* value */
long options; /* options */
int options; /* options */
php_json_error_code errcode; /* error type if there is an error */
} php_json_scanner;
void php_json_scanner_init(php_json_scanner *scanner, char *str, int str_len, long options);
void php_json_scanner_init(php_json_scanner *scanner, char *str, size_t str_len, int options);
int php_json_scan(php_json_scanner *s);
#endif /* PHP_JSON_SCANNER_H */

View File

@ -1,4 +1,4 @@
/* Generated by re2c 0.13.5 */
/* Generated by re2c 0.13.7.5 */
enum YYCONDTYPE {
yycJS,

View File

@ -80,7 +80,7 @@ static zend_class_entry *libxmlerror_class_entry;
/* {{{ dynamically loadable module stuff */
#ifdef COMPILE_DL_LIBXML
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE;
ZEND_TSRMLS_CACHE_DEFINE();
#endif
ZEND_GET_MODULE(libxml)
#endif /* COMPILE_DL_LIBXML */
@ -272,7 +272,7 @@ static void php_libxml_node_free_list(xmlNodePtr node)
static PHP_GINIT_FUNCTION(libxml)
{
#if defined(COMPILE_DL_LIBXML) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE;
ZEND_TSRMLS_CACHE_UPDATE();
#endif
ZVAL_UNDEF(&libxml_globals->stream_context);
libxml_globals->error_buffer.s = NULL;
@ -752,7 +752,7 @@ PHP_LIBXML_API void php_libxml_shutdown(void)
#if defined(LIBXML_SCHEMAS_ENABLED)
xmlRelaxNGCleanupTypes();
#endif
xmlCleanupParser();
/* xmlCleanupParser(); */
zend_hash_destroy(&php_libxml_exports);
xmlSetExternalEntityLoader(_php_libxml_default_entity_loader);

View File

@ -115,7 +115,7 @@ PHP_LIBXML_API void php_libxml_shutdown(void);
#ifdef ZTS
#define LIBXML(v) ZEND_TSRMG(libxml_globals_id, zend_libxml_globals *, v)
#ifdef COMPILE_DL_LIBXML
ZEND_TSRMLS_CACHE_EXTERN;
ZEND_TSRMLS_CACHE_EXTERN();
#endif
#else
#define LIBXML(v) (libxml_globals.v)

Some files were not shown because too many files have changed in this diff Show More