php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #73875 assert() evaluated despite runtime assert_options(ASSERT_ACTIVE, 0);
Submitted: 2017-01-05 18:31 UTC Modified: 2017-10-24 16:44 UTC
From: vedad at kajtaz dot net Assigned:
Status: Open Package: Scripting Engine problem
PHP Version: 7.0.14 OS: FreeBSD 10.1
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-01-05 18:31 UTC] vedad at kajtaz dot net
Description:
------------
Expressions in assert() are evaluated despite setting assert_options(ASSERT_ACTIVE, 0) at runtime.

I understand one should use zend.assertions in PHP 7+, yet IMHO this is either a documentation bug, or a misbehavior.

Test script:
---------------
echo 'PHP VERSION '.PHP_VERSION.' running `'.PHP_SAPI.'` sapi.'.PHP_EOL;

echo 'Initial settings:'.PHP_EOL;
echo 'zend.assertions: '.ini_get('zend.assertions').PHP_EOL;
echo 'assert.active: '.ini_get('assert.active').PHP_EOL;

assert_options(ASSERT_ACTIVE, 0);

echo 'After altering settings:'.PHP_EOL;
echo 'zend.assertions: '.ini_get('zend.assertions').PHP_EOL;
echo 'assert.active: '.ini_get('assert.active').PHP_EOL;

$assert = false;
assert($assert = true);

if($assert)
	echo 'Code in assert() was evaluated'.PHP_EOL;
else
	echo 'Code in assert() was NOT evaluated'.PHP_EOL;


Expected result:
----------------
PHP VERSION 7.0.14 running `cli` sapi.
Initial settings:
zend.assertions: 1
assert.active: 1
After altering settings:
zend.assertions: 1
assert.active: 0
Code in assert() was NOT evaluated


Actual result:
--------------
PHP VERSION 7.0.14 running `cli` sapi.
Initial settings:
zend.assertions: 1
assert.active: 1
After altering settings:
zend.assertions: 1
assert.active: 0
Code in assert() was evaluated


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-01-06 13:28 UTC] vedad at kajtaz dot net
Actually, setting zend.assertions to 0 produces the same effect - expression in assert is still evaluated.

echo 'PHP VERSION '.PHP_VERSION.' running `'.PHP_SAPI.'` sapi.'.PHP_EOL;

echo 'Initial settings:'.PHP_EOL;
echo 'zend.assertions: '.ini_get('zend.assertions').PHP_EOL;
echo 'assert.active: '.ini_get('assert.active').PHP_EOL;

ini_set('zend.assertions', '0');
assert_options(ASSERT_ACTIVE, 0);

echo 'After altering settings:'.PHP_EOL;
echo 'zend.assertions: '.ini_get('zend.assertions').PHP_EOL;
echo 'assert.active: '.ini_get('assert.active').PHP_EOL;


$assert = false;
assert($assert = true);

if($assert)
	echo 'Code in assert() was evaluated'.PHP_EOL;
else
	echo 'Code in assert() was NOT evaluated'.PHP_EOL;
 [2017-01-06 14:17 UTC] fernando at null-life dot com
> assert($assert = true);

Shouldn't this line be 

> assert('$assert = true');

After changing it I get the expected result:

PHP VERSION 7.0.13 running `cli` sapi.
Initial settings:
zend.assertions: 1
assert.active: 1
After altering settings:
zend.assertions: 1
assert.active: 0
Code in assert() was NOT evaluated
 [2017-01-06 14:32 UTC] vedad at kajtaz dot net
Expressions are allowed in assertions since PHP 7.0:

> 7.0.0	assert() is now a language construct and not a function. assertion() can now be an expression.

That being said, it is either undocumented or plain wrong that the expression be evaluated despite asserts being disabled.
 [2017-01-06 22:56 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2017-01-06 22:56 UTC] cmb@php.net
> Actually, setting zend.assertions to 0 produces the same effect
> - expression in assert is still evaluated.

That would be a bug, but I can't reproduce this, see
<https://3v4l.org/EYrTO>. Please double-check.

Otherwise there may be the need to improve the documentation.
Actually, assert.active=0 is not supposed to suppress the
evaluation of the assertion parameter (unless it's a string), but
rather to ignore the result of the evalutation. This works as
expected as long as the assertion expression doesn't have any
side-effects (and usually you don't want side-effects in
assertions, anyway).

> assertion() can now be an expression.

Indeed, this changelog info is wrong. An expression was also
allowed in former versions, but it was always evaluated, as there
has been no zend.assertions (think of the PHP 5 behavior being
like zend.assertions=1).
 [2017-01-06 23:42 UTC] vedad at kajtaz dot net
>> Actually, setting zend.assertions to 0 produces the same effect
>> - expression in assert is still evaluated.

> That would be a bug, but I can't reproduce this, see
> <https://3v4l.org/EYrTO>. Please double-check.


Indeed, my result seems to have been due to the 'uopz' extension. Disabling uopz produces the correct result. I guess I now need to file a bug for uopz.


> Actually, assert.active=0 is not supposed to suppress the
> evaluation of the assertion parameter (unless it's a string), but
> rather to ignore the result of the evalutation. This works as
> expected as long as the assertion expression doesn't have any
> side-effects (and usually you don't want side-effects in
> assertions, anyway).

The point is that both the "assert.active" ini setting documentation, and the assert_options() documentation explicitly state that they "enable" (or, implicitly, disable) evaluation. I believe this makes more sense than the subtle string/non-string discrepancy (though you're right that assertions are not meant to have side effects).
 [2017-01-12 00:00 UTC] cmb@php.net
-Type: Bug +Type: Documentation Problem -Assigned To: +Assigned To: cmb
 [2017-01-12 00:00 UTC] cmb@php.net
> Indeed, my result seems to have been due to the 'uopz'
> extension. Disabling uopz produces the correct result. I guess I
> now need to file a bug for uopz.

That appears to be in order. :-)

> The point is that both the "assert.active" ini setting
> documentation, and the assert_options() documentation explicitly
> state that they "enable" (or, implicitly, disable) evaluation. I
> believe this makes more sense than the subtle string/non-string
> discrepancy […]

PHP 5 has only security support now[1], and the new
zend.assertions setting has been explicitly designed for full
backward compatibility[2], so I'm changing to doc bug.

[1] <http://php.net/supported-versions.php>
[2] <https://wiki.php.net/rfc/expectations#unaffected_php_functionality>
 [2017-01-13 14:41 UTC] vedad at kajtaz dot net
Hi cmb,

I somehow disagree with the backward-compatibility argument. assert() with non-string expressions was not available prior to PHP 7.0, hence IMHO bc does not apply here. And if it did, I would expect expressions of any kind not to be evaluated, after all they were not in PHP < 7.

Is there any chance that this be actually fixed, rather than updating the documentation?

Thanks,
Kind regards
 [2017-01-13 15:02 UTC] cmb@php.net
> assert() with non-string expressions was not available prior to
> PHP 7.0, […]

assert() with general expressions has been available as of PHP 4.3
at least, see <https://3v4l.org/8f8gd>.

> Is there any chance that this be actually fixed, rather than
> updating the documentation?

As for me, this is a documention issue only, but others may think
otherwise about this, so I suggest you write to
internals@lists.php.net.
 [2017-10-24 05:26 UTC] kalle@php.net
-Status: Verified +Status: Assigned
 [2017-10-24 16:44 UTC] cmb@php.net
-Assigned To: cmb +Assigned To:
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Thu Jul 19 19:01:25 2018 UTC