RFC: Deprecate remains of string evaluated code assertions (#11671)

Link: https://wiki.php.net/rfc/assert-string-eval-cleanup
This commit is contained in:
George Peter Banyard 2023-07-13 15:45:32 +01:00 committed by GitHub
parent 591f3f619e
commit 3d4ff5ae22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 498 additions and 188 deletions

View file

@ -126,6 +126,12 @@ PHP 8.3 UPGRADE NOTES
. The MT_RAND_PHP Mt19937 variant is deprecated.
RFC: https://wiki.php.net/rfc/deprecations_php_8_3#mt_rand_php
- Standard:
. The assert_option() function is now deprecated.
. The ASSERT_ACTIVE, ASSERT_BAIL,ASSERT_CALLBACK, ASSERT_EXCEPTION, and
ASSERT_WARNING constants have been deprecated.
RFC: https://wiki.php.net/rfc/assert-string-eval-cleanup
- SQLite3
. Using exceptions is now preferred, warnings will be removed in the future.
Calling SQLite3::enableExceptions(false) will trigger a depreciation warning
@ -364,6 +370,18 @@ PHP 8.3 UPGRADE NOTES
11. Changes to INI File Handling
========================================
- assert.*
. The assert.* INI settings have been deprecated.
This comprises the following INI settings:
- assert.active
- assert.bail
- assert.callback
- assert.exception
- assert.warning
If the value of the setting is equal to the default value, no deprecation
notice is emitted.
The zend.assertions INI setting should be used instead.
- zend.max_allowed_stack_size
. New INI directive to set the maximum allowed stack size. Possible
values are `0` (detect the process or thread maximum stack size), `-1`

View file

@ -2,16 +2,24 @@
Pretty printing for arrow functions
--INI--
zend.assertions=1
assert.exception=0
--FILE--
<?php
// TODO We're missing parentheses for the direct call
assert((fn() => false)());
assert((fn&(int... $args): ?bool => $args[0])(false));
try {
assert((fn() => false)());
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
try {
assert((fn&(int... $args): ?bool => $args[0])(false));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(fn() => false()) failed in %s on line %d
Warning: assert(): assert(fn&(int ...$args): ?bool => $args[0](false)) failed in %s on line %d
--EXPECT--
assert(): assert(fn() => false()) failed
assert(): assert(fn&(int ...$args): ?bool => $args[0](false)) failed

View file

@ -2,8 +2,6 @@
Bug #70528 (assert() with instanceof adds apostrophes around class name)
--INI--
zend.assertions=1
assert.exception=0
assert.warning=1
--FILE--
<?php
@ -11,13 +9,23 @@ namespace Foo;
class Bar {}
$bar = "Bar";
assert(new \stdClass instanceof $bar);
assert(new \stdClass instanceof Bar);
assert(new \stdClass instanceof \Foo\Bar);
try {
assert(new \stdClass instanceof $bar);
} catch (\AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
try {
assert(new \stdClass instanceof Bar);
} catch (\AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
try {
assert(new \stdClass instanceof \Foo\Bar);
} catch (\AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(new \stdClass() instanceof $bar) failed in %sbug70528.php on line %d
Warning: assert(): assert(new \stdClass() instanceof Bar) failed in %sbug70528.php on line %d
Warning: assert(): assert(new \stdClass() instanceof \Foo\Bar) failed in %sbug70528.php on line %d
--EXPECT--
assert(): assert(new \stdClass() instanceof $bar) failed
assert(): assert(new \stdClass() instanceof Bar) failed
assert(): assert(new \stdClass() instanceof \Foo\Bar) failed

View file

@ -2,9 +2,9 @@
AST pretty-peinter
--INI--
zend.assertions=1
assert.exception=0
--FILE--
<?php
try {
assert(0 && ($a = function () {
global $a, $$b;
static $c, $d = 0;
@ -19,7 +19,11 @@ assert(0 && ($a = function () {
yield 1 => 2;
yield from $x;
}));
} catch (AssertionError $e) {
echo $e->getMessage(), PHP_EOL;
}
try {
assert(0 && ($a = function &(array &$a, ?X $b = null) use ($c,&$d) : ?X {
abstract class A extends B implements C, D {
const X = 12;
@ -64,7 +68,11 @@ assert(0 && ($a = function &(array &$a, ?X $b = null) use ($c,&$d) : ?X {
}
}
}));
} catch (AssertionError $e) {
echo $e->getMessage(), PHP_EOL;
}
try {
assert(0 && ($a = function &(array &$a, X $b = null, int|float $c) use ($c,&$d) : X {
final class A {
final protected function f2() {
@ -96,7 +104,11 @@ L0:
}
}
}));
} catch (AssertionError $e) {
echo $e->getMessage(), PHP_EOL;
}
try {
assert(0 && ($a = function &(?array &$a, X $b = null) use ($c,&$d) : X {
class A {
use T1, T2 {
@ -108,7 +120,11 @@ assert(0 && ($a = function &(?array &$a, X $b = null) use ($c,&$d) : X {
use T3;
}
}));
} catch (AssertionError $e) {
echo $e->getMessage(), PHP_EOL;
}
try {
assert(0 && ($a = function &(array &...$a) {
declare(A=1,B=2);
try {
@ -121,7 +137,11 @@ assert(0 && ($a = function &(array &...$a) {
echo 3;
}
}));
} catch (AssertionError $e) {
echo $e->getMessage(), PHP_EOL;
}
try {
assert(0 && ($a = function (): ?static {
declare(C=1) { echo 1; }
$x = '\'"`$a';
@ -145,10 +165,13 @@ assert(0 && ($a = function (): ?static {
}
if ($a); else;
}));
} catch (AssertionError $e) {
echo $e->getMessage(), PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(0 && ($a = function () {
--EXPECT--
assert(0 && ($a = function () {
global $a;
global $$b;
static $c;
@ -163,9 +186,8 @@ Warning: assert(): assert(0 && ($a = function () {
$y = clone $x;
yield 1 => 2;
yield from $x;
})) failed in %s on line %d
Warning: assert(): assert(0 && ($a = function &(array &$a, ?X $b = null) use($c, &$d): ?X {
}))
assert(0 && ($a = function &(array &$a, ?X $b = null) use($c, &$d): ?X {
abstract class A extends B implements C, D {
public const X = 12;
public const Y = self::X, Z = 'aaa';
@ -208,9 +230,8 @@ Warning: assert(): assert(0 && ($a = function &(array &$a, ?X $b = null) use($c,
}
})) failed in %s on line %d
Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null, int|float $c) use($c, &$d): X {
}))
assert(0 && ($a = function &(array &$a, X $b = null, int|float $c) use($c, &$d): X {
final class A {
protected final function f2() {
if (!$x) {
@ -248,9 +269,8 @@ Warning: assert(): assert(0 && ($a = function &(array &$a, X $b = null, int|floa
}
})) failed in %s on line %d
Warning: assert(): assert(0 && ($a = function &(?array &$a, X $b = null) use($c, &$d): X {
}))
assert(0 && ($a = function &(?array &$a, X $b = null) use($c, &$d): X {
class A {
use T1, T2 {
T1::foo insteadof foo;
@ -261,9 +281,8 @@ Warning: assert(): assert(0 && ($a = function &(?array &$a, X $b = null) use($c,
use T3;
}
})) failed in %s on line %d
Warning: assert(): assert(0 && ($a = function &(array &...$a) {
}))
assert(0 && ($a = function &(array &...$a) {
declare(A = 1, B = 2);
try {
$i++;
@ -274,9 +293,8 @@ Warning: assert(): assert(0 && ($a = function &(array &...$a) {
} finally {
echo 3;
}
})) failed in %s on line %d
Warning: assert(): assert(0 && ($a = function (): ?static {
}))
assert(0 && ($a = function (): ?static {
declare(C = 1) {
echo 1;
}
@ -302,4 +320,4 @@ Warning: assert(): assert(0 && ($a = function (): ?static {
if ($a) {
} else {
}
})) failed in %s on line %d
}))

View file

@ -2,23 +2,24 @@
test enable/disable assertions at runtime (assertions not completely disabled)
--INI--
zend.assertions=0
assert.exception=0
--FILE--
<?php
ini_set("zend.assertions", 0);
var_dump(assert(false));
var_dump(assert(true));
ini_set("zend.assertions", 1);
var_dump(assert(false));
try {
var_dump(assert(false));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
var_dump(assert(true));
ini_set("zend.assertions", -1);
?>
--EXPECTF--
bool(true)
bool(true)
Warning: assert(): assert(false) failed in %sexpect_016.php on line 6
bool(false)
assert(): assert(false) failed
bool(true)
Warning: zend.assertions may be completely enabled or disabled only in php.ini in %sexpect_016.php on line 8
Warning: zend.assertions may be completely enabled or disabled only in php.ini in %s on line %d

View file

@ -2,18 +2,16 @@
test enable/disable assertions at runtime (assertions completely disabled)
--INI--
zend.assertions=-1
assert.exception=0
--FILE--
<?php
ini_set("zend.assertions", 0);
var_dump(assert(false));
var_dump(assert(true));
ini_set("zend.assertions", 0);
ini_set("zend.assertions", 1);
?>
--EXPECTF--
Warning: zend.assertions may be completely enabled or disabled only in php.ini in %sexpect_017.php on line 2
bool(true)
bool(true)
Warning: zend.assertions may be completely enabled or disabled only in php.ini in %sexpect_017.php on line 4
Warning: zend.assertions may be completely enabled or disabled only in php.ini in %sexpect_017.php on line 5

View file

@ -2,7 +2,6 @@
test assertions in namespace
--INI--
zend.assertions=1
assert.exception=0
--FILE--
<?php
namespace Foo;
@ -13,21 +12,25 @@ var_dump(\assert(true));
var_dump(assert(false));
var_dump(assert(true));
ini_set("zend.assertions", 1);
var_dump(\assert(false));
try {
var_dump(\assert(false));
} catch (\AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
var_dump(\assert(true));
var_dump(assert(false));
try {
var_dump(assert(false));
} catch (\AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
var_dump(assert(true));
?>
--EXPECTF--
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
Warning: assert(): assert(false) failed in %sexpect_018.php on line 10
bool(false)
assert(): assert(false) failed
bool(true)
Warning: assert(): assert(false) failed in %sexpect_018.php on line 12
bool(false)
assert(): assert(false) failed
bool(true)

View file

@ -2,7 +2,6 @@
test assertions in namespace (assertions completely disabled)
--INI--
zend.assertions=-1
assert.exception=0
--FILE--
<?php
namespace Foo;

View file

@ -2,16 +2,19 @@
AST pretty-printer
--INI--
zend.assertions=1
assert.exception=0
--FILE--
<?php
try {
assert(0 && ($a = function () {
$var = 'test';
$str = "$var, $var[1], {$var}[], {$var[1]}[], ${var}[], ${var[1]}[]";
}));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(0 && ($a = function () {
--EXPECT--
assert(): assert(0 && ($a = function () {
$var = 'test';
$str = "$var, {$var[1]}, {$var}[], {$var[1]}[], {$var}[], {$var[1]}[]";
})) failed in %sexpect_020.php on line %d
})) failed

View file

@ -0,0 +1,16 @@
--TEST--
Serialization of backtick literal is incorrect
--INI--
zend.assertions=1
--FILE--
<?php
try {
assert(false && `echo -n ""`);
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECT--
assert(): assert(false && `echo -n ""`) failed

View file

@ -2,12 +2,14 @@
ZEND_POW_ASSIGN
--INI--
zend.assertions=1
assert.exception=0
--FILE--
<?php
assert_options(ASSERT_WARNING);
assert(false && ($a **= 2));
try {
assert(false && ($a **= 2));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(false && ($a **= 2)) failed in %s%ezend-pow-assign.php on line %d
--EXPECT--
assert(): assert(false && ($a **= 2)) failed

View file

@ -1,13 +0,0 @@
--TEST--
Serialization of backtick literal is incorrect
--INI--
zend.assertions=1
assert.exception=0
--FILE--
<?php
assert_options(ASSERT_WARNING);
assert(false && `echo -n ""`);
?>
--EXPECTF--
Warning: assert(): assert(false && `echo -n ""`) failed in %s%east_serialize_backtick_literal.php on line %d

View file

@ -2,35 +2,47 @@
Attributes AST can be exported.
--INI--
zend.assertions=1
assert.exception=0
assert.warning=1
--FILE--
<?php
assert(0 && ($a = #[A1] #[A2] function ($a, #[A3(1)] $b) { }));
try {
assert(0 && ($a = #[A1] #[A2] function ($a, #[A3(1)] $b) { }));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn () => 1));
try {
assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn () => 1));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
try {
assert(0 && ($a = new #[A1] class() {
#[A1]#[A2] const FOO = 'foo';
#[A2] public $x;
#[A3] function a() { }
}));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
try {
assert(0 && ($a = function () {
#[A1] class Test1 { }
#[A2] interface Test2 { }
#[A3] trait Test3 { }
}));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(0 && ($a = #[A1] #[A2] function ($a, #[A3(1)] $b) {
})) failed in %s on line %d
Warning: assert(): assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn() => 1)) failed in %s on line %d
Warning: assert(): assert(0 && ($a = new #[A1] class {
--EXPECT--
assert(): assert(0 && ($a = #[A1] #[A2] function ($a, #[A3(1)] $b) {
})) failed
assert(): assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn() => 1)) failed
assert(): assert(0 && ($a = new #[A1] class {
#[A1]
#[A2]
public const FOO = 'foo';
@ -40,9 +52,8 @@ Warning: assert(): assert(0 && ($a = new #[A1] class {
public function a() {
}
})) failed in %s on line %d
Warning: assert(): assert(0 && ($a = function () {
})) failed
assert(): assert(0 && ($a = function () {
#[A1]
class Test1 {
}
@ -55,4 +66,4 @@ Warning: assert(): assert(0 && ($a = function () {
trait Test3 {
}
})) failed in %s on line %d
})) failed

View file

@ -1,17 +1,12 @@
--TEST--
Test exception doesn't cause RSHUTDOWN bypass, variation 0
--INI--
assert.bail=1
assert.exception=1
zend.assertions=1
--FILE--
<?php
define ("XXXXX", 1);
try {
assert(false);
} catch (AssertionError $error) {
echo "Caught\n";
}
assert(false);
?>
--EXPECTHEADERS--

View file

@ -1,10 +1,11 @@
--TEST--
Pretty printing for match expression
--INI--
assert.exception=0
zend.assertions=1
--FILE--
<?php
try {
assert((function () {
match ('foo') {
'foo', 'bar' => false,
@ -12,13 +13,16 @@ assert((function () {
default => 'b',
};
})());
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(function () {
assert(): assert(function () {
match ('foo') {
'foo', 'bar' => false,
'baz' => 'a',
default => 'b',
};
}()) failed in %s on line %d
}()) failed

View file

@ -2,9 +2,9 @@
AST pretty-printer
--INI--
zend.assertions=1
assert.exception=0
--FILE--
<?php
try {
assert(0 && ($a = function (int $a, ?int $b, int $c = null): ?int {
$x = new class {
public $a;
@ -12,12 +12,15 @@ assert(0 && ($a = function (int $a, ?int $b, int $c = null): ?int {
public ?int $c;
};
}));
} catch (AssertionError $e) {
echo 'assert(): ', $e->getMessage(), ' failed', PHP_EOL;
}
?>
--EXPECTF--
Warning: assert(): assert(0 && ($a = function (int $a, ?int $b, int $c = null): ?int {
--EXPECT--
assert(): assert(0 && ($a = function (int $a, ?int $b, int $c = null): ?int {
$x = new class {
public $a;
public int $b;
public ?int $c;
};
})) failed in %stypes_in_ast.php on line 2
})) failed

View file

@ -36,6 +36,15 @@ ZEND_DECLARE_MODULE_GLOBALS(assert)
PHPAPI zend_class_entry *assertion_error_ce;
/* Hack to pass a custom stage for the our OnModify handler so that a deprecation warning does not get emitted
* when an option is modified via assert_option() function */
#define ZEND_INI_STAGE_ASSERT_OPTIONS (1<<6)
static inline bool php_must_emit_ini_deprecation(int stage)
{
return stage != ZEND_INI_STAGE_DEACTIVATE && stage != ZEND_INI_STAGE_SHUTDOWN && stage != ZEND_INI_STAGE_ASSERT_OPTIONS;
}
static PHP_INI_MH(OnChangeCallback) /* {{{ */
{
if (EG(current_execute_data)) {
@ -44,6 +53,9 @@ static PHP_INI_MH(OnChangeCallback) /* {{{ */
ZVAL_UNDEF(&ASSERTG(callback));
}
if (new_value && (Z_TYPE(ASSERTG(callback)) != IS_UNDEF || ZSTR_LEN(new_value))) {
if (php_must_emit_ini_deprecation(stage)) {
php_error_docref(NULL, E_DEPRECATED, "assert.callback INI setting is deprecated");
}
ZVAL_STR_COPY(&ASSERTG(callback), new_value);
}
} else {
@ -51,6 +63,9 @@ static PHP_INI_MH(OnChangeCallback) /* {{{ */
pefree(ASSERTG(cb), 1);
}
if (new_value && ZSTR_LEN(new_value)) {
if (php_must_emit_ini_deprecation(stage)) {
php_error_docref(NULL, E_DEPRECATED, "assert.callback INI setting is deprecated");
}
ASSERTG(cb) = pemalloc(ZSTR_LEN(new_value) + 1, 1);
memcpy(ASSERTG(cb), ZSTR_VAL(new_value), ZSTR_LEN(new_value));
ASSERTG(cb)[ZSTR_LEN(new_value)] = '\0';
@ -62,12 +77,54 @@ static PHP_INI_MH(OnChangeCallback) /* {{{ */
}
/* }}} */
static PHP_INI_MH(OnUpdateActiveBool)
{
bool *p = (bool *) ZEND_INI_GET_ADDR();
*p = zend_ini_parse_bool(new_value);
if (php_must_emit_ini_deprecation(stage) && !*p) {
php_error_docref(NULL, E_DEPRECATED, "assert.active INI setting is deprecated");
}
return SUCCESS;
}
static PHP_INI_MH(OnUpdateBailBool)
{
bool *p = (bool *) ZEND_INI_GET_ADDR();
*p = zend_ini_parse_bool(new_value);
if (php_must_emit_ini_deprecation(stage) && *p) {
php_error_docref(NULL, E_DEPRECATED, "assert.bail INI setting is deprecated");
}
return SUCCESS;
}
static PHP_INI_MH(OnUpdateExceptionBool)
{
bool *p = (bool *) ZEND_INI_GET_ADDR();
*p = zend_ini_parse_bool(new_value);
if (php_must_emit_ini_deprecation(stage) && !*p) {
php_error_docref(NULL, E_DEPRECATED, "assert.exception INI setting is deprecated");
}
return SUCCESS;
}
static PHP_INI_MH(OnUpdateWarningBool)
{
bool *p = (bool *) ZEND_INI_GET_ADDR();
*p = zend_ini_parse_bool(new_value);
if (php_must_emit_ini_deprecation(stage) && !*p) {
php_error_docref(NULL, E_DEPRECATED, "assert.warning INI setting is deprecated");
}
return SUCCESS;
}
PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN("assert.active", "1", PHP_INI_ALL, OnUpdateBool, active, zend_assert_globals, assert_globals)
STD_PHP_INI_BOOLEAN("assert.bail", "0", PHP_INI_ALL, OnUpdateBool, bail, zend_assert_globals, assert_globals)
STD_PHP_INI_BOOLEAN("assert.warning", "1", PHP_INI_ALL, OnUpdateBool, warning, zend_assert_globals, assert_globals)
PHP_INI_ENTRY("assert.callback", NULL, PHP_INI_ALL, OnChangeCallback)
STD_PHP_INI_BOOLEAN("assert.exception", "1", PHP_INI_ALL, OnUpdateBool, exception, zend_assert_globals, assert_globals)
STD_PHP_INI_BOOLEAN("assert.active", "1", PHP_INI_ALL, OnUpdateActiveBool, active, zend_assert_globals, assert_globals)
STD_PHP_INI_BOOLEAN("assert.bail", "0", PHP_INI_ALL, OnUpdateBailBool, bail, zend_assert_globals, assert_globals)
STD_PHP_INI_BOOLEAN("assert.warning", "1", PHP_INI_ALL, OnUpdateWarningBool, warning, zend_assert_globals, assert_globals)
PHP_INI_ENTRY("assert.callback", NULL, PHP_INI_ALL, OnChangeCallback)
STD_PHP_INI_BOOLEAN("assert.exception", "1", PHP_INI_ALL, OnUpdateExceptionBool, exception, zend_assert_globals, assert_globals)
PHP_INI_END()
static void php_assert_init_globals(zend_assert_globals *assert_globals_p) /* {{{ */
@ -214,7 +271,7 @@ PHP_FUNCTION(assert_options)
}
key = ZSTR_INIT_LITERAL("assert.active", 0);
zend_alter_ini_entry_ex(key, value_str, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0);
zend_alter_ini_entry_ex(key, value_str, PHP_INI_USER, ZEND_INI_STAGE_ASSERT_OPTIONS, 0);
zend_string_release_ex(key, 0);
zend_string_release_ex(value_str, 0);
}
@ -230,7 +287,7 @@ PHP_FUNCTION(assert_options)
}
key = ZSTR_INIT_LITERAL("assert.bail", 0);
zend_alter_ini_entry_ex(key, value_str, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0);
zend_alter_ini_entry_ex(key, value_str, PHP_INI_USER, ZEND_INI_STAGE_ASSERT_OPTIONS, 0);
zend_string_release_ex(key, 0);
zend_string_release_ex(value_str, 0);
}
@ -246,7 +303,7 @@ PHP_FUNCTION(assert_options)
}
key = ZSTR_INIT_LITERAL("assert.warning", 0);
zend_alter_ini_entry_ex(key, value_str, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0);
zend_alter_ini_entry_ex(key, value_str, PHP_INI_USER, ZEND_INI_STAGE_ASSERT_OPTIONS, 0);
zend_string_release_ex(key, 0);
zend_string_release_ex(value_str, 0);
}
@ -281,7 +338,7 @@ PHP_FUNCTION(assert_options)
}
key = ZSTR_INIT_LITERAL("assert.exception", 0);
zend_alter_ini_entry_ex(key, val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0);
zend_alter_ini_entry_ex(key, val, PHP_INI_USER, ZEND_INI_STAGE_ASSERT_OPTIONS, 0);
zend_string_release_ex(val, 0);
zend_string_release_ex(key, 0);
}

View file

@ -124,26 +124,31 @@ const ARRAY_FILTER_USE_KEY = UNKNOWN;
/**
* @var int
* @deprecated
* @cvalue PHP_ASSERT_ACTIVE
*/
const ASSERT_ACTIVE = UNKNOWN;
/**
* @var int
* @deprecated
* @cvalue PHP_ASSERT_CALLBACK
*/
const ASSERT_CALLBACK = UNKNOWN;
/**
* @var int
* @deprecated
* @cvalue PHP_ASSERT_BAIL
*/
const ASSERT_BAIL = UNKNOWN;
/**
* @var int
* @deprecated
* @cvalue PHP_ASSERT_WARNING
*/
const ASSERT_WARNING = UNKNOWN;
/**
* @var int
* @deprecated
* @cvalue PHP_ASSERT_EXCEPTION
*/
const ASSERT_EXCEPTION = UNKNOWN;
@ -2264,6 +2269,7 @@ function get_html_translation_table(int $table = HTML_SPECIALCHARS, int $flags =
function assert(mixed $assertion, Throwable|string|null $description = null): bool {}
/** @deprecated */
function assert_options(int $option, mixed $value = UNKNOWN): mixed {}
/* string.c */

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: b0767630614e040866bd7ffdaf50dd31298a64f3 */
* Stub hash: a15bbbd1d29dfd674dd2174b3be5678a0832116a */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
@ -3061,7 +3061,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(htmlentities, arginfo_htmlentities)
ZEND_FE(get_html_translation_table, arginfo_get_html_translation_table)
ZEND_FE(assert, arginfo_assert)
ZEND_FE(assert_options, arginfo_assert_options)
ZEND_DEP_FE(assert_options, arginfo_assert_options)
ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(bin2hex, arginfo_bin2hex)
ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(hex2bin, arginfo_hex2bin)
ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(strspn, arginfo_strspn)
@ -3500,11 +3500,11 @@ static void register_basic_functions_symbols(int module_number)
REGISTER_LONG_CONSTANT("COUNT_RECURSIVE", PHP_COUNT_RECURSIVE, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_BOTH", ARRAY_FILTER_USE_BOTH, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_KEY", ARRAY_FILTER_USE_KEY, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ASSERT_ACTIVE", PHP_ASSERT_ACTIVE, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ASSERT_CALLBACK", PHP_ASSERT_CALLBACK, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ASSERT_BAIL", PHP_ASSERT_BAIL, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ASSERT_WARNING", PHP_ASSERT_WARNING, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ASSERT_EXCEPTION", PHP_ASSERT_EXCEPTION, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("ASSERT_ACTIVE", PHP_ASSERT_ACTIVE, CONST_PERSISTENT | CONST_DEPRECATED);
REGISTER_LONG_CONSTANT("ASSERT_CALLBACK", PHP_ASSERT_CALLBACK, CONST_PERSISTENT | CONST_DEPRECATED);
REGISTER_LONG_CONSTANT("ASSERT_BAIL", PHP_ASSERT_BAIL, CONST_PERSISTENT | CONST_DEPRECATED);
REGISTER_LONG_CONSTANT("ASSERT_WARNING", PHP_ASSERT_WARNING, CONST_PERSISTENT | CONST_DEPRECATED);
REGISTER_LONG_CONSTANT("ASSERT_EXCEPTION", PHP_ASSERT_EXCEPTION, CONST_PERSISTENT | CONST_DEPRECATED);
REGISTER_LONG_CONSTANT("CONNECTION_ABORTED", PHP_CONNECTION_ABORTED, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CONNECTION_NORMAL", PHP_CONNECTION_NORMAL, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CONNECTION_TIMEOUT", PHP_CONNECTION_TIMEOUT, CONST_PERSISTENT);

View file

@ -36,7 +36,30 @@ $obj = new a();
assert_options(ASSERT_CALLBACK,array(&$obj,"assert"));
assert($a != 0);
?>
--EXPECT--
--EXPECTF--
Deprecated: PHP Startup: assert.active INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
assertion failed 21,"assert($a != 0)"
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
class assertion failed 24,"assert($a != 0)"
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
class assertion failed 28,"assert($a != 0)"

View file

@ -31,6 +31,23 @@ ini_set("assert.callback", "b");
assert($a != 0);
?>
--EXPECT--
--EXPECTF--
Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
assertion failed - a - 18,"assert($a != 0)"
Deprecated: ini_set(): assert.callback INI setting is deprecated in %s on line %d
assertion failed - b - 22,"assert($a != 0)"

View file

@ -27,6 +27,20 @@ echo "not reached\n";
?>
--EXPECTF--
Warning: assert(): assert(0) failed in %s on line %d
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Warning: assert(): assert(0) failed in %s on line %d
Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Warning: assert(): assert(0) failed in %s on line %d

View file

@ -16,7 +16,12 @@ function f1()
var_dump($r2 = assert(0));
var_dump($r2 = assert(1));
?>
--EXPECT--
--EXPECTF--
Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
f1 called
bool(false)
bool(true)

View file

@ -15,6 +15,11 @@ function f1()
var_dump($r2=assert(0));
var_dump($r2=assert(1));
?>
--EXPECT--
--EXPECTF--
Deprecated: PHP Startup: assert.active INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
bool(true)
bool(true)

View file

@ -26,12 +26,27 @@ var_dump($n= assert_options(ASSERT_CALLBACK));
assert(0);
?>
--EXPECTF--
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(2) "f1"
f1 called
Warning: assert(): assert(0) failed in %s on line 13
Warning: assert(): assert(0) failed in %s on line %d
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(2) "f1"
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(2) "f2"
f2 called
Warning: assert(): assert(0) failed in %s on line 17
Warning: assert(): assert(0) failed in %s on line %d

View file

@ -19,6 +19,13 @@ var_dump($r2=assert(0 != 0));
echo "If this is printed BAIL hasn't worked";
?>
--EXPECTF--
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
int(0)
f1 called

View file

@ -21,10 +21,31 @@ echo "Initial values: ini.get(\"assert.warning\") => [".ini_get("assert.warning"
echo "Initial values: ini.get(\"assert.bail\") => [".ini_get("assert.bail")."]\n";
echo "Initial values: ini.get(\"assert.callback\") => [".ini_get("assert.callback")."]\n\n";
?>
--EXPECT--
--EXPECTF--
Deprecated: PHP Startup: assert.active INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Initial values: assert_options(ASSERT_ACTIVE) => [0]
Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Initial values: assert_options(ASSERT_WARNING) => [0]
Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Initial values: assert_options(ASSERT_BAIL) => [0]
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Initial values: assert_options(ASSERT_CALLBACK) => [f1]
Initial values: ini.get("assert.active") => [0]
Initial values: ini.get("assert.warning") => [0]

View file

@ -22,10 +22,23 @@ var_dump($r2=assert(0 == 0));
var_dump($rao=assert_options(ASSERT_WARNING, 0));
?>
--EXPECTF--
Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
int(0)
f1 called
Warning: assert(): assert(0 != 0) failed in %s on line %d
bool(false)
bool(true)
Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
int(1)

View file

@ -31,10 +31,25 @@ try {
}
?>
--EXPECT--
--EXPECTF--
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(2) "f1"
foo
assert(false)
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
NULL
assert(false)

View file

@ -11,6 +11,11 @@ assert_options(ASSERT_CALLBACK, function () { echo "Hello World!\n"; });
assert(0);
?>
--EXPECTF--
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Hello World!
Warning: assert(): assert(0) failed in %s on line %d

View file

@ -31,5 +31,8 @@ try {
} catch (Throwable) {}
?>
DONE
--EXPECT--
--EXPECTF--
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
DONE

View file

@ -21,6 +21,13 @@ var_dump($r2 = assert(0 != 0));
echo "If this is printed BAIL hasn't worked";
?>
--EXPECTF--
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
int(0)
f1 called

View file

@ -9,5 +9,6 @@ try {
echo $e->getMessage();
}
?>
--EXPECT--
--EXPECTF--
Deprecated: Function assert_options() is deprecated in %s on line %d
assert_options(): Argument #1 ($option) must be an ASSERT_* constant

View file

@ -9,6 +9,7 @@ var_dump(assert(true));
var_dump(assert(false));
?>
--EXPECTF--
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
bool(true)
Warning: assert(): assert(false) failed in %s on line %d

View file

@ -32,14 +32,14 @@ echo "Initial values: ini.get(\"assert.callback\") => [".ini_get("assert.callbac
var_dump($r2=assert(0 != 0));
echo"\n";
echo "Change callback function using ini.set and test return value \n";
echo "Change callback function using ini.set and test return value\n";
var_dump($rv = ini_set("assert.callback","f2"));
echo "assert_options(ASSERT_CALLBACK) => [".assert_options(ASSERT_CALLBACK)."]\n";
echo "ini.get(\"assert.callback\") => [".ini_get("assert.callback")."]\n";
var_dump($r2=assert(0 != 0));
echo"\n";
echo "Change callback function using assert_options and test return value \n";
echo "Change callback function using assert_options and test return value\n";
var_dump($rv=assert_options(ASSERT_CALLBACK, "f3"));
echo "assert_options(ASSERT_CALLBACK) => [".assert_options(ASSERT_CALLBACK)."]\n";
echo "ini.get(\"assert.callback\") => [".ini_get("assert.callback")."]\n";
@ -58,14 +58,14 @@ try {
}
echo"\n";
echo "Reset callback options to use a class method \n";
echo "Reset callback options to use a class method\n";
var_dump($rc = assert_options(ASSERT_CALLBACK,array("c1","assert")));
var_dump($rao=assert_options(ASSERT_CALLBACK));
echo "ini.get(\"assert.callback\") => [".ini_get("assert.callback")."]\n\n";
var_dump($r2=assert(0 != 0));
echo"\n";
echo "Reset callback options to use an object method \n";
echo "Reset callback options to use an object method\n";
$o = new c1();
var_dump($rc=assert_options(ASSERT_CALLBACK,array(&$o,"assert")));
var_dump($rao=assert_options(ASSERT_CALLBACK));
@ -78,34 +78,73 @@ assert_options(ASSERT_CALLBACK, 3.141);
var_dump($rao = assert_options(ASSERT_CALLBACK));
?>
--EXPECT--
--EXPECTF--
Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Initial values: assert_options(ASSERT_CALLBACK) => [f1]
Initial values: ini.get("assert.callback") => [f1]
f1 called
bool(false)
Change callback function using ini.set and test return value
Change callback function using ini.set and test return value
Deprecated: ini_set(): assert.callback INI setting is deprecated in %s on line %d
string(2) "f1"
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
assert_options(ASSERT_CALLBACK) => [f2]
ini.get("assert.callback") => [f2]
f2 called
bool(false)
Change callback function using assert_options and test return value
Change callback function using assert_options and test return value
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(2) "f2"
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
assert_options(ASSERT_CALLBACK) => [f3]
ini.get("assert.callback") => [f2]
f3 called
bool(false)
Reset the name of the callback routine to a class method
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(2) "f3"
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
assert_options(ASSERT_CALLBACK) => [c1]
ini.get("assert.callback") => [f2]
Invalid callback c1, function "c1" not found or invalid function name
Reset callback options to use a class method
Reset callback options to use a class method
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(2) "c1"
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
array(2) {
[0]=>
string(2) "c1"
@ -117,13 +156,21 @@ ini.get("assert.callback") => [f2]
Class assertion failed 56, "assert(0 != 0)"
bool(false)
Reset callback options to use an object method
Reset callback options to use an object method
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
array(2) {
[0]=>
string(2) "c1"
[1]=>
string(6) "assert"
}
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
array(2) {
[0]=>
&object(c1)#2 (0) {
@ -137,4 +184,12 @@ Class assertion failed 64, "assert(0 != 0)"
bool(false)
Set callback to something silly
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
float(3.141)

View file

@ -10,4 +10,6 @@ assert.exception=0
assert(0, null);
?>
--EXPECTF--
Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0
Warning: assert(): Assertion failed in %s on line %d

View file

@ -12,6 +12,9 @@ assert(false, 'Dynamic message: ' . $x);
?>
--EXPECTF--
Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d
Deprecated: Function assert_options() is deprecated in %s on line %d
string(18) "Dynamic message: x"
Fatal error: Uncaught AssertionError: Dynamic message: x in %s:%d

View file

@ -1601,33 +1601,14 @@ session.sid_bits_per_character = 5
; -1: Do not compile at all
; 0: Jump over assertion at run-time
; 1: Execute assertions
; Changing from or to a negative value is only possible in php.ini! (For turning assertions on and off at run-time, see assert.active, when zend.assertions = 1)
; Changing from or to a negative value is only possible in php.ini!
; (For turning assertions on and off at run-time, toggle zend.assertions between the values 1 and 0)
; Default Value: 1
; Development Value: 1
; Production Value: -1
; https://php.net/zend.assertions
zend.assertions = 1
; Assert(expr); active by default.
; https://php.net/assert.active
;assert.active = On
; Throw an AssertionError on failed assertions
; https://php.net/assert.exception
;assert.exception = On
; Issue a PHP warning for each failed assertion. (Overridden by assert.exception if active)
; https://php.net/assert.warning
;assert.warning = On
; Don't bail out by default.
; https://php.net/assert.bail
;assert.bail = Off
; User-function to be called if an assertion fails.
; https://php.net/assert.callback
;assert.callback = 0
[COM]
; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs
; https://php.net/com.typelib-file

View file

@ -1603,33 +1603,14 @@ session.sid_bits_per_character = 5
; -1: Do not compile at all
; 0: Jump over assertion at run-time
; 1: Execute assertions
; Changing from or to a negative value is only possible in php.ini! (For turning assertions on and off at run-time, see assert.active, when zend.assertions = 1)
; Changing from or to a negative value is only possible in php.ini!
; (For turning assertions on and off at run-time, toggle zend.assertions between the values 1 and 0)
; Default Value: 1
; Development Value: 1
; Production Value: -1
; https://php.net/zend.assertions
zend.assertions = -1
; Assert(expr); active by default.
; https://php.net/assert.active
;assert.active = On
; Throw an AssertionError on failed assertions
; https://php.net/assert.exception
;assert.exception = On
; Issue a PHP warning for each failed assertion. (Overridden by assert.exception if active)
; https://php.net/assert.warning
;assert.warning = On
; Don't bail out by default.
; https://php.net/assert.bail
;assert.bail = Off
; User-function to be called if an assertion fails.
; https://php.net/assert.callback
;assert.callback = 0
[COM]
; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs
; https://php.net/com.typelib-file

View file

@ -2,7 +2,6 @@
zend_throw_exception with NULL message
--FILE--
<?php
assert_options(ASSERT_EXCEPTION, true);
try {
$assert = 'assert';
$assert(false);