mirror of
https://github.com/php/php-src.git
synced 2024-09-25 11:57:26 +00:00
Merge branch 'PHP-7.1' of git.php.net:php-src into PHP-7.1
* 'PHP-7.1' of git.php.net:php-src: (134 commits) fix useless assignment avoid needless function call remove useless assignment remove unused assignment rewrite the getcwd part fix leak fix unused assignment remove duplicated symbol Revert39587c4817
8b7f594a2b
Because of24fdffdacb
add extra test to protected behavior of compact and array string key order fix unintentional bc break with compact('this') behavior Fix some grammatical errors in PHP 7.1 Upgrade Notes Update NEWS Fixed bug #72982 (Memory leak in zend_accel_blacklist_update_regexp() function) Update NEWS and UPGRADING Revert "Revert "Implement RFC Add session_gc() https://wiki.php.net/rfc/session-gc"" Revert "Revert "Merge RFC https://wiki.php.net/rfc/session-create-id"" Revert "Revert "Add tests"" Revert "Fix NEWS" Fix bug #72940 properly. Reduce needless branches ...
This commit is contained in:
commit
2adc335eb5
92
NEWS
92
NEWS
@ -1,8 +1,90 @@
|
||||
PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? 2016, PHP 7.1.0RC1
|
||||
?? ??? 2016, PHP 7.1.0RC2
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #72982 (Memory leak in zend_accel_blacklist_update_regexp()
|
||||
function). (Laruence)
|
||||
|
||||
|
||||
01 Sep 2016, PHP 7.1.0RC1
|
||||
|
||||
- Core:
|
||||
. Fixed bug #72944 (Null pointer deref in zval_delref_p). (Dmitry)
|
||||
. Fixed bug #72943 (assign_dim on string doesn't reset hval). (Laruence)
|
||||
. Fixed bug #72598 (Reference is lost after array_slice()) (Nikita)
|
||||
. Fixed bug #72703 (Out of bounds global memory read in BF_crypt triggered by
|
||||
password_verify). (Anatol)
|
||||
. Implement \ArgumentCountError when passing in too few arguments (Davey)
|
||||
|
||||
- COM:
|
||||
. Fixed bug #72922 (COM called from PHP does not return out parameters).
|
||||
(Anatol)
|
||||
|
||||
- Dba:
|
||||
. Fixed bug #70825 (Cannot fetch multiple values with group in ini file).
|
||||
(cmb)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #66005 (imagecopy does not support 1bit transparency on truecolor
|
||||
images). (cmb)
|
||||
. Fixed bug #72913 (imagecopy() loses single-color transparency on palette
|
||||
images). (cmb)
|
||||
. Fixed bug #68716 (possible resource leaks in _php_image_convert()). (cmb)
|
||||
|
||||
- iconv:
|
||||
. Fixed bug #72320 (iconv_substr returns false for empty strings). (cmb)
|
||||
|
||||
- Intl:
|
||||
. Fixed bug #65732 (grapheme_*() is not Unicode compliant on CR LF
|
||||
sequence). (cmb)
|
||||
|
||||
- JSON:
|
||||
. Implemented earlier return when json_encode fails, fixes bugs #68992
|
||||
(Stacking exceptions thrown by JsonSerializable) and #70275 (On recursion
|
||||
error, json_encode can eat up all system memory). (Jakub Zelenka)
|
||||
|
||||
- mbstring:
|
||||
. Fixed bug #66797 (mb_substr only takes 32-bit signed integer). (cmb)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #72949 (Typo in opcache error message). (cmb)
|
||||
|
||||
- PDO_DBlib:
|
||||
. Implemented stringify 'uniqueidentifier' fields.
|
||||
(Alexander Zhuravlev, Adam Baratz)
|
||||
|
||||
- Reflection:
|
||||
. Reverted prepending \ for class names. (Trowski)
|
||||
|
||||
- Session:
|
||||
. Fixed bug #72940 (SID always return "name=ID", even if session
|
||||
cookie exist). (Yasuo)
|
||||
. Implemented session_gc() (Yasuo)
|
||||
https://wiki.php.net/rfc/session-create-id
|
||||
. Implemented session_create_id() (Yasuo)
|
||||
https://wiki.php.net/rfc/session-gc
|
||||
|
||||
- SimpleXML:
|
||||
. Fixed bug #72971 (SimpleXML isset/unset do not respect namespace). (Nikita)
|
||||
. Fixed bug #72957 (Null coalescing operator doesn't behave as expected with
|
||||
SimpleXMLElement). (Nikita)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug #71711 (Soap Server Member variables reference bug). (Nikita)
|
||||
. Fixed bug #71996 (Using references in arrays doesn't work like expected).
|
||||
(Nikita)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #72920 (Accessing a private constant using constant() creates
|
||||
an exception AND warning). (Laruence)
|
||||
. Fixed bug #65550 (get_browser() incorrectly parses entries with "+" sign).
|
||||
(cmb)
|
||||
. Fixed bug #71882 (Negative ftruncate() on php://memory exhausts memory).
|
||||
(cmb)
|
||||
|
||||
- XML:
|
||||
. Fixed bug #72714 (_xml_startElementHandler() segmentation fault). (cmb)
|
||||
|
||||
18 Aug 2016, PHP 7.1.0beta3
|
||||
|
||||
@ -18,6 +100,8 @@ PHP NEWS
|
||||
. Fixed bug #72681 (PHP Session Data Injection Vulnerability). (Stas)
|
||||
. Fixed bug #72742 (memory allocator fails to realloc small block to large
|
||||
one). (Stas)
|
||||
. Fixed URL rewriter. It would not rewrite '//example.com/' URL
|
||||
unconditionally. URL rewrite target hosts whitelist is implemented. (Yasuo)
|
||||
|
||||
- Bz2:
|
||||
. Fixed bug #72837 (integer overflow in bzdecompress caused heap
|
||||
@ -59,8 +143,10 @@ PHP NEWS
|
||||
- Reflection:
|
||||
. Implemented request #38992 (invoke() and invokeArgs() static method calls
|
||||
should match). (cmb).
|
||||
. Add ReflectionNamedType::getName() and return leading "?" for nullable types
|
||||
from ReflectionType::__toString(). (Trowski)
|
||||
. Add ReflectionNamedType::getName(). This method should be used instead of
|
||||
ReflectionType::__toString()
|
||||
. Prepend \ for class names and ? for nullable types returned from
|
||||
ReflectionType::__toString(). (Trowski)
|
||||
|
||||
- Session:
|
||||
. Implemented RFC: Session ID without hashing. (Yasuo)
|
||||
|
@ -672,6 +672,12 @@ TSRM_API int shmget(int key, int size, int flags)
|
||||
}
|
||||
} else {
|
||||
if (flags & IPC_EXCL) {
|
||||
if (shm_handle) {
|
||||
CloseHandle(shm_handle);
|
||||
}
|
||||
if (info_handle) {
|
||||
CloseHandle(info_handle);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
12
UPGRADING
12
UPGRADING
@ -61,7 +61,7 @@ PHP 7.1 UPGRADE NOTES
|
||||
. Fixes to random number generators mean that mt_rand() now produces a
|
||||
different sequence of outputs to previous versions. If you relied on
|
||||
mt_srand() to produce a deterministic sequence, it can be called using
|
||||
mt_srand($seed, MT_RAND_PHP) to produce old the sequences.
|
||||
mt_srand($seed, MT_RAND_PHP) to produce the old sequences.
|
||||
. URL rewriter has been improved.
|
||||
. Use dedicated buffer for Session module rewrite and User rewrite.
|
||||
. Full path URL rewrite is supported. Allowed domain can be specified.
|
||||
@ -122,7 +122,7 @@ PHP 7.1 UPGRADE NOTES
|
||||
|
||||
- Reflection:
|
||||
. The behavior of ReflectionMethod::invoke() and ::invokeArgs() has been
|
||||
aligned, what causes slightly different behavior than before for some
|
||||
aligned, which causes slightly different behavior than before for some
|
||||
pathological cases.
|
||||
. ReflectionType::__toString() will now return the type name with a leading
|
||||
"?" if it is nullable. To retrieve the type name without leading "?" the new
|
||||
@ -236,6 +236,12 @@ PHP 7.1 UPGRADE NOTES
|
||||
. Added pcntl_signal_get_handler() that returns the current signal handler
|
||||
for a particular signal.
|
||||
|
||||
- Session:
|
||||
. Added session_gc() that performs session data garbage collection.
|
||||
https://wiki.php.net/rfc/session-gc
|
||||
. Added session_create_id() for creating custom session ID.
|
||||
https://wiki.php.net/rfc/session-create-id
|
||||
|
||||
- Standard:
|
||||
. Added is_iterable() that determines if a value will be accepted by the new
|
||||
iterable pseudo-type.
|
||||
@ -262,7 +268,7 @@ PHP 7.1 UPGRADE NOTES
|
||||
|
||||
- DBA:
|
||||
. Data modification functions (e.g.: dba_insert()) now throw an instance of
|
||||
Error instead of triggering a catchable fatal error if the key is does not
|
||||
Error instead of triggering a catchable fatal error if the key does not
|
||||
contain exactly two elements.
|
||||
|
||||
- DOM:
|
||||
|
@ -82,6 +82,8 @@ changes. See: https://wiki.php.net/phpng-upgrading
|
||||
a. Unix build system changes
|
||||
|
||||
b. Windows build system changes
|
||||
Static analysis with clang and Cppcheck is supported by passing "clang" or
|
||||
"cppcheck" keyword to the --with-analyzer configure option.
|
||||
|
||||
========================
|
||||
3. Module changes
|
||||
|
@ -44,7 +44,7 @@ Non-static method A::A_ftk() should not be called statically
|
||||
2 %sbug38047.php:36 kalus_error_handler()
|
||||
|
||||
|
||||
Fatal error: Uncaught Error: Too few arguments to function A::A_ftk(), 0 passed in %sbug38047.php on line 36 and exactly 1 expected in %sbug38047.php:7
|
||||
Fatal error: Uncaught ArgumentCountError: Too few arguments to function A::A_ftk(), 0 passed in %sbug38047.php on line 36 and exactly 1 expected in %sbug38047.php:7
|
||||
Stack trace:
|
||||
#0 %sbug38047.php(36): A::A_ftk()
|
||||
#1 {main}
|
||||
|
@ -6,7 +6,7 @@ function f(callable $c) {}
|
||||
f();
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Too few arguments to function f(), 0 passed in %s on line 3 and exactly 1 expected in %s:2
|
||||
Fatal error: Uncaught ArgumentCountError: Too few arguments to function f(), 0 passed in %s on line 3 and exactly 1 expected in %s:2
|
||||
Stack trace:
|
||||
#0 %s(%d): f()
|
||||
#1 {main}
|
||||
|
@ -19,7 +19,7 @@ try {
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Too few arguments to function foo(), 0 passed in %sbug70689.php on line 12 and exactly 1 expected in %sbug70689.php:3
|
||||
Fatal error: Uncaught ArgumentCountError: Too few arguments to function foo(), 0 passed in %sbug70689.php on line 12 and exactly 1 expected in %sbug70689.php:3
|
||||
Stack trace:
|
||||
#0 %sbug70689.php(12): foo()
|
||||
#1 {main}
|
||||
|
26
Zend/tests/bug72598.phpt
Normal file
26
Zend/tests/bug72598.phpt
Normal file
@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #72598 (Reference is lost after array_slice())
|
||||
--FILE--
|
||||
<?php
|
||||
function ref(&$ref) {
|
||||
var_dump($ref);
|
||||
}
|
||||
|
||||
new class {
|
||||
function __construct() {
|
||||
$args = [&$this];
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$a = array_slice($args, 0, 1);
|
||||
call_user_func_array('ref', $a);
|
||||
}
|
||||
}
|
||||
};
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Parameter 1 to ref() expected to be a reference, value given in %sbug72598.php on line 11
|
||||
object(class@anonymous)#1 (0) {
|
||||
}
|
||||
|
||||
Warning: Parameter 1 to ref() expected to be a reference, value given in %sbug72598.php on line 11
|
||||
object(class@anonymous)#1 (0) {
|
||||
}
|
27
Zend/tests/bug72598_2.phpt
Normal file
27
Zend/tests/bug72598_2.phpt
Normal file
@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
Bug #72598.2 (Reference is lost after array_slice())
|
||||
--FILE--
|
||||
<?php
|
||||
function ref(&$ref) {
|
||||
var_dump($ref);
|
||||
$ref = 1;
|
||||
}
|
||||
|
||||
new class {
|
||||
function __construct() {
|
||||
$b = 0;
|
||||
$args = [&$b];
|
||||
unset($b);
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$a = array_slice($args, 0, 1);
|
||||
call_user_func_array('ref', $a);
|
||||
}
|
||||
}
|
||||
};
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Parameter 1 to ref() expected to be a reference, value given in %sbug72598_2.php on line 14
|
||||
int(0)
|
||||
|
||||
Warning: Parameter 1 to ref() expected to be a reference, value given in %sbug72598_2.php on line 14
|
||||
int(0)
|
17
Zend/tests/bug72911.phpt
Normal file
17
Zend/tests/bug72911.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #72911 (Memleak in zend_binary_assign_op_obj_helper)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = 0;
|
||||
|
||||
$b = $a->b->i -= 0;
|
||||
|
||||
var_dump($b);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Attempt to modify property of non-object in %sbug72911.php on line %d
|
||||
|
||||
Warning: Attempt to assign property of non-object in %sbug72911.php on line %d
|
||||
NULL
|
20
Zend/tests/bug72943.phpt
Normal file
20
Zend/tests/bug72943.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug #72943 (assign_dim on string doesn't reset hval)
|
||||
--FILE--
|
||||
<?php
|
||||
$array = array("test" => 1);
|
||||
|
||||
$a = "lest";
|
||||
var_dump($array[$a]);
|
||||
$a[0] = "f";
|
||||
var_dump($array[$a]);
|
||||
$a[0] = "t";
|
||||
var_dump($array[$a]);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Undefined index: lest in %sbug72943.php on line %d
|
||||
NULL
|
||||
|
||||
Notice: Undefined index: fest in %sbug72943.php on line %d
|
||||
NULL
|
||||
int(1)
|
12
Zend/tests/bug72944.phpt
Normal file
12
Zend/tests/bug72944.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #72944 (Null pointer deref in zval_delref_p).
|
||||
--FILE--
|
||||
<?php
|
||||
"a"== e & $A = $A? 0 : 0 ?:0;
|
||||
echo "OK\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Notice: Use of undefined constant e - assumed 'e' in %sbug72944.php on line 2
|
||||
|
||||
Notice: Undefined variable: A in %sbug72944.php on line 2
|
||||
OK
|
54
Zend/tests/call_user_func_008.phpt
Normal file
54
Zend/tests/call_user_func_008.phpt
Normal file
@ -0,0 +1,54 @@
|
||||
--TEST--
|
||||
call_user_func() behavior with references
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test(&$ref1, &$ref2) {
|
||||
$ref1 += 42;
|
||||
$ref2 -= 42;
|
||||
return true;
|
||||
}
|
||||
|
||||
$i = $j = 0;
|
||||
var_dump(call_user_func('test', $i, $j));
|
||||
var_dump($i, $j);
|
||||
|
||||
var_dump(call_user_func_array('test', [$i, $j]));
|
||||
var_dump($i, $j);
|
||||
|
||||
$x =& $i; $y =& $j;
|
||||
var_dump(call_user_func('test', $i, $j));
|
||||
var_dump($i, $j);
|
||||
|
||||
var_dump(call_user_func_array('test', [$i, $j]));
|
||||
var_dump($i, $j);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Parameter 1 to test() expected to be a reference, value given in %s on line %d
|
||||
|
||||
Warning: Parameter 2 to test() expected to be a reference, value given in %s on line %d
|
||||
bool(true)
|
||||
int(0)
|
||||
int(0)
|
||||
|
||||
Warning: Parameter 1 to test() expected to be a reference, value given in %s on line %d
|
||||
|
||||
Warning: Parameter 2 to test() expected to be a reference, value given in %s on line %d
|
||||
bool(true)
|
||||
int(0)
|
||||
int(0)
|
||||
|
||||
Warning: Parameter 1 to test() expected to be a reference, value given in %s on line %d
|
||||
|
||||
Warning: Parameter 2 to test() expected to be a reference, value given in %s on line %d
|
||||
bool(true)
|
||||
int(0)
|
||||
int(0)
|
||||
|
||||
Warning: Parameter 1 to test() expected to be a reference, value given in %s on line %d
|
||||
|
||||
Warning: Parameter 2 to test() expected to be a reference, value given in %s on line %d
|
||||
bool(true)
|
||||
int(0)
|
||||
int(0)
|
20
Zend/tests/function_arguments/argument_count_correct.phpt
Normal file
20
Zend/tests/function_arguments/argument_count_correct.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Call function with correct number of arguments
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() { }
|
||||
foo();
|
||||
|
||||
function bar($foo, $bar) { }
|
||||
bar(1, 2);
|
||||
|
||||
function bat(int $foo, string $bar) { }
|
||||
bat(123, "foo");
|
||||
bat("123", "foo");
|
||||
|
||||
$fp = fopen(__FILE__, "r");
|
||||
fclose($fp);
|
||||
|
||||
echo "done";
|
||||
--EXPECT--
|
||||
done
|
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Call function with correct number of arguments with strict types
|
||||
--FILE--
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
function foo() { }
|
||||
foo();
|
||||
|
||||
function bar($foo, $bar) { }
|
||||
bar(1, 2);
|
||||
|
||||
function bat(int $foo, string $bar) { }
|
||||
bat(123, "foo");
|
||||
|
||||
$fp = fopen(__FILE__, "r");
|
||||
fclose($fp);
|
||||
|
||||
echo "done";
|
||||
--EXPECT--
|
||||
done
|
@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Call internal function with incorrect number of arguments
|
||||
--FILE--
|
||||
<?php
|
||||
substr("foo");
|
||||
array_diff([]);
|
||||
--EXPECTF--
|
||||
Warning: substr() expects at least 2 parameters, 1 given in %s
|
||||
|
||||
Warning: array_diff(): at least 2 parameters are required, 1 given in %s
|
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Call internal function with incorrect number of arguments with strict types
|
||||
--FILE--
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
try {
|
||||
substr("foo");
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
array_diff([]);
|
||||
--EXPECTF--
|
||||
ArgumentCountError
|
||||
substr() expects at least 2 parameters, 1 given
|
||||
|
||||
Warning: array_diff(): at least 2 parameters are required, 1 given in %s
|
@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
Call userland function with incorrect number of arguments
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
function foo($bar) { }
|
||||
foo();
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
function bar($foo, $bar) { }
|
||||
bar(1);
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
function bat(int $foo, string $bar) { }
|
||||
|
||||
try {
|
||||
bat(123);
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
bat("123");
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
--EXPECTF--
|
||||
ArgumentCountError
|
||||
Too few arguments to function foo(), 0 passed in %s and exactly 1 expected
|
||||
ArgumentCountError
|
||||
Too few arguments to function bar(), 1 passed in %s and exactly 2 expected
|
||||
ArgumentCountError
|
||||
Too few arguments to function bat(), 1 passed in %s and exactly 2 expected
|
||||
ArgumentCountError
|
||||
Too few arguments to function bat(), 1 passed in %s and exactly 2 expected
|
@ -0,0 +1,54 @@
|
||||
--TEST--
|
||||
Call userland function with incorrect number of arguments with strict types
|
||||
--FILE--
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
try {
|
||||
function foo($bar) { }
|
||||
foo();
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
function bar($foo, $bar) { }
|
||||
bar(1);
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
function bat(int $foo, string $bar) { }
|
||||
|
||||
try {
|
||||
bat(123);
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
bat("123");
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
bat(123, 456);
|
||||
} catch (\Error $e) {
|
||||
echo get_class($e) . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
}
|
||||
--EXPECTF--
|
||||
ArgumentCountError
|
||||
Too few arguments to function foo(), 0 passed in %s and exactly 1 expected
|
||||
ArgumentCountError
|
||||
Too few arguments to function bar(), 1 passed in %s and exactly 2 expected
|
||||
ArgumentCountError
|
||||
Too few arguments to function bat(), 1 passed in %s and exactly 2 expected
|
||||
TypeError
|
||||
Argument 1 passed to bat() must be of the type integer, string given, called in %s
|
||||
TypeError
|
||||
Argument 2 passed to bat() must be of the type string, integer given, called in %s
|
@ -9,7 +9,7 @@ function f(?callable $p) {}
|
||||
f();
|
||||
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Too few arguments to function f(), 0 passed in %snullable_type_parameters_do_not_have_default_value.php on line %d and exactly 1 expected in %s:%d
|
||||
Fatal error: Uncaught ArgumentCountError: Too few arguments to function f(), 0 passed in %snullable_type_parameters_do_not_have_default_value.php on line %d and exactly 1 expected in %s:%d
|
||||
Stack trace:
|
||||
#%d %s
|
||||
#%d %s
|
||||
|
17
Zend/zend.c
17
Zend/zend.c
@ -1372,6 +1372,23 @@ ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, cons
|
||||
va_end(va);
|
||||
} /* }}} */
|
||||
|
||||
ZEND_API ZEND_COLD void zend_internal_argument_count_error(zend_bool throw_exception, const char *format, ...) /* {{{ */
|
||||
{
|
||||
va_list va;
|
||||
char *message = NULL;
|
||||
|
||||
va_start(va, format);
|
||||
zend_vspprintf(&message, 0, format, va);
|
||||
if (throw_exception) {
|
||||
zend_throw_exception(zend_ce_argument_count_error, message, 0);
|
||||
} else {
|
||||
zend_error(E_WARNING, "%s", message);
|
||||
}
|
||||
efree(message);
|
||||
|
||||
va_end(va);
|
||||
} /* }}} */
|
||||
|
||||
ZEND_API ZEND_COLD void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) /* {{{ */
|
||||
{
|
||||
#if ZEND_DEBUG
|
||||
|
@ -271,6 +271,7 @@ ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRI
|
||||
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||
ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
|
||||
ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||
ZEND_API ZEND_COLD void zend_internal_argument_count_error(zend_bool throw_exception, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||
|
||||
ZEND_COLD void zenderror(const char *error);
|
||||
|
||||
|
@ -157,7 +157,7 @@ ZEND_API ZEND_COLD void zend_wrong_param_count(void) /* {{{ */
|
||||
const char *space;
|
||||
const char *class_name = get_active_class_name(&space);
|
||||
|
||||
zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
|
||||
zend_internal_argument_count_error(ZEND_ARG_USES_STRICT_TYPES(), "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name());
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -208,7 +208,9 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int num_
|
||||
zend_function *active_function = EG(current_execute_data)->func;
|
||||
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
|
||||
|
||||
zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects %s %d parameter%s, %d given",
|
||||
zend_internal_argument_count_error(
|
||||
ZEND_ARG_USES_STRICT_TYPES(),
|
||||
"%s%s%s() expects %s %d parameter%s, %d given",
|
||||
class_name, \
|
||||
class_name[0] ? "::" : "", \
|
||||
ZSTR_VAL(active_function->common.function_name),
|
||||
@ -875,7 +877,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
|
||||
zend_function *active_function = EG(current_execute_data)->func;
|
||||
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
|
||||
zend_bool throw_exception = ZEND_ARG_USES_STRICT_TYPES() || (flags & ZEND_PARSE_PARAMS_THROW);
|
||||
zend_internal_type_error(throw_exception, "%s%s%s() expects %s %d parameter%s, %d given",
|
||||
zend_internal_argument_count_error(throw_exception, "%s%s%s() expects %s %d parameter%s, %d given",
|
||||
class_name,
|
||||
class_name[0] ? "::" : "",
|
||||
ZSTR_VAL(active_function->common.function_name),
|
||||
@ -2909,7 +2911,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||
zend_string *mname, *cname;
|
||||
zend_string *lmname;
|
||||
const char *colon;
|
||||
size_t clen, mlen;
|
||||
size_t clen;
|
||||
HashTable *ftable;
|
||||
int call_via_handler = 0;
|
||||
zend_class_entry *scope;
|
||||
@ -2962,6 +2964,8 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||
colon > Z_STRVAL_P(callable) &&
|
||||
*(colon-1) == ':'
|
||||
) {
|
||||
size_t mlen;
|
||||
|
||||
colon--;
|
||||
clen = colon - Z_STRVAL_P(callable);
|
||||
mlen = Z_STRLEN_P(callable) - clen - 2;
|
||||
@ -2994,7 +2998,6 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
||||
mname = zend_string_init(Z_STRVAL_P(callable) + clen + 2, mlen, 0);
|
||||
} else if (ce_org) {
|
||||
/* Try to fetch find static method of given class. */
|
||||
mlen = Z_STRLEN_P(callable);
|
||||
mname = Z_STR_P(callable);
|
||||
zend_string_addref(mname);
|
||||
ftable = &ce_org->function_table;
|
||||
|
@ -2198,10 +2198,42 @@ static inline uint32_t zend_emit_jump(uint32_t opnum_target) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_is_smart_branch(zend_op *opline) /* {{{ */
|
||||
{
|
||||
switch (opline->opcode) {
|
||||
case ZEND_IS_IDENTICAL:
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
case ZEND_IS_EQUAL:
|
||||
case ZEND_IS_NOT_EQUAL:
|
||||
case ZEND_IS_SMALLER:
|
||||
case ZEND_IS_SMALLER_OR_EQUAL:
|
||||
case ZEND_CASE:
|
||||
case ZEND_ISSET_ISEMPTY_VAR:
|
||||
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
|
||||
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
|
||||
case ZEND_INSTANCEOF:
|
||||
case ZEND_TYPE_CHECK:
|
||||
case ZEND_DEFINED:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static inline uint32_t zend_emit_cond_jump(zend_uchar opcode, znode *cond, uint32_t opnum_target) /* {{{ */
|
||||
{
|
||||
uint32_t opnum = get_next_op_number(CG(active_op_array));
|
||||
zend_op *opline = zend_emit_op(NULL, opcode, cond, NULL);
|
||||
zend_op *opline;
|
||||
|
||||
if ((cond->op_type & (IS_CV|IS_CONST))
|
||||
&& opnum > 0
|
||||
&& zend_is_smart_branch(CG(active_op_array)->opcodes + opnum - 1)) {
|
||||
/* emit extra NOP to avoid incorrect SMART_BRANCH in very rare cases */
|
||||
zend_emit_op(NULL, ZEND_NOP, NULL, NULL);
|
||||
opnum = get_next_op_number(CG(active_op_array));
|
||||
}
|
||||
opline = zend_emit_op(NULL, opcode, cond, NULL);
|
||||
opline->op2.opline_num = opnum_target;
|
||||
return opnum;
|
||||
}
|
||||
|
@ -791,6 +791,7 @@ ZEND_API char *zend_make_compiled_string_description(const char *name);
|
||||
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers);
|
||||
uint32_t zend_get_class_fetch_type(zend_string *name);
|
||||
ZEND_API zend_uchar zend_get_call_op(const zend_op *init_op, zend_function *fbc);
|
||||
ZEND_API int zend_is_smart_branch(zend_op *opline);
|
||||
|
||||
typedef zend_bool (*zend_auto_global_callback)(zend_string *name);
|
||||
typedef struct _zend_auto_global {
|
||||
|
@ -36,6 +36,7 @@ ZEND_API zend_class_entry *zend_ce_error_exception;
|
||||
ZEND_API zend_class_entry *zend_ce_error;
|
||||
ZEND_API zend_class_entry *zend_ce_parse_error;
|
||||
ZEND_API zend_class_entry *zend_ce_type_error;
|
||||
ZEND_API zend_class_entry *zend_ce_argument_count_error;
|
||||
ZEND_API zend_class_entry *zend_ce_arithmetic_error;
|
||||
ZEND_API zend_class_entry *zend_ce_division_by_zero_error;
|
||||
|
||||
@ -709,7 +710,7 @@ ZEND_METHOD(exception, __toString)
|
||||
ZVAL_UNDEF(&trace);
|
||||
}
|
||||
|
||||
if (Z_OBJCE_P(exception) == zend_ce_type_error && strstr(ZSTR_VAL(message), ", called in ")) {
|
||||
if ((Z_OBJCE_P(exception) == zend_ce_type_error || Z_OBJCE_P(exception) == zend_ce_argument_count_error) && strstr(ZSTR_VAL(message), ", called in ")) {
|
||||
zend_string *real_message = zend_strpprintf(0, "%s and defined", ZSTR_VAL(message));
|
||||
zend_string_release(message);
|
||||
message = real_message;
|
||||
@ -859,6 +860,10 @@ void zend_register_default_exception(void) /* {{{ */
|
||||
zend_ce_type_error = zend_register_internal_class_ex(&ce, zend_ce_error);
|
||||
zend_ce_type_error->create_object = zend_default_exception_new;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "ArgumentCountError", NULL);
|
||||
zend_ce_argument_count_error = zend_register_internal_class_ex(&ce, zend_ce_type_error);
|
||||
zend_ce_argument_count_error->create_object = zend_default_exception_new;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "ArithmeticError", NULL);
|
||||
zend_ce_arithmetic_error = zend_register_internal_class_ex(&ce, zend_ce_error);
|
||||
zend_ce_arithmetic_error->create_object = zend_default_exception_new;
|
||||
|
@ -32,6 +32,7 @@ extern ZEND_API zend_class_entry *zend_ce_error_exception;
|
||||
extern ZEND_API zend_class_entry *zend_ce_error;
|
||||
extern ZEND_API zend_class_entry *zend_ce_parse_error;
|
||||
extern ZEND_API zend_class_entry *zend_ce_type_error;
|
||||
extern ZEND_API zend_class_entry *zend_ce_argument_count_error;
|
||||
extern ZEND_API zend_class_entry *zend_ce_arithmetic_error;
|
||||
extern ZEND_API zend_class_entry *zend_ce_division_by_zero_error;
|
||||
|
||||
|
@ -696,6 +696,7 @@ static ZEND_COLD void zend_verify_arg_error(
|
||||
const char *fname, *fsep, *fclass;
|
||||
const char *need_msg, *need_kind, *need_or_null, *given_msg, *given_kind;
|
||||
|
||||
if (value) {
|
||||
zend_verify_type_error_common(
|
||||
zf, arg_info, ce, value,
|
||||
&fname, &fsep, &fclass, &need_msg, &need_kind, &need_or_null, &given_msg, &given_kind);
|
||||
@ -711,6 +712,9 @@ static ZEND_COLD void zend_verify_arg_error(
|
||||
} else {
|
||||
zend_type_error("Argument %d passed to %s%s%s() must %s%s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind);
|
||||
}
|
||||
} else {
|
||||
zend_missing_arg_error(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static int is_null_constant(zend_class_entry *scope, zval *default_value)
|
||||
@ -955,7 +959,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *
|
||||
zend_execute_data *ptr = EX(prev_execute_data);
|
||||
|
||||
if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
|
||||
zend_throw_error(NULL, "Too few arguments to function %s%s%s(), %d passed in %s on line %d and %s %d expected",
|
||||
zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %s%s%s(), %d passed in %s on line %d and %s %d expected",
|
||||
EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "",
|
||||
EX(func)->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(func)->common.function_name),
|
||||
@ -965,7 +969,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *
|
||||
EX(func)->common.required_num_args == EX(func)->common.num_args ? "exactly" : "at least",
|
||||
EX(func)->common.required_num_args);
|
||||
} else {
|
||||
zend_throw_error(NULL, "Too few arguments to function %s%s%s(), %d passed and %s %d expected",
|
||||
zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %s%s%s(), %d passed and %s %d expected",
|
||||
EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "",
|
||||
EX(func)->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(func)->common.function_name),
|
||||
@ -1330,6 +1334,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
|
||||
zend_string_release(old_str);
|
||||
} else {
|
||||
SEPARATE_STRING(str);
|
||||
zend_string_forget_hash_val(Z_STR_P(str));
|
||||
}
|
||||
|
||||
Z_STRVAL_P(str)[offset] = c;
|
||||
|
@ -788,41 +788,29 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
|
||||
|
||||
if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
|
||||
if (UNEXPECTED(!Z_ISREF_P(arg))) {
|
||||
if (fci->no_separation &&
|
||||
!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
|
||||
if (i) {
|
||||
/* hack to clean up the stack */
|
||||
ZEND_CALL_NUM_ARGS(call) = i;
|
||||
zend_vm_stack_free_args(call);
|
||||
}
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
i+1,
|
||||
if (!fci->no_separation) {
|
||||
/* Separation is enabled -- create a ref */
|
||||
ZVAL_NEW_REF(arg, arg);
|
||||
} else if (!ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
|
||||
/* By-value send is not allowed -- emit a warning,
|
||||
* but still perform the call with a by-value send. */
|
||||
zend_error(E_WARNING,
|
||||
"Parameter %d to %s%s%s() expected to be a reference, value given", i+1,
|
||||
func->common.scope ? ZSTR_VAL(func->common.scope->name) : "",
|
||||
func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(func->common.function_name));
|
||||
if (EG(current_execute_data) == &dummy_execute_data) {
|
||||
EG(current_execute_data) = dummy_execute_data.prev_execute_data;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
ZVAL_NEW_REF(arg, arg);
|
||||
}
|
||||
Z_ADDREF_P(arg);
|
||||
} else {
|
||||
if (Z_ISREF_P(arg) &&
|
||||
!(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
/* don't separate references for __call */
|
||||
arg = Z_REFVAL_P(arg);
|
||||
}
|
||||
if (Z_OPT_REFCOUNTED_P(arg)) {
|
||||
Z_ADDREF_P(arg);
|
||||
}
|
||||
}
|
||||
|
||||
param = ZEND_CALL_ARG(call, i+1);
|
||||
ZVAL_COPY_VALUE(param, arg);
|
||||
ZVAL_COPY(param, arg);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
|
||||
|
@ -2444,7 +2444,6 @@ ZEND_API int ZEND_FASTCALL _zend_handle_numeric_str_ex(const char *key, size_t l
|
||||
register const char *tmp = key;
|
||||
|
||||
const char *end = key + length;
|
||||
ZEND_ASSERT(*end == '\0');
|
||||
|
||||
if (*tmp == '-') {
|
||||
tmp++;
|
||||
|
@ -328,13 +328,9 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{
|
||||
buf->st_dev = buf->st_rdev = 0;
|
||||
} else {
|
||||
wchar_t cur_path[MAXPATHLEN+1];
|
||||
DWORD len = sizeof(cur_path);
|
||||
wchar_t *tmp = cur_path;
|
||||
|
||||
while(1) {
|
||||
DWORD r = GetCurrentDirectoryW(len, tmp);
|
||||
if (r < len) {
|
||||
if (tmp[1] == L':') {
|
||||
if (NULL != _wgetcwd(cur_path, sizeof(cur_path)/sizeof(wchar_t))) {
|
||||
if (cur_path[1] == L':') {
|
||||
if (pathw[0] >= L'A' && pathw[0] <= L'Z') {
|
||||
buf->st_dev = buf->st_rdev = pathw[0] - L'A';
|
||||
} else {
|
||||
@ -343,17 +339,8 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{
|
||||
} else {
|
||||
buf->st_dev = buf->st_rdev = -1;
|
||||
}
|
||||
break;
|
||||
} else if (!r) {
|
||||
buf->st_dev = buf->st_rdev = -1;
|
||||
break;
|
||||
} else {
|
||||
len = r+1;
|
||||
tmp = (wchar_t*)malloc(len*sizeof(wchar_t));
|
||||
}
|
||||
}
|
||||
if (tmp != cur_path) {
|
||||
free(tmp);
|
||||
buf->st_dev = buf->st_rdev = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -934,7 +921,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
wchar_t * reparsetarget;
|
||||
BOOL isVolume = FALSE;
|
||||
char *printname = NULL, *substitutename = NULL;
|
||||
int printname_len, substitutename_len;
|
||||
int substitutename_len;
|
||||
int substitutename_off = 0;
|
||||
|
||||
if(++(*ll) > LINK_MAX) {
|
||||
@ -969,7 +956,6 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
|
||||
if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
|
||||
reparsetarget = pbuffer->SymbolicLinkReparseBuffer.ReparseTarget;
|
||||
printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
|
||||
isabsolute = (pbuffer->SymbolicLinkReparseBuffer.Flags == 0) ? 1 : 0;
|
||||
printname = php_win32_ioutil_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR));
|
||||
if (!printname) {
|
||||
@ -992,7 +978,6 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
|
||||
else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
|
||||
isabsolute = 1;
|
||||
reparsetarget = pbuffer->MountPointReparseBuffer.ReparseTarget;
|
||||
printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
|
||||
printname = php_win32_ioutil_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR));
|
||||
if (!printname) {
|
||||
free_alloca(pbuffer, use_heap_large);
|
||||
@ -1406,6 +1391,7 @@ verify:
|
||||
|
||||
tmp = erealloc(state->cwd, state->cwd_length+1);
|
||||
if (tmp == NULL) {
|
||||
CWD_STATE_FREE(&old_state);
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf (stderr, "Out of memory\n");
|
||||
#endif
|
||||
|
@ -4626,23 +4626,15 @@ ZEND_VM_C_LABEL(send_array):
|
||||
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
if (UNEXPECTED(!Z_ISREF_P(arg))) {
|
||||
if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
|
||||
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
/* By-value send is not allowed -- emit a warning,
|
||||
* but still perform the call. */
|
||||
zend_error(E_WARNING,
|
||||
"Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
arg_num,
|
||||
EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name));
|
||||
|
||||
if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
|
||||
OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
|
||||
}
|
||||
if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
|
||||
OBJ_RELEASE(Z_OBJ(EX(call)->This));
|
||||
}
|
||||
EX(call)->func = (zend_function*)&zend_pass_function;
|
||||
Z_OBJ(EX(call)->This) = NULL;
|
||||
ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -4673,25 +4665,12 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, NUM)
|
||||
param = ZEND_CALL_VAR(EX(call), opline->result.var);
|
||||
|
||||
if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
|
||||
ZVAL_DEREF(arg);
|
||||
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
opline->op2.num,
|
||||
EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name));
|
||||
|
||||
if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
|
||||
OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
|
||||
}
|
||||
if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
|
||||
OBJ_RELEASE(Z_OBJ(EX(call)->This));
|
||||
}
|
||||
ZVAL_UNDEF(param);
|
||||
EX(call)->func = (zend_function*)&zend_pass_function;
|
||||
Z_OBJ(EX(call)->This) = NULL;
|
||||
ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
|
||||
|
||||
FREE_OP1();
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
} else {
|
||||
if (Z_ISREF_P(arg) &&
|
||||
!(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
|
@ -1423,23 +1423,15 @@ send_array:
|
||||
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
if (UNEXPECTED(!Z_ISREF_P(arg))) {
|
||||
if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
|
||||
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
/* By-value send is not allowed -- emit a warning,
|
||||
* but still perform the call. */
|
||||
zend_error(E_WARNING,
|
||||
"Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
arg_num,
|
||||
EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name));
|
||||
|
||||
if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
|
||||
OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
|
||||
}
|
||||
if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
|
||||
OBJ_RELEASE(Z_OBJ(EX(call)->This));
|
||||
}
|
||||
EX(call)->func = (zend_function*)&zend_pass_function;
|
||||
Z_OBJ(EX(call)->This) = NULL;
|
||||
ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -15904,25 +15896,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEN
|
||||
param = ZEND_CALL_VAR(EX(call), opline->result.var);
|
||||
|
||||
if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
|
||||
ZVAL_DEREF(arg);
|
||||
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
opline->op2.num,
|
||||
EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name));
|
||||
|
||||
if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
|
||||
OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
|
||||
}
|
||||
if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
|
||||
OBJ_RELEASE(Z_OBJ(EX(call)->This));
|
||||
}
|
||||
ZVAL_UNDEF(param);
|
||||
EX(call)->func = (zend_function*)&zend_pass_function;
|
||||
Z_OBJ(EX(call)->This) = NULL;
|
||||
ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
|
||||
|
||||
zval_ptr_dtor_nogc(free_op1);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
} else {
|
||||
if (Z_ISREF_P(arg) &&
|
||||
!(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
@ -34925,24 +34904,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND
|
||||
param = ZEND_CALL_VAR(EX(call), opline->result.var);
|
||||
|
||||
if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
|
||||
ZVAL_DEREF(arg);
|
||||
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
|
||||
opline->op2.num,
|
||||
EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
|
||||
EX(call)->func->common.scope ? "::" : "",
|
||||
ZSTR_VAL(EX(call)->func->common.function_name));
|
||||
|
||||
if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) {
|
||||
OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype);
|
||||
}
|
||||
if (Z_TYPE(EX(call)->This) == IS_OBJECT) {
|
||||
OBJ_RELEASE(Z_OBJ(EX(call)->This));
|
||||
}
|
||||
ZVAL_UNDEF(param);
|
||||
EX(call)->func = (zend_function*)&zend_pass_function;
|
||||
Z_OBJ(EX(call)->This) = NULL;
|
||||
ZEND_SET_CALL_INFO(EX(call), 0, ZEND_CALL_INFO(EX(call)) & ~ZEND_CALL_RELEASE_THIS);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
} else {
|
||||
if (Z_ISREF_P(arg) &&
|
||||
!(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
|
@ -1827,7 +1827,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
||||
gen_specs($f, $spec, $kind, $prolog."\t", $specs);
|
||||
out($f,$prolog."};\n");
|
||||
out($f,$prolog."zend_opcode_handlers = labels;\n");
|
||||
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
|
||||
out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n");
|
||||
out($f,$prolog."zend_spec_handlers = specs;\n");
|
||||
}
|
||||
break;
|
||||
|
@ -92,7 +92,7 @@ typedef struct bc_struct
|
||||
/* Define the _PROTOTYPE macro if it is needed. */
|
||||
|
||||
#ifndef _PROTOTYPE
|
||||
#ifdef __STDC__
|
||||
#if defined(__STDC__) || defined(PHP_WIN32) && defined(__clang__)
|
||||
#define _PROTOTYPE(func, args) func args
|
||||
#else
|
||||
#define _PROTOTYPE(func, args) func()
|
||||
|
@ -553,7 +553,10 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
|
||||
for (i = 0, j = 0; i < nargs; i++) {
|
||||
/* if this was byref, update the zval */
|
||||
if (f->arg_info[nargs - i - 1].pass_by_reference) {
|
||||
SEPARATE_ZVAL_IF_NOT_REF(&args[nargs - i - 1]);
|
||||
zval *arg = &args[nargs - i - 1];
|
||||
|
||||
ZVAL_DEREF(arg);
|
||||
SEPARATE_ZVAL_NOREF(arg);
|
||||
|
||||
/* if the variant is pointing at the byref_vals, we need to map
|
||||
* the pointee value as a zval; otherwise, the value is pointing
|
||||
@ -561,14 +564,12 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
|
||||
if (V_VT(&vargs[i]) & VT_BYREF) {
|
||||
if (vargs[i].byref == &V_UINT(&byref_vals[j])) {
|
||||
/* copy that value */
|
||||
php_com_zval_from_variant(&args[nargs - i - 1], &byref_vals[j],
|
||||
obj->code_page);
|
||||
php_com_zval_from_variant(arg, &byref_vals[j], obj->code_page);
|
||||
}
|
||||
} else {
|
||||
/* not sure if this can ever happen; the variant we marked as BYREF
|
||||
* is no longer BYREF - copy its value */
|
||||
php_com_zval_from_variant(&args[nargs - i - 1], &vargs[i],
|
||||
obj->code_page);
|
||||
php_com_zval_from_variant(arg, &vargs[i], obj->code_page);
|
||||
}
|
||||
VariantClear(&byref_vals[j]);
|
||||
j++;
|
||||
|
@ -279,7 +279,6 @@ static union _zend_function *com_method_get(zend_object **object_ptr, zend_strin
|
||||
f.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
|
||||
f.function_name = zend_string_copy(name);
|
||||
f.handler = PHP_FN(com_method_handler);
|
||||
zend_set_function_arg_flags((zend_function*)&f);
|
||||
|
||||
fptr = &f;
|
||||
|
||||
@ -305,11 +304,12 @@ static union _zend_function *com_method_get(zend_object **object_ptr, zend_strin
|
||||
for (i = 0; i < bindptr.lpfuncdesc->cParams; i++) {
|
||||
f.arg_info[i].allow_null = 1;
|
||||
if (bindptr.lpfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOUT) {
|
||||
f.arg_info[i].pass_by_reference = 1;
|
||||
f.arg_info[i].pass_by_reference = ZEND_SEND_BY_REF;
|
||||
}
|
||||
}
|
||||
|
||||
f.num_args = bindptr.lpfuncdesc->cParams;
|
||||
zend_set_function_arg_flags((zend_function*)&f);
|
||||
|
||||
ITypeInfo_ReleaseFuncDesc(TI, bindptr.lpfuncdesc);
|
||||
break;
|
||||
|
@ -1901,8 +1901,9 @@ static void create_certinfo(struct curl_certinfo *ci, zval *listcode)
|
||||
int len;
|
||||
char s[64];
|
||||
char *tmp;
|
||||
strncpy(s, slist->data, 64);
|
||||
tmp = memchr(s, ':', 64);
|
||||
strncpy(s, slist->data, sizeof(s));
|
||||
s[sizeof(s)-1] = '\0';
|
||||
tmp = memchr(s, ':', sizeof(s));
|
||||
if(tmp) {
|
||||
*tmp = '\0';
|
||||
len = strlen(s);
|
||||
|
@ -250,6 +250,7 @@ val_type inifile_fetch(inifile *dba, const key_type *key, int skip) {
|
||||
if (skip == -1 && dba->next.key.group && dba->next.key.name && !inifile_key_cmp(&dba->next.key, key)) {
|
||||
/* we got position already from last fetch */
|
||||
php_stream_seek(dba->fp, dba->next.pos, SEEK_SET);
|
||||
ln.key.group = estrdup(dba->next.key.group);
|
||||
} else {
|
||||
/* specific instance or not same key -> restart search */
|
||||
/* the slow way: restart and seacrch */
|
||||
|
71
ext/dba/tests/bug70825.phpt
Normal file
71
ext/dba/tests/bug70825.phpt
Normal file
@ -0,0 +1,71 @@
|
||||
--TEST--
|
||||
Bug #70825 (Cannot fetch multiple values with group in ini file)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('dba')) die('skip dba extension not available');
|
||||
if (!in_array('inifile', dba_handlers())) die('skip inifile handler not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug70825.ini';
|
||||
|
||||
$db = dba_open($filename, 'n', 'inifile');
|
||||
dba_insert('foo', 23, $db);
|
||||
dba_insert('foo', 42, $db);
|
||||
dba_insert('foo', 1337, $db);
|
||||
var_dump(dba_fetch('foo', -1, $db));
|
||||
var_dump(dba_fetch('foo', -1, $db));
|
||||
var_dump(dba_fetch('foo', -1, $db));
|
||||
dba_close($db);
|
||||
unlink($filename);
|
||||
|
||||
$db = dba_open($filename, 'n', 'inifile');
|
||||
dba_insert(['foo', 'bar'], 23, $db);
|
||||
dba_insert(['foo', 'bar'], 42, $db);
|
||||
dba_insert(['foo', 'bar'], 1337, $db);
|
||||
var_dump(dba_fetch(['foo', 'bar'], -1, $db));
|
||||
var_dump(dba_fetch(['foo', 'bar'], -1, $db));
|
||||
var_dump(dba_fetch(['foo', 'bar'], -1, $db));
|
||||
dba_close($db);
|
||||
unlink($filename);
|
||||
|
||||
$db = dba_open($filename, 'n', 'inifile');
|
||||
dba_insert('[foo]bar', 23, $db);
|
||||
dba_insert('[foo]bar', 42, $db);
|
||||
dba_insert('[foo]bar', 1337, $db);
|
||||
var_dump(dba_fetch('[foo]bar', -1, $db));
|
||||
var_dump(dba_fetch('[foo]bar', -1, $db));
|
||||
var_dump(dba_fetch('[foo]bar', -1, $db));
|
||||
dba_close($db);
|
||||
unlink($filename);
|
||||
|
||||
$db = dba_open($filename, 'n', 'inifile');
|
||||
dba_insert('[foo]bar', 23, $db);
|
||||
dba_insert('[foo]bar', 42, $db);
|
||||
dba_insert('[foo]bar', 1337, $db);
|
||||
var_dump(dba_fetch('[foo]bar', 0, $db));
|
||||
var_dump(dba_fetch('[foo]bar', 1, $db));
|
||||
var_dump(dba_fetch('[foo]bar', 2, $db));
|
||||
dba_close($db);
|
||||
unlink($filename);
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
string(2) "23"
|
||||
string(2) "42"
|
||||
string(4) "1337"
|
||||
string(2) "23"
|
||||
string(2) "42"
|
||||
string(4) "1337"
|
||||
string(2) "23"
|
||||
string(2) "42"
|
||||
string(4) "1337"
|
||||
string(2) "23"
|
||||
string(2) "42"
|
||||
string(4) "1337"
|
||||
==DONE==
|
||||
--CLEAN--
|
||||
<?php
|
||||
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug70825.ini';
|
||||
unlink($filename);
|
||||
?>
|
28
ext/dba/tests/bug71514.phpt
Normal file
28
ext/dba/tests/bug71514.phpt
Normal file
@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #71514 (Bad dba_replace condition because of wrong API usage)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('dba')) die('skip dba extension not available');
|
||||
if (!in_array('inifile', dba_handlers())) die('skip inifile handler not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug71514.ini';
|
||||
|
||||
$db = dba_open($filename, 'c', 'inifile');
|
||||
|
||||
dba_insert('foo', 'value1', $db);
|
||||
dba_replace('foo', 'value2', $db);
|
||||
var_dump(dba_fetch('foo', $db));
|
||||
|
||||
dba_close($db);
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
string(6) "value2"
|
||||
==DONE==
|
||||
--CLEAN--
|
||||
<?php
|
||||
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug71514.ini';
|
||||
unlink($filename);
|
||||
?>
|
@ -139,7 +139,10 @@ if ($pid) {
|
||||
$buf = fread($s, 2048);
|
||||
}
|
||||
|
||||
if (!preg_match('/^USER (\w+)\r\n$/', $buf, $m)) {
|
||||
if ($buf == "AUTH TLS\r\n") {
|
||||
fputs($s, "500 not supported.\r\n");
|
||||
return ;
|
||||
} else if (!preg_match('/^USER (\w+)\r\n$/', $buf, $m)) {
|
||||
fputs($s, "500 Syntax error, command unrecognized.\r\n");
|
||||
dump_and_exit($buf);
|
||||
}
|
||||
@ -208,6 +211,10 @@ if ($pid) {
|
||||
$ascii = true;
|
||||
fputs($s, "200 OK\r\n");
|
||||
|
||||
} elseif ($buf === "AUTH SSL\r\n") {
|
||||
$ascii = true;
|
||||
fputs($s, "500 not supported\r\n");
|
||||
|
||||
} elseif ($buf === "TYPE I\r\n") {
|
||||
$ascii = false;
|
||||
fputs($s, "200 OK\r\n");
|
||||
|
23
ext/gd/gd.c
23
ext/gd/gd.c
@ -4071,6 +4071,7 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
|
||||
dest = VCWD_FOPEN(fn_dest, "wb");
|
||||
if (!dest) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to open '%s' for writing", fn_dest);
|
||||
fclose(org);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@ -4079,6 +4080,8 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
|
||||
im_org = gdImageCreateFromGif(org);
|
||||
if (im_org == NULL) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to open '%s' Not a valid GIF file", fn_dest);
|
||||
fclose(org);
|
||||
fclose(dest);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
@ -4089,6 +4092,8 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
|
||||
im_org = gdImageCreateFromJpegEx(org, ignore_warning);
|
||||
if (im_org == NULL) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to open '%s' Not a valid JPEG file", fn_dest);
|
||||
fclose(org);
|
||||
fclose(dest);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
@ -4099,6 +4104,8 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
|
||||
im_org = gdImageCreateFromPng(org);
|
||||
if (im_org == NULL) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to open '%s' Not a valid PNG file", fn_dest);
|
||||
fclose(org);
|
||||
fclose(dest);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
@ -4106,10 +4113,14 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
|
||||
|
||||
default:
|
||||
php_error_docref(NULL, E_WARNING, "Format not supported");
|
||||
fclose(org);
|
||||
fclose(dest);
|
||||
RETURN_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(org);
|
||||
|
||||
org_width = gdImageSX (im_org);
|
||||
org_height = gdImageSY (im_org);
|
||||
|
||||
@ -4140,6 +4151,8 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
|
||||
im_tmp = gdImageCreate (dest_width, dest_height);
|
||||
if (im_tmp == NULL ) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to allocate temporary buffer");
|
||||
fclose(dest);
|
||||
gdImageDestroy(im_org);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@ -4147,23 +4160,29 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
|
||||
|
||||
gdImageDestroy(im_org);
|
||||
|
||||
fclose(org);
|
||||
|
||||
im_dest = gdImageCreate(dest_width, dest_height);
|
||||
if (im_dest == NULL) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to allocate destination buffer");
|
||||
fclose(dest);
|
||||
gdImageDestroy(im_tmp);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
white = gdImageColorAllocate(im_dest, 255, 255, 255);
|
||||
if (white == -1) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to allocate the colors for the destination buffer");
|
||||
fclose(dest);
|
||||
gdImageDestroy(im_tmp);
|
||||
gdImageDestroy(im_dest);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
black = gdImageColorAllocate(im_dest, 0, 0, 0);
|
||||
if (black == -1) {
|
||||
php_error_docref(NULL, E_WARNING, "Unable to allocate the colors for the destination buffer");
|
||||
fclose(dest);
|
||||
gdImageDestroy(im_tmp);
|
||||
gdImageDestroy(im_dest);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2245,9 +2245,11 @@ void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,
|
||||
for (y = 0; (y < h); y++) {
|
||||
for (x = 0; (x < w); x++) {
|
||||
int c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y);
|
||||
if (c != src->transparent) {
|
||||
gdImageSetPixel (dst, dstX + x, dstY + y, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* source is palette based */
|
||||
for (y = 0; (y < h); y++) {
|
||||
@ -2262,26 +2264,6 @@ void gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Destination is palette based */
|
||||
if (src->trueColor) { /* But source is truecolor (Ouch!) */
|
||||
toy = dstY;
|
||||
for (y = srcY; (y < (srcY + h)); y++) {
|
||||
tox = dstX;
|
||||
for (x = srcX; x < (srcX + w); x++) {
|
||||
int nc;
|
||||
c = gdImageGetPixel (src, x, y);
|
||||
|
||||
/* Get best match possible. */
|
||||
nc = gdImageColorResolveAlpha(dst, gdTrueColorGetRed(c), gdTrueColorGetGreen(c), gdTrueColorGetBlue(c), gdTrueColorGetAlpha(c));
|
||||
|
||||
gdImageSetPixel(dst, tox, toy, nc);
|
||||
tox++;
|
||||
}
|
||||
toy++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Palette based to palette based */
|
||||
for (i = 0; i < gdMaxColors; i++) {
|
||||
colorMap[i] = (-1);
|
||||
|
35
ext/gd/tests/bug66005.phpt
Normal file
35
ext/gd/tests/bug66005.phpt
Normal file
@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Bug #66005 (imagecopy does not support 1bit transparency on truecolor images)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip gd extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$dest = imagecreatetruecolor(150, 50);
|
||||
$transparent = imagecolorallocatealpha($dest, 255, 255, 255, 127);
|
||||
imagealphablending($dest, false);
|
||||
imagefill($dest, 1, 1, $transparent);
|
||||
imagesavealpha($dest, true);
|
||||
|
||||
// Palette image with transparent color
|
||||
$png_palette = imagecreatefromstring(base64_decode('iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAgMAAABjUWAiAAAACVBMVEUAAAD/AAD///9nGWQeAAAAAXRSTlMAQObYZgAAAEFJREFUKM9jYBimIASZIxoagOAwhoaGInisQJ4DksJQJKWoPCAnNIQYHsgChBX4eMSbiddlqH5A9R+q39HCZWgDAFxFGyOrmguhAAAAAElFTkSuQmCCPHP'));
|
||||
|
||||
// 24 bit with transparent color
|
||||
$png_24 = imagecreatefromstring(base64_decode('iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAABnRSTlMAAAAAAABupgeRAAAAVklEQVRYw+3UQQqAMBAEwf3/p9eTBxEPiWAmWMU8oGFJqgAAuOpzWTX3xQUti+uRJTZ9V5aY1bOTFZLV7yZr9zt6ibv/qPXfrMpsGipbIy7oqQ8AYJED1plDy5PCu2sAAAAASUVORK5CYII='));
|
||||
|
||||
// 32 bit with full alpha channel
|
||||
$png_full = imagecreatefromstring(base64_decode('iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAXklEQVRo3u3XMQrAIBBFwb3/pU2VwiJNIvjdzMD2PlBwqwAAAGajatxz9OGf5viA+KA3EXExXyKiYlqErIiIiBGSFLIyYmuMkO7Xy2MX4ovS/ONoH7Eh/m1nBwCASBe3VYeVaAy8PwAAAABJRU5ErkJggg=='));
|
||||
|
||||
imagecopy($dest, $png_palette, 0, 0, 0, 0, 50, 50);
|
||||
imagecopy($dest, $png_24, 50, 0, 0, 0, 50, 50);
|
||||
imagecopy($dest, $png_full, 100, 0, 0, 0, 50, 50);
|
||||
|
||||
ob_start();
|
||||
imagegd($dest);
|
||||
echo md5(ob_get_clean()), PHP_EOL;
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
9b36049de01006b367efd433f1689043
|
||||
==DONE==
|
29
ext/gd/tests/bug72913.phpt
Normal file
29
ext/gd/tests/bug72913.phpt
Normal file
@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Bug #72913 (imagecopy() loses single-color transparency on palette images)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip gd extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$base64 = 'iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAABnRSTlMAAAAAAABu'
|
||||
. 'pgeRAAAAVklEQVRYw+3UQQqAMBAEwf3/p9eTBxEPiWAmWMU8oGFJqgAAuOpzWTX3'
|
||||
. 'xQUti+uRJTZ9V5aY1bOTFZLV7yZr9zt6ibv/qPXfrMpsGipbIy7oqQ8AYJED1plD'
|
||||
. 'y5PCu2sAAAAASUVORK5CYII=';
|
||||
$src = imagecreatefromstring(base64_decode($base64));
|
||||
|
||||
$dst = imagecreate(50, 50);
|
||||
$transparent = imagecolorallocatealpha($dst, 255, 255, 255, 127);
|
||||
imagealphablending($dst, false);
|
||||
imagesavealpha($dst, true);
|
||||
|
||||
imagecopy($dst, $src, 0,0, 0,0, 50,50);
|
||||
|
||||
ob_start();
|
||||
imagegd($dst);
|
||||
echo md5(ob_get_clean()), PHP_EOL;
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
f03c27f20710e21debd7090c660f1a1e
|
||||
==DONE==
|
@ -720,7 +720,6 @@ PHP_ICONV_API php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len,
|
||||
|
||||
default:
|
||||
/* other error */
|
||||
retval = PHP_ICONV_ERR_UNKNOWN;
|
||||
zend_string_free(out_buf);
|
||||
return PHP_ICONV_ERR_UNKNOWN;
|
||||
}
|
||||
@ -858,7 +857,7 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval,
|
||||
}
|
||||
|
||||
|
||||
if ((size_t)offset >= total_len) {
|
||||
if ((size_t)offset > total_len) {
|
||||
return PHP_ICONV_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2108,7 +2107,7 @@ PHP_FUNCTION(iconv_substr)
|
||||
err = _php_iconv_substr(&retval, ZSTR_VAL(str), ZSTR_LEN(str), offset, length, charset);
|
||||
_php_iconv_show_error(err, GENERIC_SUPERSET_NAME, charset);
|
||||
|
||||
if (err == PHP_ICONV_ERR_SUCCESS && ZSTR_LEN(str) > 0 && retval.s != NULL) {
|
||||
if (err == PHP_ICONV_ERR_SUCCESS && ZSTR_LEN(str) >= 0 && retval.s != NULL) {
|
||||
RETURN_NEW_STR(retval.s);
|
||||
}
|
||||
smart_str_free(&retval);
|
||||
|
14
ext/iconv/tests/bug72320.phpt
Normal file
14
ext/iconv/tests/bug72320.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #72320 (iconv_substr returns false for empty strings)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('iconv')) die('skip ext/iconv required');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(iconv_substr('', 0, 10, 'UTF-8'));
|
||||
var_dump(iconv_substr('foo', 3, 10, 'UTF-8'));
|
||||
?>
|
||||
--EXPECT--
|
||||
string(0) ""
|
||||
string(0) ""
|
@ -3962,7 +3962,7 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *
|
||||
bt_len++;
|
||||
offset = 0;
|
||||
addr = NULL;
|
||||
rfc822_parse_adrlist(&addr, tempMailTo, NULL);
|
||||
rfc822_parse_adrlist(&addr, tempMailTo, "NO HOST");
|
||||
while (addr) {
|
||||
if (addr->host == NULL || strcmp(addr->host, ERRHOST) == 0) {
|
||||
PHP_IMAP_BAD_DEST;
|
||||
@ -3991,7 +3991,7 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *
|
||||
bt_len++;
|
||||
offset = 0;
|
||||
addr = NULL;
|
||||
rfc822_parse_adrlist(&addr, tempMailTo, NULL);
|
||||
rfc822_parse_adrlist(&addr, tempMailTo, "NO HOST");
|
||||
while (addr) {
|
||||
if (addr->host == NULL || strcmp(addr->host, ERRHOST) == 0) {
|
||||
PHP_IMAP_BAD_DEST;
|
||||
@ -4017,7 +4017,7 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *
|
||||
bt_len++;
|
||||
offset = 0;
|
||||
addr = NULL;
|
||||
rfc822_parse_adrlist(&addr, tempMailTo, NULL);
|
||||
rfc822_parse_adrlist(&addr, tempMailTo, "NO HOST");
|
||||
while (addr) {
|
||||
if (addr->host == NULL || strcmp(addr->host, ERRHOST) == 0) {
|
||||
PHP_IMAP_BAD_DEST;
|
||||
|
@ -223,7 +223,7 @@ zend_long grapheme_ascii_check(const unsigned char *day, size_t len)
|
||||
{
|
||||
int ret_len = len;
|
||||
while ( len-- ) {
|
||||
if ( *day++ > 0x7f )
|
||||
if ( *day++ > 0x7f || (*day == '\n' && *(day - 1) == '\r') )
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -50,11 +50,10 @@ static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *ret
|
||||
zend_hash_destroy(args_copy);
|
||||
efree(args_copy);
|
||||
|
||||
if (formatted && U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
|
||||
if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
|
||||
if (formatted) {
|
||||
efree(formatted);
|
||||
}
|
||||
|
||||
if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
INTL_METHOD_RETVAL_UTF8(mfo, formatted, formatted_len, 1);
|
||||
|
19
ext/intl/tests/bug65732.phpt
Normal file
19
ext/intl/tests/bug65732.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #65732 (grapheme_*() is not Unicode compliant on CR LF sequence)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('intl')) die('skip intl extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(grapheme_strlen("\r\n"));
|
||||
var_dump(grapheme_substr(implode("\r\n", ['abc', 'def', 'ghi']), 5));
|
||||
var_dump(grapheme_strrpos("a\r\nb", 'b'));
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
int(1)
|
||||
string(7) "ef
|
||||
ghi"
|
||||
int(2)
|
||||
==DONE==
|
@ -66,7 +66,7 @@ foreach($args as $arg) {
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
TypeError: NumberFormatter::__construct() expects at least 2 parameters, 0 given in %s on line %d
|
||||
ArgumentCountError: NumberFormatter::__construct() expects at least 2 parameters, 0 given in %s on line %d
|
||||
'numfmt_create: unable to parse input parameters: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
|
||||
Warning: numfmt_create() expects at least 2 parameters, 0 given in %s on line %d
|
||||
|
@ -79,7 +79,7 @@ foreach($args as $arg) {
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
TypeError: MessageFormatter::__construct() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
ArgumentCountError: MessageFormatter::__construct() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
'msgfmt_create: unable to parse input parameters: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
|
||||
Warning: msgfmt_create() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
@ -88,7 +88,7 @@ Warning: msgfmt_create() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
Warning: MessageFormatter::create() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
'msgfmt_create: unable to parse input parameters: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
|
||||
TypeError: MessageFormatter::__construct() expects exactly 2 parameters, 1 given in %s on line %d
|
||||
ArgumentCountError: MessageFormatter::__construct() expects exactly 2 parameters, 1 given in %s on line %d
|
||||
'msgfmt_create: unable to parse input parameters: U_ILLEGAL_ARGUMENT_ERROR'
|
||||
|
||||
Warning: msgfmt_create() expects exactly 2 parameters, 1 given in %s on line %d
|
||||
|
@ -566,8 +566,8 @@ IC_METHOD(getFC_NFKC_Closure) {
|
||||
|
||||
error = U_ZERO_ERROR;
|
||||
u8str = intl_convert_utf16_to_utf8(closure, closure_len, &error);
|
||||
efree(closure);
|
||||
INTL_CHECK_STATUS(error, "Failed converting output to UTF8");
|
||||
efree(closure);
|
||||
RETVAL_NEW_STR(u8str);
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -186,9 +186,7 @@ static PHP_MINFO_FUNCTION(json)
|
||||
|
||||
PHP_JSON_API int php_json_encode(smart_str *buf, zval *val, int options) /* {{{ */
|
||||
{
|
||||
php_json_encode_zval(buf, val, options);
|
||||
|
||||
return JSON_G(error_code) > 0 ? FAILURE : SUCCESS;
|
||||
return php_json_encode_zval(buf, val, options);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
static const char digits[] = "0123456789abcdef";
|
||||
|
||||
static void php_json_escape_string(smart_str *buf, char *s, size_t len, int options);
|
||||
static int php_json_escape_string(smart_str *buf, char *s, size_t len, int options);
|
||||
|
||||
static int php_json_determine_array_type(zval *val) /* {{{ */
|
||||
{
|
||||
@ -108,7 +108,21 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */
|
||||
#define PHP_JSON_HASH_APPLY_PROTECTION_INC(_tmp_ht) \
|
||||
do { \
|
||||
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(_tmp_ht)) { \
|
||||
ZEND_HASH_INC_APPLY_COUNT(_tmp_ht); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PHP_JSON_HASH_APPLY_PROTECTION_DEC(_tmp_ht) \
|
||||
do { \
|
||||
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(_tmp_ht)) { \
|
||||
ZEND_HASH_DEC_APPLY_COUNT(_tmp_ht); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */
|
||||
{
|
||||
int i, r, need_comma = 0;
|
||||
HashTable *myht;
|
||||
@ -124,7 +138,7 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||
if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) {
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
|
||||
smart_str_appendl(buf, "null", 4);
|
||||
return;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (r == PHP_JSON_OUTPUT_ARRAY) {
|
||||
@ -146,9 +160,7 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) {
|
||||
ZVAL_DEREF(data);
|
||||
tmp_ht = HASH_OF(data);
|
||||
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
|
||||
ZEND_HASH_INC_APPLY_COUNT(tmp_ht);
|
||||
}
|
||||
PHP_JSON_HASH_APPLY_PROTECTION_INC(tmp_ht);
|
||||
|
||||
if (r == PHP_JSON_OUTPUT_ARRAY) {
|
||||
if (need_comma) {
|
||||
@ -159,14 +171,11 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||
|
||||
php_json_pretty_print_char(buf, options, '\n');
|
||||
php_json_pretty_print_indent(buf, options);
|
||||
php_json_encode(buf, data, options);
|
||||
} else if (r == PHP_JSON_OUTPUT_OBJECT) {
|
||||
if (key) {
|
||||
if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) {
|
||||
/* Skip protected and private members. */
|
||||
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
|
||||
ZEND_HASH_DEC_APPLY_COUNT(tmp_ht);
|
||||
}
|
||||
PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -180,11 +189,6 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||
php_json_pretty_print_indent(buf, options);
|
||||
|
||||
php_json_escape_string(buf, ZSTR_VAL(key), ZSTR_LEN(key), options & ~PHP_JSON_NUMERIC_CHECK);
|
||||
smart_str_appendc(buf, ':');
|
||||
|
||||
php_json_pretty_print_char(buf, options, ' ');
|
||||
|
||||
php_json_encode(buf, data, options);
|
||||
} else {
|
||||
if (need_comma) {
|
||||
smart_str_appendc(buf, ',');
|
||||
@ -198,22 +202,26 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||
smart_str_appendc(buf, '"');
|
||||
smart_str_append_long(buf, (zend_long) index);
|
||||
smart_str_appendc(buf, '"');
|
||||
}
|
||||
|
||||
smart_str_appendc(buf, ':');
|
||||
|
||||
php_json_pretty_print_char(buf, options, ' ');
|
||||
|
||||
php_json_encode(buf, data, options);
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_ht && ZEND_HASH_APPLY_PROTECTION(tmp_ht)) {
|
||||
ZEND_HASH_DEC_APPLY_COUNT(tmp_ht);
|
||||
if (php_json_encode(buf, data, options) == FAILURE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
|
||||
PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
PHP_JSON_HASH_APPLY_PROTECTION_DEC(tmp_ht);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
|
||||
if (JSON_G(encoder_depth) > JSON_G(encode_max_depth)) {
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_DEPTH;
|
||||
if (!(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
--JSON_G(encoder_depth);
|
||||
|
||||
@ -228,6 +236,8 @@ static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{
|
||||
} else {
|
||||
smart_str_appendc(buf, '}');
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -268,7 +278,7 @@ static int php_json_utf8_to_utf16(unsigned short *utf16, char utf8[], size_t len
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void php_json_escape_string(smart_str *buf, char *s, size_t len, int options) /* {{{ */
|
||||
static int php_json_escape_string(smart_str *buf, char *s, size_t len, int options) /* {{{ */
|
||||
{
|
||||
int status;
|
||||
unsigned int us;
|
||||
@ -276,7 +286,7 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti
|
||||
|
||||
if (len == 0) {
|
||||
smart_str_appendl(buf, "\"\"", 2);
|
||||
return;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (options & PHP_JSON_NUMERIC_CHECK) {
|
||||
@ -287,10 +297,10 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti
|
||||
if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
|
||||
if (type == IS_LONG) {
|
||||
smart_str_append_long(buf, p);
|
||||
return;
|
||||
return SUCCESS;
|
||||
} else if (type == IS_DOUBLE && php_json_is_valid_double(d)) {
|
||||
php_json_encode_double(buf, d, options);
|
||||
return;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,8 +310,10 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti
|
||||
/* validate UTF-8 string first */
|
||||
if (php_json_utf8_to_utf16(NULL, s, len) < 0) {
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
|
||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||
smart_str_appendl(buf, "null", 4);
|
||||
return;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,8 +334,10 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti
|
||||
ZSTR_LEN(buf->s) = checkpoint;
|
||||
}
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_UTF8;
|
||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||
smart_str_appendl(buf, "null", 4);
|
||||
return;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
/* Escape U+2028/U+2029 line terminators, UNLESS both
|
||||
JSON_UNESCAPED_UNICODE and
|
||||
@ -442,10 +456,12 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti
|
||||
} while (pos < len);
|
||||
|
||||
smart_str_appendc(buf, '"');
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void php_json_encode_serializable_object(smart_str *buf, zval *val, int options) /* {{{ */
|
||||
static int php_json_encode_serializable_object(smart_str *buf, zval *val, int options) /* {{{ */
|
||||
{
|
||||
zend_class_entry *ce = Z_OBJCE_P(val);
|
||||
zval retval, fname;
|
||||
@ -460,8 +476,10 @@ static void php_json_encode_serializable_object(smart_str *buf, zval *val, int o
|
||||
|
||||
if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) {
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
|
||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||
smart_str_appendl(buf, "null", 4);
|
||||
return;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@ -470,9 +488,12 @@ static void php_json_encode_serializable_object(smart_str *buf, zval *val, int o
|
||||
origin_error_code = JSON_G(error_code);
|
||||
if (FAILURE == call_user_function_ex(EG(function_table), val, &fname, &retval, 0, NULL, 1, NULL) || Z_TYPE(retval) == IS_UNDEF) {
|
||||
zend_throw_exception_ex(NULL, 0, "Failed calling %s::jsonSerialize()", ZSTR_VAL(ce->name));
|
||||
smart_str_appendl(buf, "null", sizeof("null") - 1);
|
||||
zval_ptr_dtor(&fname);
|
||||
return;
|
||||
|
||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||
smart_str_appendl(buf, "null", 4);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
JSON_G(error_code) = origin_error_code;
|
||||
@ -480,8 +501,11 @@ static void php_json_encode_serializable_object(smart_str *buf, zval *val, int o
|
||||
/* Error already raised */
|
||||
zval_ptr_dtor(&retval);
|
||||
zval_ptr_dtor(&fname);
|
||||
smart_str_appendl(buf, "null", sizeof("null") - 1);
|
||||
return;
|
||||
|
||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||
smart_str_appendl(buf, "null", 4);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if ((Z_TYPE(retval) == IS_OBJECT) &&
|
||||
@ -495,10 +519,12 @@ static void php_json_encode_serializable_object(smart_str *buf, zval *val, int o
|
||||
|
||||
zval_ptr_dtor(&retval);
|
||||
zval_ptr_dtor(&fname);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void php_json_encode_zval(smart_str *buf, zval *val, int options) /* {{{ */
|
||||
int php_json_encode_zval(smart_str *buf, zval *val, int options) /* {{{ */
|
||||
{
|
||||
again:
|
||||
switch (Z_TYPE_P(val))
|
||||
@ -528,18 +554,15 @@ again:
|
||||
break;
|
||||
|
||||
case IS_STRING:
|
||||
php_json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options);
|
||||
break;
|
||||
return php_json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val), options);
|
||||
|
||||
case IS_OBJECT:
|
||||
if (instanceof_function(Z_OBJCE_P(val), php_json_serializable_ce)) {
|
||||
php_json_encode_serializable_object(buf, val, options);
|
||||
break;
|
||||
return php_json_encode_serializable_object(buf, val, options);
|
||||
}
|
||||
/* fallthrough -- Non-serializable object */
|
||||
case IS_ARRAY:
|
||||
php_json_encode_array(buf, val, options);
|
||||
break;
|
||||
return php_json_encode_array(buf, val, options);
|
||||
|
||||
case IS_REFERENCE:
|
||||
val = Z_REFVAL_P(val);
|
||||
@ -547,11 +570,13 @@ again:
|
||||
|
||||
default:
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_UNSUPPORTED_TYPE;
|
||||
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
|
||||
smart_str_appendl(buf, "null", 4);
|
||||
break;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return;
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef PHP_JSON_H
|
||||
#define PHP_JSON_H
|
||||
|
||||
#define PHP_JSON_VERSION "1.4.0"
|
||||
#define PHP_JSON_VERSION "1.5.0"
|
||||
#include "zend_smart_str_public.h"
|
||||
|
||||
extern zend_module_entry json_module_entry;
|
||||
|
@ -22,6 +22,6 @@
|
||||
#include "php.h"
|
||||
#include "zend_smart_str.h"
|
||||
|
||||
void php_json_encode_zval(smart_str *buf, zval *val, int options);
|
||||
int php_json_encode_zval(smart_str *buf, zval *val, int options);
|
||||
|
||||
#endif /* PHP_JSON_ENCODER_H */
|
||||
|
30
ext/json/tests/bug68992.phpt
Normal file
30
ext/json/tests/bug68992.phpt
Normal file
@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Bug #68992 (json_encode stacks exceptions thrown by JsonSerializable classes)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('json')) die('skip');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyClass implements JsonSerializable {
|
||||
public function jsonSerialize() {
|
||||
throw new Exception('Not implemented!');
|
||||
}
|
||||
}
|
||||
$classes = [];
|
||||
for($i = 0; $i < 5; $i++) {
|
||||
$classes[] = new MyClass();
|
||||
}
|
||||
|
||||
try {
|
||||
json_encode($classes);
|
||||
} catch(Exception $e) {
|
||||
do {
|
||||
printf("%s (%d) [%s]\n", $e->getMessage(), $e->getCode(), get_class($e));
|
||||
} while ($e = $e->getPrevious());
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Failed calling MyClass::jsonSerialize() (0) [Exception]
|
||||
Not implemented! (0) [Exception]
|
@ -419,6 +419,7 @@ PHP_FUNCTION(ldap_connect)
|
||||
int urllen = hostlen + sizeof( "ldap://:65535" );
|
||||
|
||||
if (port <= 0 || port > 65535) {
|
||||
efree(ld);
|
||||
php_error_docref(NULL, E_WARNING, "invalid port number: " ZEND_LONG_FMT, port);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
@ -2934,6 +2934,13 @@ PHP_FUNCTION(mb_substr)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (from > INT_MAX) {
|
||||
from = INT_MAX;
|
||||
}
|
||||
if (len > INT_MAX) {
|
||||
len = INT_MAX;
|
||||
}
|
||||
|
||||
ret = mbfl_substr(&string, &result, from, len);
|
||||
if (NULL == ret) {
|
||||
RETURN_FALSE;
|
||||
|
23
ext/mbstring/tests/bug66797.phpt
Normal file
23
ext/mbstring/tests/bug66797.phpt
Normal file
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #66797 (mb_substr only takes 32-bit signed integer)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (PHP_INT_SIZE != 8) die('skip this test is for 64bit platforms only');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(
|
||||
mb_substr('bar', 0, 0x7fffffff),
|
||||
mb_substr('bar', 0, 0x80000000),
|
||||
mb_substr('bar', 0xffffffff, 1),
|
||||
mb_substr('bar', 0x100000000, 1)
|
||||
);
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECTF--
|
||||
string(3) "bar"
|
||||
string(3) "bar"
|
||||
string(0) ""
|
||||
string(0) ""
|
||||
==DONE==
|
@ -91,6 +91,15 @@ static void strip_leading_nops(zend_op_array *op_array, zend_basic_block *b)
|
||||
zend_op *opcodes = op_array->opcodes;
|
||||
|
||||
while (b->len > 0 && opcodes[b->start].opcode == ZEND_NOP) {
|
||||
/* check if NOP breaks incorrect smart branch */
|
||||
if (b->len == 2
|
||||
&& (op_array->opcodes[b->start + 1].opcode == ZEND_JMPZ
|
||||
|| op_array->opcodes[b->start + 1].opcode == ZEND_JMPNZ)
|
||||
&& (op_array->opcodes[b->start + 1].op1_type & (IS_CV|IS_CONST))
|
||||
&& b->start > 0
|
||||
&& zend_is_smart_branch(op_array->opcodes + b->start - 1)) {
|
||||
break;
|
||||
}
|
||||
b->start++;
|
||||
b->len--;
|
||||
}
|
||||
@ -114,6 +123,14 @@ static void strip_nops(zend_op_array *op_array, zend_basic_block *b)
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (i + 1 < b->start + b->len
|
||||
&& (op_array->opcodes[i+1].opcode == ZEND_JMPZ
|
||||
|| op_array->opcodes[i+1].opcode == ZEND_JMPNZ)
|
||||
&& op_array->opcodes[i+1].op1_type & (IS_CV|IS_CONST)
|
||||
&& zend_is_smart_branch(op_array->opcodes + j - 1)) {
|
||||
/* don't remove NOP, that splits incorrect smart branch */
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
b->len = j - b->start;
|
||||
|
@ -149,20 +149,7 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
|
||||
i + 1 < op_array->last &&
|
||||
(op_array->opcodes[i+1].opcode == ZEND_JMPZ ||
|
||||
op_array->opcodes[i+1].opcode == ZEND_JMPNZ) &&
|
||||
(op_array->opcodes[i-1].opcode == ZEND_IS_IDENTICAL ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_IS_NOT_IDENTICAL ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_IS_EQUAL ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_IS_NOT_EQUAL ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_IS_SMALLER ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_IS_SMALLER_OR_EQUAL ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_CASE ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_ISSET_ISEMPTY_VAR ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_ISSET_ISEMPTY_STATIC_PROP ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_ISSET_ISEMPTY_PROP_OBJ ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_INSTANCEOF ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_TYPE_CHECK ||
|
||||
op_array->opcodes[i-1].opcode == ZEND_DEFINED))) {
|
||||
zend_is_smart_branch(op_array->opcodes + i - 1))) {
|
||||
if (i != target) {
|
||||
op_array->opcodes[target] = op_array->opcodes[i];
|
||||
ssa->ops[target] = ssa->ops[i];
|
||||
|
@ -24,11 +24,12 @@
|
||||
#include "zend_optimizer.h"
|
||||
#include "zend_optimizer_internal.h"
|
||||
|
||||
static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend_basic_block *b) /* {{{ */
|
||||
static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_block *b) /* {{{ */
|
||||
{
|
||||
zend_uchar opcode;
|
||||
zend_basic_block *b0;
|
||||
int successor_0, successor_1;
|
||||
zend_basic_block *blocks = cfg->blocks;
|
||||
|
||||
while (1) {
|
||||
b->flags |= ZEND_BB_REACHABLE;
|
||||
@ -39,7 +40,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
|
||||
b0 = blocks + successor_0;
|
||||
b0->flags |= ZEND_BB_TARGET;
|
||||
if (!(b0->flags & ZEND_BB_REACHABLE)) {
|
||||
zend_mark_reachable(opcodes, blocks, b0);
|
||||
zend_mark_reachable(opcodes, cfg, b0);
|
||||
}
|
||||
|
||||
ZEND_ASSERT(b->len != 0);
|
||||
@ -58,8 +59,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
|
||||
} else {
|
||||
b->flags |= ZEND_BB_FOLLOW;
|
||||
|
||||
//TODO: support for stackless CFG???
|
||||
if (0/*stackless*/) {
|
||||
if (cfg->split_at_calls) {
|
||||
if (opcode == ZEND_INCLUDE_OR_EVAL ||
|
||||
opcode == ZEND_GENERATOR_CREATE ||
|
||||
opcode == ZEND_YIELD ||
|
||||
@ -70,6 +70,12 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
|
||||
b->flags |= ZEND_BB_ENTRY;
|
||||
}
|
||||
}
|
||||
if (cfg->split_at_recv) {
|
||||
if (opcode == ZEND_RECV ||
|
||||
opcode == ZEND_RECV_INIT) {
|
||||
b->flags |= ZEND_BB_RECV_ENTRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
b = blocks + successor_0;
|
||||
@ -89,7 +95,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
zend_basic_block *blocks = cfg->blocks;
|
||||
|
||||
blocks[start].flags = ZEND_BB_START;
|
||||
zend_mark_reachable(op_array->opcodes, blocks, blocks + start);
|
||||
zend_mark_reachable(op_array->opcodes, cfg, blocks + start);
|
||||
|
||||
if (op_array->last_live_range || op_array->last_try_catch) {
|
||||
zend_basic_block *b;
|
||||
@ -109,6 +115,15 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
b = blocks + block_map[live_range->start];
|
||||
if (b->flags & ZEND_BB_REACHABLE) {
|
||||
while (b->len > 0 && op_array->opcodes[b->start].opcode == ZEND_NOP) {
|
||||
/* check if NOP breaks incorrect smart branch */
|
||||
if (b->len == 2
|
||||
&& (op_array->opcodes[b->start + 1].opcode == ZEND_JMPZ
|
||||
|| op_array->opcodes[b->start + 1].opcode == ZEND_JMPNZ)
|
||||
&& (op_array->opcodes[b->start + 1].op1_type & (IS_CV|IS_CONST))
|
||||
&& b->start > 0
|
||||
&& zend_is_smart_branch(op_array->opcodes + b->start - 1)) {
|
||||
break;
|
||||
}
|
||||
b->start++;
|
||||
b->len--;
|
||||
}
|
||||
@ -123,7 +138,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
if (!(b->flags & ZEND_BB_REACHABLE)) {
|
||||
if (cfg->split_at_live_ranges) {
|
||||
changed = 1;
|
||||
zend_mark_reachable(op_array->opcodes, blocks, b);
|
||||
zend_mark_reachable(op_array->opcodes, cfg, b);
|
||||
} else {
|
||||
ZEND_ASSERT(!(b->flags & ZEND_BB_UNREACHABLE_FREE));
|
||||
ZEND_ASSERT(b->start == live_range->end);
|
||||
@ -161,7 +176,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
if (b->flags & ZEND_BB_REACHABLE) {
|
||||
op_array->try_catch_array[j].try_op = op_array->try_catch_array[j].catch_op;
|
||||
changed = 1;
|
||||
zend_mark_reachable(op_array->opcodes, blocks, blocks + block_map[op_array->try_catch_array[j].try_op]);
|
||||
zend_mark_reachable(op_array->opcodes, cfg, blocks + block_map[op_array->try_catch_array[j].try_op]);
|
||||
break;
|
||||
}
|
||||
b++;
|
||||
@ -178,7 +193,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
b->flags |= ZEND_BB_CATCH;
|
||||
if (!(b->flags & ZEND_BB_REACHABLE)) {
|
||||
changed = 1;
|
||||
zend_mark_reachable(op_array->opcodes, blocks, b);
|
||||
zend_mark_reachable(op_array->opcodes, cfg, b);
|
||||
}
|
||||
}
|
||||
if (op_array->try_catch_array[j].finally_op) {
|
||||
@ -186,7 +201,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
b->flags |= ZEND_BB_FINALLY;
|
||||
if (!(b->flags & ZEND_BB_REACHABLE)) {
|
||||
changed = 1;
|
||||
zend_mark_reachable(op_array->opcodes, blocks, b);
|
||||
zend_mark_reachable(op_array->opcodes, cfg, b);
|
||||
}
|
||||
}
|
||||
if (op_array->try_catch_array[j].finally_end) {
|
||||
@ -194,7 +209,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
|
||||
b->flags |= ZEND_BB_FINALLY_END;
|
||||
if (!(b->flags & ZEND_BB_REACHABLE)) {
|
||||
changed = 1;
|
||||
zend_mark_reachable(op_array->opcodes, blocks, b);
|
||||
zend_mark_reachable(op_array->opcodes, cfg, b);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -273,6 +288,9 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
|
||||
zend_bool extra_entry_block = 0;
|
||||
|
||||
cfg->split_at_live_ranges = (build_flags & ZEND_CFG_SPLIT_AT_LIVE_RANGES) != 0;
|
||||
cfg->split_at_calls = (build_flags & ZEND_CFG_STACKLESS) != 0;
|
||||
cfg->split_at_recv = (build_flags & ZEND_CFG_RECV_ENTRY) != 0 && (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0;
|
||||
|
||||
cfg->map = block_map = zend_arena_calloc(arena, op_array->last, sizeof(uint32_t));
|
||||
if (!block_map) {
|
||||
return FAILURE;
|
||||
@ -283,6 +301,12 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
|
||||
for (i = 0; i < op_array->last; i++) {
|
||||
zend_op *opline = op_array->opcodes + i;
|
||||
switch(opline->opcode) {
|
||||
case ZEND_RECV:
|
||||
case ZEND_RECV_INIT:
|
||||
if (build_flags & ZEND_CFG_RECV_ENTRY) {
|
||||
BB_START(i + 1);
|
||||
}
|
||||
break;
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
|
@ -32,13 +32,14 @@
|
||||
#define ZEND_BB_GEN_VAR (1<<9) /* start of live range */
|
||||
#define ZEND_BB_KILL_VAR (1<<10) /* end of live range */
|
||||
#define ZEND_BB_UNREACHABLE_FREE (1<<11) /* unreachable loop free */
|
||||
#define ZEND_BB_RECV_ENTRY (1<<12) /* RECV entry */
|
||||
|
||||
#define ZEND_BB_LOOP_HEADER (1<<16)
|
||||
#define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
|
||||
|
||||
#define ZEND_BB_REACHABLE (1<<31)
|
||||
|
||||
#define ZEND_BB_PROTECTED (ZEND_BB_ENTRY|ZEND_BB_TRY|ZEND_BB_CATCH|ZEND_BB_FINALLY|ZEND_BB_FINALLY_END|ZEND_BB_GEN_VAR|ZEND_BB_KILL_VAR)
|
||||
#define ZEND_BB_PROTECTED (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY|ZEND_BB_TRY|ZEND_BB_CATCH|ZEND_BB_FINALLY|ZEND_BB_FINALLY_END|ZEND_BB_GEN_VAR|ZEND_BB_KILL_VAR)
|
||||
|
||||
typedef struct _zend_basic_block {
|
||||
uint32_t flags;
|
||||
@ -87,6 +88,8 @@ typedef struct _zend_cfg {
|
||||
int *predecessors;
|
||||
uint32_t *map;
|
||||
unsigned int split_at_live_ranges : 1;
|
||||
unsigned int split_at_calls : 1;
|
||||
unsigned int split_at_recv : 1;
|
||||
} zend_cfg;
|
||||
|
||||
/* Build Flags */
|
||||
@ -97,6 +100,7 @@ typedef struct _zend_cfg {
|
||||
#define ZEND_SSA_RC_INFERENCE (1<<27)
|
||||
#define ZEND_CFG_SPLIT_AT_LIVE_RANGES (1<<26)
|
||||
#define ZEND_CFG_NO_ENTRY_PREDECESSORS (1<<25)
|
||||
#define ZEND_CFG_RECV_ENTRY (1<<24)
|
||||
|
||||
#define CRT_CONSTANT_EX(op_array, node, rt_constants) \
|
||||
((rt_constants) ? \
|
||||
|
@ -669,7 +669,7 @@ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags
|
||||
if (b->flags & ZEND_BB_EXIT) {
|
||||
fprintf(stderr, " exit");
|
||||
}
|
||||
if (b->flags & ZEND_BB_ENTRY) {
|
||||
if (b->flags & (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY)) {
|
||||
fprintf(stderr, " entry");
|
||||
}
|
||||
if (b->flags & ZEND_BB_TRY) {
|
||||
|
@ -2350,7 +2350,7 @@ static inline zend_uchar get_compound_assign_op(zend_uchar opcode) {
|
||||
}
|
||||
|
||||
static inline zend_class_entry *get_class_entry(const zend_script *script, zend_string *lcname) {
|
||||
zend_class_entry *ce = zend_hash_find_ptr(&script->class_table, lcname);
|
||||
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
|
||||
if (ce) {
|
||||
return ce;
|
||||
}
|
||||
@ -2943,7 +2943,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
|
||||
case ZEND_DECLARE_ANON_CLASS:
|
||||
case ZEND_DECLARE_ANON_INHERITED_CLASS:
|
||||
UPDATE_SSA_TYPE(MAY_BE_CLASS, ssa_ops[i].result_def);
|
||||
if ((ce = zend_hash_find_ptr(&script->class_table, Z_STR_P(CRT_CONSTANT_EX(op_array, opline->op1, ssa->rt_constants)))) != NULL) {
|
||||
if (script && (ce = zend_hash_find_ptr(&script->class_table, Z_STR_P(CRT_CONSTANT_EX(op_array, opline->op1, ssa->rt_constants)))) != NULL) {
|
||||
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_ops[i].result_def);
|
||||
}
|
||||
break;
|
||||
|
@ -947,12 +947,15 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend
|
||||
func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]);
|
||||
if (func_info && func_info->ssa.var_info) {
|
||||
zend_redo_pass_two_ex(call_graph.op_arrays[i], &func_info->ssa);
|
||||
ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
|
||||
} else {
|
||||
zend_redo_pass_two(call_graph.op_arrays[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < call_graph.op_arrays_count; i++) {
|
||||
ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
|
||||
}
|
||||
|
||||
zend_arena_release(&ctx.arena, checkpoint);
|
||||
} else
|
||||
#endif
|
||||
|
@ -501,7 +501,7 @@ static void place_essa_pis(
|
||||
(opline-1)->op2_type == IS_CONST) {
|
||||
int var = EX_VAR_TO_NUM((opline-1)->op1.var);
|
||||
zend_string *lcname = Z_STR_P(CRT_CONSTANT((opline-1)->op2) + 1);
|
||||
zend_class_entry *ce = zend_hash_find_ptr(&script->class_table, lcname);
|
||||
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
|
||||
if (!ce) {
|
||||
ce = zend_hash_find_ptr(CG(class_table), lcname);
|
||||
if (!ce || ce->type != ZEND_INTERNAL_CLASS) {
|
||||
|
@ -186,7 +186,7 @@ static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
|
||||
}
|
||||
#endif
|
||||
err = ERROR_INVALID_ADDRESS;
|
||||
zend_win_error_message(ACCEL_LOG_FATAL, "Base address marks unusable memory region. Please setup opcache.file_cache and opcache.file_cache_callback directives for more convenient Opcache usage", err);
|
||||
zend_win_error_message(ACCEL_LOG_FATAL, "Base address marks unusable memory region. Please setup opcache.file_cache and opcache.file_cache_fallback directives for more convenient Opcache usage", err);
|
||||
return ALLOC_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,9 @@ static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
|
||||
it->next = NULL;
|
||||
|
||||
if ((it->re = pcre_compile(regexp, PCRE_NO_AUTO_CAPTURE, &pcre_error, &pcre_error_offset, 0)) == NULL) {
|
||||
free(it);
|
||||
blacklist_report_regexp_error(pcre_error, pcre_error_offset);
|
||||
return;
|
||||
}
|
||||
/* prepare for the next iteration */
|
||||
p = regexp + 2;
|
||||
|
@ -105,7 +105,7 @@ expect_openssl_errors('openssl_private_decrypt', ['04065072']);
|
||||
// public encrypt and decrypt with failed padding check and padding
|
||||
@openssl_public_encrypt("data", $crypted, $public_key_file, 1000);
|
||||
@openssl_public_decrypt("data", $crypted, $public_key_file);
|
||||
expect_openssl_errors('openssl_private_(en|de)crypt padding', ['0906D06C', '04068076', '0407006A', '04067072']);
|
||||
expect_openssl_errors('openssl_private_(en|de)crypt padding', ['0906D06C', '04068076', '04067072']);
|
||||
|
||||
// X509
|
||||
echo "X509 errors\n";
|
||||
|
@ -1176,6 +1176,11 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
|
||||
if (UNEXPECTED(pce->name_count > 0)) {
|
||||
subpat_names = make_subpats_table(num_subpats, pce);
|
||||
if (!subpat_names) {
|
||||
if (size_offsets <= 32) {
|
||||
free_alloca(offsets, use_heap);
|
||||
} else {
|
||||
efree(offsets);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -280,18 +280,30 @@ static int dblib_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
|
||||
switch(attr) {
|
||||
case PDO_ATTR_TIMEOUT:
|
||||
return 0;
|
||||
|
||||
case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
|
||||
((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier = zval_get_long(val);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
|
||||
{
|
||||
/* dblib_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; */
|
||||
switch (attr) {
|
||||
case PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER:
|
||||
ZVAL_BOOL(return_value, ((pdo_dblib_db_handle *)dbh->driver_data)->stringify_uniqueidentifier);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct pdo_dbh_methods dblib_methods = {
|
||||
dblib_handle_closer,
|
||||
dblib_handle_preparer,
|
||||
@ -347,6 +359,15 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
|
||||
|
||||
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);
|
||||
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
H->login = dblogin();
|
||||
H->err.sqlstate = dbh->error_code;
|
||||
H->stringify_uniqueidentifier = 0;
|
||||
|
||||
if (!H->login) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (driver_options) {
|
||||
int connect_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT, -1);
|
||||
int query_timeout = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_QUERY_TIMEOUT, -1);
|
||||
@ -361,14 +382,8 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
|
||||
|
||||
dbsetlogintime(connect_timeout); /* Connection/Login Timeout */
|
||||
dbsettime(query_timeout); /* Statement Timeout */
|
||||
}
|
||||
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
H->login = dblogin();
|
||||
H->err.sqlstate = dbh->error_code;
|
||||
|
||||
if (!H->login) {
|
||||
goto cleanup;
|
||||
H->stringify_uniqueidentifier = pdo_attr_lval(driver_options, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, 0);
|
||||
}
|
||||
|
||||
DBERRHANDLE(H->login, (EHANDLEFUNC) pdo_dblib_error_handler);
|
||||
|
@ -376,16 +376,28 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef SQLUNIQUE
|
||||
case SQLUNIQUE: {
|
||||
#else
|
||||
case 36: { /* FreeTDS hack */
|
||||
#endif
|
||||
if (H->stringify_uniqueidentifier) { // 36-char hex string representation
|
||||
tmp_data_len = 36;
|
||||
tmp_data = safe_emalloc(tmp_data_len, sizeof(char), 1);
|
||||
data_len = (unsigned int) dbconvert(NULL, SQLUNIQUE, (BYTE*)data, data_len, SQLCHAR, (BYTE*)tmp_data, tmp_data_len);
|
||||
php_strtoupper(tmp_data, data_len);
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */
|
||||
ZVAL_STRINGL(zv, tmp_data, data_len);
|
||||
efree(tmp_data);
|
||||
|
||||
} else { // a 16-byte binary representation
|
||||
zv = emalloc(sizeof(zval));
|
||||
ZVAL_STRINGL(zv, data, 16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (dbwillconvert(coltype, SQLCHAR)) {
|
||||
tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
|
||||
@ -479,4 +491,3 @@ struct pdo_stmt_methods dblib_stmt_methods = {
|
||||
pdo_dblib_stmt_next_rowset, /* nextrow */
|
||||
pdo_dblib_stmt_cursor_closer
|
||||
};
|
||||
|
||||
|
@ -173,6 +173,7 @@ PHP_MINIT_FUNCTION(pdo_dblib)
|
||||
{
|
||||
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_CONNECTION_TIMEOUT", (long) PDO_DBLIB_ATTR_CONNECTION_TIMEOUT);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT);
|
||||
REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER", (long) PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER);
|
||||
|
||||
if (FAIL == dbinit()) {
|
||||
return FAILURE;
|
||||
|
@ -113,6 +113,7 @@ typedef struct {
|
||||
DBPROCESS *link;
|
||||
|
||||
pdo_dblib_err err;
|
||||
unsigned stringify_uniqueidentifier:1;
|
||||
} pdo_dblib_db_handle;
|
||||
|
||||
typedef struct {
|
||||
@ -142,7 +143,8 @@ ZEND_EXTERN_MODULE_GLOBALS(dblib)
|
||||
|
||||
enum {
|
||||
PDO_DBLIB_ATTR_CONNECTION_TIMEOUT = PDO_ATTR_DRIVER_SPECIFIC,
|
||||
PDO_DBLIB_ATTR_QUERY_TIMEOUT
|
||||
PDO_DBLIB_ATTR_QUERY_TIMEOUT,
|
||||
PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
67
ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt
Normal file
67
ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt
Normal file
@ -0,0 +1,67 @@
|
||||
--TEST--
|
||||
PDO_DBLIB: Uniqueidentifier column data type stringifying
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_dblib')) die('skip not loaded');
|
||||
require __DIR__ . '/config.inc';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/config.inc';
|
||||
|
||||
|
||||
$testGUID = '82A88958-672B-4C22-842F-216E2B88E72A';
|
||||
$testGUIDBinary = base64_decode('WImogitnIkyELyFuK4jnKg==');
|
||||
|
||||
$sql = "SELECT CAST('$testGUID' as uniqueidentifier) as [guid]";
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 1. Get and Set the attribute
|
||||
//--------------------------------------------------------------------------------
|
||||
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
|
||||
var_dump(true === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER));
|
||||
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, false);
|
||||
var_dump(false === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER));
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 2. Binary
|
||||
//--------------------------------------------------------------------------------
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
var_dump($row['guid'] === $testGUIDBinary);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 3. PDO::ATTR_STRINGIFY_FETCHES must not affect `uniqueidentifier` representation
|
||||
//--------------------------------------------------------------------------------
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
|
||||
var_dump($row['guid'] === $testGUIDBinary);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// 4. Stringifying
|
||||
// ! With TDS protocol version <7.0 binary will be returned and the test will fail !
|
||||
// TODO: something from PDO::ATTR_SERVER_VERSION, PDO::ATTR_CLIENT_VERSION or PDO::ATTR_SERVER_INFO should be used
|
||||
// to get TDS version and skip this test in this case.
|
||||
//--------------------------------------------------------------------------------
|
||||
$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
|
||||
$stmt = $db->query($sql);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
var_dump($row['guid'] === $testGUID);
|
||||
var_dump($row['guid']);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
string(36) "82A88958-672B-4C22-842F-216E2B88E72A"
|
@ -199,7 +199,6 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest) /* {{{ */
|
||||
zend_hash_internal_pointer_reset(manifest);
|
||||
|
||||
while (FAILURE != zend_hash_has_more_elements(manifest)) {
|
||||
keylen = 0;
|
||||
if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key(manifest, &str_key, &unused)) {
|
||||
break;
|
||||
}
|
||||
|
Binary file not shown.
@ -6,7 +6,7 @@ echo "hi";
|
||||
';
|
||||
$a->setStub('<?php
|
||||
try {
|
||||
Phar::webPhar("test.phar", "/index.php", null, array(), "sort");
|
||||
Phar::webPhar("test.phar", "/index.php", null, array(), function() { throw new Exception; });
|
||||
} catch (Exception $e) {
|
||||
die($e->getMessage() . "\n");
|
||||
}
|
||||
|
@ -13,4 +13,4 @@ Content-type: text/html; charset=UTF-8
|
||||
--FILE_EXTERNAL--
|
||||
files/frontcontroller17.phar
|
||||
--EXPECTF--
|
||||
%ahar error: failed to call rewrite callback
|
||||
%ahar error: rewrite callback must return a string or false
|
||||
|
Binary file not shown.
@ -6,7 +6,7 @@ echo "hi";
|
||||
';
|
||||
$a->setStub('<?php
|
||||
try {
|
||||
Phar::webPhar("test.phar", "/index.php", null, array(), "sort");
|
||||
Phar::webPhar("test.phar", "/index.php", null, array(), function() { throw new Exception; });
|
||||
} catch (Exception $e) {
|
||||
die($e->getMessage() . "\n");
|
||||
}
|
||||
|
@ -12,4 +12,4 @@ Content-type: text/html; charset=UTF-8
|
||||
--FILE_EXTERNAL--
|
||||
files/frontcontroller17.phar
|
||||
--EXPECTF--
|
||||
%ahar error: failed to call rewrite callback
|
||||
%ahar error: rewrite callback must return a string or false
|
||||
|
@ -3038,8 +3038,9 @@ ZEND_METHOD(reflection_type, __toString)
|
||||
str = reflection_type_name(param);
|
||||
|
||||
if (param->arg_info->allow_null) {
|
||||
str = zend_string_extend(str, ZSTR_LEN(str) + 1, 0);
|
||||
memmove(ZSTR_VAL(str) + 1, ZSTR_VAL(str), ZSTR_LEN(str) + 1);
|
||||
size_t orig_len = ZSTR_LEN(str);
|
||||
str = zend_string_extend(str, orig_len + 1, 0);
|
||||
memmove(ZSTR_VAL(str) + 1, ZSTR_VAL(str), orig_len + 1);
|
||||
ZSTR_VAL(str)[0] = '?';
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ var_dump($methodWithArgs->invokeArgs($testClassInstance, array()));
|
||||
--EXPECTF--
|
||||
Method with args:
|
||||
|
||||
Fatal error: Uncaught Error: Too few arguments to function TestClass::methodWithArgs(), 0 passed and exactly 2 expected in %sReflectionMethod_invokeArgs_error1.php:5
|
||||
Fatal error: Uncaught ArgumentCountError: Too few arguments to function TestClass::methodWithArgs(), 0 passed and exactly 2 expected in %sReflectionMethod_invokeArgs_error1.php:5
|
||||
Stack trace:
|
||||
#0 [internal function]: TestClass->methodWithArgs()
|
||||
#1 %sReflectionMethod_invokeArgs_error1.php(19): ReflectionMethod->invokeArgs(Object(TestClass), Array)
|
||||
|
@ -21,7 +21,7 @@ var_dump($methodWithArgs->invoke($testClassInstance));
|
||||
--EXPECTF--
|
||||
Method with args:
|
||||
|
||||
Fatal error: Uncaught Error: Too few arguments to function TestClass::methodWithArgs(), 0 passed and exactly 2 expected in %sReflectionMethod_invoke_error2.php:5
|
||||
Fatal error: Uncaught ArgumentCountError: Too few arguments to function TestClass::methodWithArgs(), 0 passed and exactly 2 expected in %sReflectionMethod_invoke_error2.php:5
|
||||
Stack trace:
|
||||
#0 [internal function]: TestClass->methodWithArgs()
|
||||
#1 %sReflectionMethod_invoke_error2.php(15): ReflectionMethod->invoke(Object(TestClass))
|
||||
|
@ -73,6 +73,8 @@ foreach ([
|
||||
var_dump((string)$ra);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
*** functions
|
||||
** Function 0 - Parameter 0
|
||||
|
@ -27,12 +27,8 @@ echo "Done\n";
|
||||
string(9) "x.changed"
|
||||
|
||||
Warning: Parameter 1 to C::__construct() expected to be a reference, value given in %sbug42976.php on line 15
|
||||
|
||||
Warning: ReflectionClass::newInstance(): Invocation of C's constructor failed in %sbug42976.php on line 15
|
||||
string(10) "x.original"
|
||||
|
||||
Warning: Parameter 1 to C::__construct() expected to be a reference, value given in %sbug42976.php on line 18
|
||||
|
||||
Warning: ReflectionClass::newInstanceArgs(): Invocation of C's constructor failed in %sbug42976.php on line 18
|
||||
string(10) "x.original"
|
||||
Done
|
||||
|
@ -643,9 +643,11 @@ PS_GC_FUNC(files)
|
||||
|
||||
if (data->dirdepth == 0) {
|
||||
*nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime);
|
||||
} else {
|
||||
*nrdels = -1; // Cannot process multiple depth save dir
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
return *nrdels;
|
||||
}
|
||||
|
||||
|
||||
|
@ -468,7 +468,7 @@ PS_GC_FUNC(mm)
|
||||
|
||||
mm_unlock(data->mm);
|
||||
|
||||
return SUCCESS;
|
||||
return nrdels;
|
||||
}
|
||||
|
||||
PS_CREATE_SID_FUNC(mm)
|
||||
|
@ -176,13 +176,22 @@ PS_DESTROY_FUNC(user)
|
||||
PS_GC_FUNC(user)
|
||||
{
|
||||
zval args[1];
|
||||
STDVARS;
|
||||
zval retval;
|
||||
|
||||
ZVAL_LONG(&args[0], maxlifetime);
|
||||
|
||||
ps_call_handler(&PSF(gc), 1, args, &retval);
|
||||
|
||||
FINISH;
|
||||
if (Z_TYPE(retval) == IS_LONG) {
|
||||
convert_to_long(&retval);
|
||||
return Z_LVAL(retval);
|
||||
}
|
||||
/* This is for older API compatibility */
|
||||
if (Z_TYPE(retval) == IS_TRUE) {
|
||||
return 1;
|
||||
}
|
||||
/* Anything else is some kind of error */
|
||||
return -1; // Error
|
||||
}
|
||||
|
||||
PS_CREATE_SID_FUNC(user)
|
||||
|
@ -148,7 +148,7 @@ PHP_METHOD(SessionHandler, destroy)
|
||||
PHP_METHOD(SessionHandler, gc)
|
||||
{
|
||||
zend_long maxlifetime;
|
||||
int nrdels;
|
||||
zend_long nrdels = -1;
|
||||
|
||||
PS_SANITY_CHECK_IS_OPEN;
|
||||
|
||||
@ -156,7 +156,10 @@ PHP_METHOD(SessionHandler, gc)
|
||||
return;
|
||||
}
|
||||
|
||||
RETURN_BOOL(SUCCESS == PS(default_mod)->s_gc(&PS(mod_data), maxlifetime, &nrdels));
|
||||
if (PS(default_mod)->s_gc(&PS(mod_data), maxlifetime, &nrdels) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
RETURN_LONG(nrdels);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#define PS_READ_ARGS void **mod_data, zend_string *key, zend_string **val, zend_long maxlifetime
|
||||
#define PS_WRITE_ARGS void **mod_data, zend_string *key, zend_string *val, zend_long maxlifetime
|
||||
#define PS_DESTROY_ARGS void **mod_data, zend_string *key
|
||||
#define PS_GC_ARGS void **mod_data, zend_long maxlifetime, int *nrdels
|
||||
#define PS_GC_ARGS void **mod_data, zend_long maxlifetime, zend_long *nrdels
|
||||
#define PS_CREATE_SID_ARGS void **mod_data
|
||||
#define PS_VALIDATE_SID_ARGS void **mod_data, zend_string *key
|
||||
#define PS_UPDATE_TIMESTAMP_ARGS void **mod_data, zend_string *key, zend_string *val, zend_long maxlifetime
|
||||
@ -51,7 +51,7 @@ typedef struct ps_module_struct {
|
||||
int (*s_read)(PS_READ_ARGS);
|
||||
int (*s_write)(PS_WRITE_ARGS);
|
||||
int (*s_destroy)(PS_DESTROY_ARGS);
|
||||
int (*s_gc)(PS_GC_ARGS);
|
||||
zend_long (*s_gc)(PS_GC_ARGS);
|
||||
zend_string *(*s_create_sid)(PS_CREATE_SID_ARGS);
|
||||
int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
|
||||
int (*s_update_timestamp)(PS_UPDATE_TIMESTAMP_ARGS);
|
||||
@ -65,7 +65,7 @@ typedef struct ps_module_struct {
|
||||
#define PS_READ_FUNC(x) int ps_read_##x(PS_READ_ARGS)
|
||||
#define PS_WRITE_FUNC(x) int ps_write_##x(PS_WRITE_ARGS)
|
||||
#define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
|
||||
#define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
|
||||
#define PS_GC_FUNC(x) zend_long ps_gc_##x(PS_GC_ARGS)
|
||||
#define PS_CREATE_SID_FUNC(x) zend_string *ps_create_sid_##x(PS_CREATE_SID_ARGS)
|
||||
#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
|
||||
#define PS_UPDATE_TIMESTAMP_FUNC(x) int ps_update_timestamp_##x(PS_UPDATE_TIMESTAMP_ARGS)
|
||||
|
@ -353,19 +353,23 @@ PHPAPI int php_session_valid_key(const char *key) /* {{{ */
|
||||
/* }}} */
|
||||
|
||||
|
||||
static void php_session_gc(void) /* {{{ */
|
||||
static zend_long php_session_gc(zend_bool immediate) /* {{{ */
|
||||
{
|
||||
int nrand;
|
||||
zend_long num = -1;
|
||||
|
||||
/* GC must be done before reading session data. */
|
||||
if ((PS(mod_data) || PS(mod_user_implemented)) && PS(gc_probability) > 0) {
|
||||
int nrdels = -1;
|
||||
|
||||
nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg());
|
||||
if (nrand < PS(gc_probability)) {
|
||||
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels);
|
||||
if ((PS(mod_data) || PS(mod_user_implemented))) {
|
||||
if (immediate) {
|
||||
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &num);
|
||||
return num;
|
||||
}
|
||||
nrand = (zend_long) ((float) PS(gc_divisor) * php_combined_lcg());
|
||||
if (PS(gc_probability) > 0 && nrand < PS(gc_probability)) {
|
||||
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &num);
|
||||
}
|
||||
}
|
||||
return num;
|
||||
} /* }}} */
|
||||
|
||||
static void php_session_initialize(void) /* {{{ */
|
||||
@ -430,7 +434,7 @@ static void php_session_initialize(void) /* {{{ */
|
||||
}
|
||||
|
||||
/* GC must be done after read */
|
||||
php_session_gc();
|
||||
php_session_gc(0);
|
||||
|
||||
if (PS(session_vars)) {
|
||||
zend_string_release(PS(session_vars));
|
||||
@ -1476,28 +1480,27 @@ PHPAPI void php_session_start(void) /* {{{ */
|
||||
if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))) {
|
||||
ppid2sid(ppid);
|
||||
PS(send_cookie) = 0;
|
||||
PS(define_sid) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (PS(define_sid) && !PS(id) && (data = zend_hash_str_find(&EG(symbol_table), "_GET", sizeof("_GET") - 1))) {
|
||||
/* Initilize session ID from non cookie values */
|
||||
if (!PS(use_only_cookies)) {
|
||||
if (!PS(id) && (data = zend_hash_str_find(&EG(symbol_table), "_GET", sizeof("_GET") - 1))) {
|
||||
ZVAL_DEREF(data);
|
||||
if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))) {
|
||||
ppid2sid(ppid);
|
||||
}
|
||||
}
|
||||
|
||||
if (PS(define_sid) && !PS(id) && (data = zend_hash_str_find(&EG(symbol_table), "_POST", sizeof("_POST") - 1))) {
|
||||
if (!PS(id) && (data = zend_hash_str_find(&EG(symbol_table), "_POST", sizeof("_POST") - 1))) {
|
||||
ZVAL_DEREF(data);
|
||||
if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))) {
|
||||
ppid2sid(ppid);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the REQUEST_URI symbol for a string of the form
|
||||
* '<session-name>=<session-id>' to allow URLs of the form
|
||||
* http://yoursite/<session-name>=<session-id>/script.php */
|
||||
if (PS(define_sid) && !PS(id) &&
|
||||
zend_is_auto_global_str("_SERVER", sizeof("_SERVER") - 1) == SUCCESS &&
|
||||
if (!PS(id) && zend_is_auto_global_str("_SERVER", sizeof("_SERVER") - 1) == SUCCESS &&
|
||||
(data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "REQUEST_URI", sizeof("REQUEST_URI") - 1)) &&
|
||||
Z_TYPE_P(data) == IS_STRING &&
|
||||
(p = strstr(Z_STRVAL_P(data), PS(session_name))) &&
|
||||
@ -1509,11 +1512,9 @@ PHPAPI void php_session_start(void) /* {{{ */
|
||||
PS(id) = zend_string_init(p, q - p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether the current request was referred to by
|
||||
* an external site which invalidates the previously found id. */
|
||||
if (PS(define_sid) && PS(id) &&
|
||||
PS(extern_referer_chk)[0] != '\0' &&
|
||||
if (PS(id) && PS(extern_referer_chk)[0] != '\0' &&
|
||||
!Z_ISUNDEF(PG(http_globals)[TRACK_VARS_SERVER]) &&
|
||||
(data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", sizeof("HTTP_REFERER") - 1)) &&
|
||||
Z_TYPE_P(data) == IS_STRING &&
|
||||
@ -1524,6 +1525,7 @@ PHPAPI void php_session_start(void) /* {{{ */
|
||||
PS(id) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally check session id for dangerous characters
|
||||
* Security note: session id may be embedded in HTML pages.*/
|
||||
@ -2016,7 +2018,6 @@ static PHP_FUNCTION(session_regenerate_id)
|
||||
|
||||
/* {{{ proto void session_create_id([string prefix])
|
||||
Generate new session ID. Intended for user save handlers. */
|
||||
#if 0
|
||||
/* This is not used yet */
|
||||
static PHP_FUNCTION(session_create_id)
|
||||
{
|
||||
@ -2038,7 +2039,20 @@ static PHP_FUNCTION(session_create_id)
|
||||
}
|
||||
|
||||
if (PS(session_status) == php_session_active) {
|
||||
int limit = 3;
|
||||
while (limit--) {
|
||||
new_id = PS(mod)->s_create_sid(&PS(mod_data));
|
||||
if (!PS(mod)->s_validate_sid) {
|
||||
break;
|
||||
} else {
|
||||
/* Detect collision and retry */
|
||||
if (PS(mod)->s_validate_sid(&PS(mod_data), new_id) == FAILURE) {
|
||||
zend_string_release(new_id);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
new_id = php_session_create_id(NULL);
|
||||
}
|
||||
@ -2053,9 +2067,7 @@ static PHP_FUNCTION(session_create_id)
|
||||
}
|
||||
smart_str_0(&id);
|
||||
RETVAL_NEW_STR(id.s);
|
||||
smart_str_free(&id);
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string session_cache_limiter([string new_cache_limiter])
|
||||
@ -2239,6 +2251,32 @@ static PHP_FUNCTION(session_unset)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int session_gc(void)
|
||||
Perform GC and return number of deleted sessions */
|
||||
static PHP_FUNCTION(session_gc)
|
||||
{
|
||||
zend_long num;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PS(session_status) != php_session_active) {
|
||||
php_error_docref(NULL, E_WARNING, "Session is not active");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
num = php_session_gc(1);
|
||||
if (num < 0) {
|
||||
php_error_docref(NULL, E_WARNING, "Failed to perfom session GC");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
RETURN_LONG(num);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto void session_write_close(void)
|
||||
Write session data and end session */
|
||||
static PHP_FUNCTION(session_write_close)
|
||||
@ -2326,6 +2364,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_session_id, 0, 0, 0)
|
||||
ZEND_ARG_INFO(0, id)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_session_create_id, 0, 0, 0)
|
||||
ZEND_ARG_INFO(0, prefix)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_session_regenerate_id, 0, 0, 0)
|
||||
ZEND_ARG_INFO(0, delete_old_session)
|
||||
ZEND_END_ARG_INFO()
|
||||
@ -2410,12 +2452,14 @@ static const zend_function_entry session_functions[] = {
|
||||
PHP_FE(session_module_name, arginfo_session_module_name)
|
||||
PHP_FE(session_save_path, arginfo_session_save_path)
|
||||
PHP_FE(session_id, arginfo_session_id)
|
||||
PHP_FE(session_create_id, arginfo_session_create_id)
|
||||
PHP_FE(session_regenerate_id, arginfo_session_regenerate_id)
|
||||
PHP_FE(session_decode, arginfo_session_decode)
|
||||
PHP_FE(session_encode, arginfo_session_void)
|
||||
PHP_FE(session_start, arginfo_session_void)
|
||||
PHP_FE(session_destroy, arginfo_session_void)
|
||||
PHP_FE(session_unset, arginfo_session_void)
|
||||
PHP_FE(session_gc, arginfo_session_void)
|
||||
PHP_FE(session_set_save_handler, arginfo_session_set_save_handler)
|
||||
PHP_FE(session_cache_limiter, arginfo_session_cache_limiter)
|
||||
PHP_FE(session_cache_expire, arginfo_session_cache_expire)
|
||||
|
35
ext/session/tests/bug72940.phpt
Normal file
35
ext/session/tests/bug72940.phpt
Normal file
@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Bug #72940 - SID always defined
|
||||
--INI--
|
||||
error_reporting=-1
|
||||
session.save_path=
|
||||
session.name=PHPSESSID
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--COOKIE--
|
||||
PHPSESSID=bug72940test
|
||||
--GET--
|
||||
PHPSESSID=bug72940get
|
||||
--FILE--
|
||||
<?php
|
||||
ob_start();
|
||||
|
||||
ini_set('session.use_strict_mode', 0);
|
||||
ini_set('session.use_cookies', 1);
|
||||
ini_set('session.use_only_cookies', 0);
|
||||
session_start();
|
||||
var_dump(session_id(), SID);
|
||||
session_destroy();
|
||||
|
||||
ini_set('session.use_strict_mode', 0);
|
||||
ini_set('session.use_cookies', 0);
|
||||
ini_set('session.use_only_cookies', 0);
|
||||
session_start();
|
||||
var_dump(session_id(), SID);
|
||||
session_destroy();
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(12) "bug72940test"
|
||||
string(0) ""
|
||||
string(11) "bug72940get"
|
||||
string(21) "PHPSESSID=bug72940get"
|
57
ext/session/tests/session_create_id_basic.phpt
Normal file
57
ext/session/tests/session_create_id_basic.phpt
Normal file
@ -0,0 +1,57 @@
|
||||
--TEST--
|
||||
Test session_create_id() function : basic functionality
|
||||
--INI--
|
||||
session.save_handler=files
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start();
|
||||
|
||||
/*
|
||||
* Prototype : string session_create_id([string $prefix])
|
||||
* Description : Create new session ID with prefix optionally.
|
||||
* Source code : ext/session/session.c
|
||||
*/
|
||||
|
||||
echo "*** Testing session_create_id() : basic functionality ***\n";
|
||||
|
||||
// No session
|
||||
var_dump(session_create_id());
|
||||
var_dump(session_create_id('ABCD'));
|
||||
|
||||
ini_set('session.use_strict_mode', true);
|
||||
$sid = session_create_id('XYZ');
|
||||
var_dump($sid);
|
||||
var_dump(session_id($sid));
|
||||
session_start();
|
||||
var_dump(session_id());
|
||||
var_dump(session_id() === $sid);
|
||||
session_destroy();
|
||||
|
||||
ini_set('session.use_strict_mode', false);
|
||||
$sid = session_create_id('XYZ');
|
||||
var_dump($sid);
|
||||
var_dump(session_id($sid));
|
||||
session_start();
|
||||
var_dump(session_id());
|
||||
var_dump(session_id() === $sid);
|
||||
session_destroy();
|
||||
|
||||
echo "Done";
|
||||
ob_end_flush();
|
||||
?>
|
||||
--EXPECTF--
|
||||
*** Testing session_create_id() : basic functionality ***
|
||||
string(32) "%s"
|
||||
string(36) "ABCD%s"
|
||||
string(35) "XYZ%s"
|
||||
string(0) ""
|
||||
string(32) "%s"
|
||||
bool(false)
|
||||
string(35) "XYZ%s"
|
||||
string(0) ""
|
||||
string(35) "XYZ%s"
|
||||
bool(true)
|
||||
Done
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user