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
  Revert 	39587c4817 	8b7f594a2b Because of 	24fdffdacb
  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:
Stanislav Malyshev 2016-09-01 23:28:56 -07:00
commit 2adc335eb5
156 changed files with 3129 additions and 585 deletions

92
NEWS
View File

@ -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)

View File

@ -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;
}
}

View File

@ -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:

View File

@ -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

View File

@ -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}

View File

@ -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}

View File

@ -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
View 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) {
}

View 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
View 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
View 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
View 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

View 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)

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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,14 +208,16 @@ 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",
class_name, \
class_name[0] ? "::" : "", \
ZSTR_VAL(active_function->common.function_name),
min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
num_args < min_num_args ? min_num_args : max_num_args,
(num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
num_args);
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),
min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
num_args < min_num_args ? min_num_args : max_num_args,
(num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
num_args);
}
/* }}} */
@ -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;

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -696,20 +696,24 @@ 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;
zend_verify_type_error_common(
zf, arg_info, ce, value,
&fname, &fsep, &fclass, &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);
if (zf->common.type == ZEND_USER_FUNCTION) {
if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
zend_type_error("Argument %d passed to %s%s%s() must %s%s%s, %s%s given, called in %s on line %d",
arg_num, fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind,
ZSTR_VAL(ptr->func->op_array.filename), ptr->opline->lineno);
if (zf->common.type == ZEND_USER_FUNCTION) {
if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
zend_type_error("Argument %d passed to %s%s%s() must %s%s%s, %s%s given, called in %s on line %d",
arg_num, fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind,
ZSTR_VAL(ptr->func->op_array.filename), ptr->opline->lineno);
} 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_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_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);
zend_missing_arg_error(ptr);
}
}
@ -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;

View File

@ -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)) {

View File

@ -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++;

View File

@ -328,32 +328,19 @@ 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 (pathw[0] >= L'A' && pathw[0] <= L'Z') {
buf->st_dev = buf->st_rdev = pathw[0] - L'A';
} else {
buf->st_dev = buf->st_rdev = pathw[0] - L'a';
}
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 {
buf->st_dev = buf->st_rdev = -1;
buf->st_dev = buf->st_rdev = pathw[0] - L'a';
}
break;
} else if (!r) {
buf->st_dev = buf->st_rdev = -1;
break;
} else {
len = r+1;
tmp = (wchar_t*)malloc(len*sizeof(wchar_t));
buf->st_dev = buf->st_rdev = -1;
}
}
if (tmp != cur_path) {
free(tmp);
} else {
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

View File

@ -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)) {

View File

@ -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)) {
@ -61867,7 +61834,7 @@ void zend_init_opcodes_handlers(void)
4596
};
zend_opcode_handlers = labels;
zend_handlers_count = sizeof(labels) / sizeof(void*);
zend_handlers_count = sizeof(labels) / sizeof(void*);
zend_spec_handlers = specs;
}

View File

@ -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;

View File

@ -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()

View File

@ -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++;

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View 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);
?>

View 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);
?>

View File

@ -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");

View File

@ -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;
}

View File

@ -2245,7 +2245,9 @@ 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);
gdImageSetPixel (dst, dstX + x, dstY + y, c);
if (c != src->transparent) {
gdImageSetPixel (dst, dstX + x, dstY + y, c);
}
}
}
} else {
@ -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);

View 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==

View 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==

View File

@ -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);

View 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) ""

View File

@ -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;

View File

@ -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;
}

View File

@ -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))) {
efree(formatted);
}
if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
if (formatted) {
efree(formatted);
}
RETURN_FALSE;
} else {
INTL_METHOD_RETVAL_UTF8(mfo, formatted, formatted_len, 1);

View 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==

View File

@ -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

View File

@ -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

View File

@ -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);
}
/* }}} */

View File

@ -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);
}
/* }}} */

View File

@ -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);
}
smart_str_appendc(buf, ':');
php_json_pretty_print_char(buf, 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;
smart_str_appendl(buf, "null", 4);
return;
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
smart_str_appendl(buf, "null", 4);
}
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;
smart_str_appendl(buf, "null", 4);
return;
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
smart_str_appendl(buf, "null", 4);
}
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;
smart_str_appendl(buf, "null", 4);
return;
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
smart_str_appendl(buf, "null", 4);
}
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;
smart_str_appendl(buf, "null", 4);
break;
if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
smart_str_appendl(buf, "null", 4);
}
return FAILURE;
}
return;
return SUCCESS;
}
/* }}} */

View File

@ -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;

View File

@ -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 */

View 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]

View File

@ -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;
}

View File

@ -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;

View 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==

View File

@ -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;

View File

@ -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];

View File

@ -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:

View File

@ -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) ? \

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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";

View File

@ -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;
}
}

View File

@ -280,16 +280,28 @@ 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; */
return 0;
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 = {
@ -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);

View File

@ -120,7 +120,7 @@ static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt)
dbcancel(H->link);
pdo_dblib_err_dtor(&H->err);
return 1;
}
@ -213,7 +213,7 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno)
pdo_dblib_db_handle *H = S->H;
struct pdo_column_data *col;
char *fname;
if(colno >= stmt->column_count || colno < 0) {
return FAILURE;
}
@ -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
zv = emalloc(sizeof(zval));
ZVAL_STRINGL(zv, data, 16); /* uniqueidentifier is a 16-byte binary number */
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, 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
};

View File

@ -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;

View File

@ -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

View 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"

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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

View File

@ -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");
}

View File

@ -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

View File

@ -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] = '?';
}

View File

@ -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)

View File

@ -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))

View File

@ -73,6 +73,8 @@ foreach ([
var_dump((string)$ra);
}
}
?>
--EXPECT--
*** functions
** Function 0 - Parameter 0

View File

@ -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

View File

@ -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;
}

View File

@ -468,7 +468,7 @@ PS_GC_FUNC(mm)
mm_unlock(data->mm);
return SUCCESS;
return nrdels;
}
PS_CREATE_SID_FUNC(mm)

View File

@ -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)

View File

@ -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);
}
/* }}} */

View File

@ -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)

View File

@ -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,52 +1480,50 @@ 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))) {
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);
/* 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))) {
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(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 &&
(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))) &&
p[lensess] == '='
) {
char *q;
p += lensess + 1;
if ((q = strpbrk(p, "/?\\"))) {
PS(id) = zend_string_init(p, q - p, 0);
/* 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(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))) &&
p[lensess] == '='
) {
char *q;
p += lensess + 1;
if ((q = strpbrk(p, "/?\\"))) {
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(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 &&
Z_STRLEN_P(data) != 0 &&
strstr(Z_STRVAL_P(data), PS(extern_referer_chk)) == NULL
) {
zend_string_release(PS(id));
PS(id) = NULL;
}
}
/* 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' &&
!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 &&
Z_STRLEN_P(data) != 0 &&
strstr(Z_STRVAL_P(data), PS(extern_referer_chk)) == NULL
) {
zend_string_release(PS(id));
PS(id) = NULL;
}
}
@ -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) {
new_id = PS(mod)->s_create_sid(&PS(mod_data));
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)

View 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"

View 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