Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw on error declare #2

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
If throw_on_error declare statement is explicitly turned off do not promote warning
--FILE--
<?php
declare(throw_on_error=0);

echo $undef;

--EXPECTF--
Warning: Undefined variable $undef in %s on line %d
30 changes: 30 additions & 0 deletions Zend/tests/throw_on_error/declare_on_must_promote_warning.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
throw_on_error declare statement promote warning
--FILE--
<?php
declare(throw_on_error=1);

try {
echo $undef;
} catch (\Exception $e) {
var_dump($e);
}

--EXPECTF--
object(Exception)#1 (7) {
["message":protected]=>
string(25) "Undefined variable $undef"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(2)
["file":protected]=>
string(%d) "%s"
["line":protected]=>
int(5)
["trace":"Exception":private]=>
array(0) {
}
["previous":"Exception":private]=>
NULL
}
20 changes: 20 additions & 0 deletions Zend/tests/throw_on_error/declare_statement_isolated.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
Test throw_on_error declare statement is isolated to file
--FILE--
<?php
include 'fixture/no_declare.inc';

try {
include 'fixture/declare_on.inc';
} catch (\Exception $e) {
echo "Warning caught\n";
}
include 'fixture/declare_off.inc';
?>
DONE
--EXPECTF--
Warning: Undefined variable $undef in %sno_declare.inc on line 2
Warning caught

Warning: Undefined variable $undef in %sdeclare_off.inc on line 4
DONE
20 changes: 20 additions & 0 deletions Zend/tests/throw_on_error/exception_or_warning-docref_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
php_exception_or_warning_docref test when declare enabled
--SKIPIF--
<?php
if (!class_exists('_ZendTestClass')) die('skip zend_test extension required');
?>
--FILE--
<?php
declare(throw_on_error=1);

try {
zend_throw_on_error_declare_exception_or_warning();
} catch (\Exception $e) {
echo $e->getMessage() . \PHP_EOL;
}

echo "OK";
--EXPECT--
Context dependent
OK
16 changes: 16 additions & 0 deletions Zend/tests/throw_on_error/exception_or_warning-docref_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
php_exception_or_warning_docref test when declare explicitly disable
--SKIPIF--
<?php
if (!class_exists('_ZendTestClass')) die('skip zend_test extension required');
?>
--FILE--
<?php
declare(throw_on_error=0);

zend_throw_on_error_declare_exception_or_warning();

echo "OK";
--EXPECTF--
Warning: zend_throw_on_error_declare_exception_or_warning(): Context dependent in %s on line %d
OK
15 changes: 15 additions & 0 deletions Zend/tests/throw_on_error/exception_or_warning-docref_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
php_exception_or_warning_docref test when declare implicitly disable
--SKIPIF--
<?php
if (!class_exists('_ZendTestClass')) die('skip zend_test extension required');
?>
--FILE--
<?php

zend_throw_on_error_declare_exception_or_warning();

echo "OK";
--EXPECTF--
Warning: zend_throw_on_error_declare_exception_or_warning(): Context dependent in %s on line %d
OK
4 changes: 4 additions & 0 deletions Zend/tests/throw_on_error/fixture/declare_off.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
declare(throw_on_error=0);

echo $undef;
4 changes: 4 additions & 0 deletions Zend/tests/throw_on_error/fixture/declare_on.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
declare(throw_on_error=1);

echo $undef;
2 changes: 2 additions & 0 deletions Zend/tests/throw_on_error/fixture/no_declare.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
echo $undef;
30 changes: 30 additions & 0 deletions Zend/tests/throw_on_error/ignore_error_reporting.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
Promoted warning by throw_on_error must ignore error_reporting setting
--FILE--
<?php
declare(throw_on_error=1);
ini_set("error_reporting", 0);
try {
echo $undef;
} catch(Exception $e) {
var_dump($e);
}

--EXPECTF--
object(Exception)#1 (7) {
["message":protected]=>
string(25) "Undefined variable $undef"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(2)
["file":protected]=>
string(%d) "%s"
["line":protected]=>
int(5)
["trace":"Exception":private]=>
array(0) {
}
["previous":"Exception":private]=>
NULL
}
30 changes: 30 additions & 0 deletions Zend/tests/throw_on_error/ignore_suppress_operator.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
Promoted warning by throw_on_error must ignore @ operator
--FILE--
<?php
declare(throw_on_error=1);

try {
echo @$undef;
} catch (\Exception $e) {
var_dump($e);
}

--EXPECTF--
object(Exception)#1 (7) {
["message":protected]=>
string(25) "Undefined variable $undef"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(2)
["file":protected]=>
string(%d) "%s"
["line":protected]=>
int(5)
["trace":"Exception":private]=>
array(0) {
}
["previous":"Exception":private]=>
NULL
}
17 changes: 17 additions & 0 deletions Zend/tests/throw_on_error/no_declare_must_not_promote_warning.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
If throw_on_error declare statement is missing do not promote warning
--FILE--
<?php

echo $undef;

function foo() {
echo $undef;
}

foo();

--EXPECTF--
Warning: Undefined variable $undef in %s on line %d

Warning: Undefined variable $undef in %s on line %d
10 changes: 10 additions & 0 deletions Zend/tests/throw_on_error/play_nice_with_strict_types_after.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
throw_on_error declare statement with strict_types declare after
--FILE--
<?php
declare(throw_on_error=1);
declare(strict_types=1);

echo "OK";
--EXPECT--
OK
10 changes: 10 additions & 0 deletions Zend/tests/throw_on_error/play_nice_with_strict_types_before.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
throw_on_error declare statement with strict_types declare before
--FILE--
<?php
declare(strict_types=1);
declare(throw_on_error=1);

echo "OK";
--EXPECT--
OK
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
--TEST--
throw_on_error declare statement must promote warning emit in internal function
--FILE--
<?php
declare(throw_on_error=1);

try {
file_get_contents('not_found.txt');
} catch (\Exception $e) {
var_dump($e);
}

--EXPECTF--
object(Exception)#1 (7) {
["message":protected]=>
string(82) "file_get_contents(not_found.txt): Failed to open stream: No such file or directory"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(2)
["file":protected]=>
string(%d) "%s"
["line":protected]=>
int(5)
["trace":"Exception":private]=>
array(1) {
[0]=>
array(4) {
["file"]=>
string(%d) "%s"
["line"]=>
int(5)
["function"]=>
string(17) "file_get_contents"
["args"]=>
array(1) {
[0]=>
string(13) "not_found.txt"
}
}
}
["previous":"Exception":private]=>
NULL
}
46 changes: 46 additions & 0 deletions Zend/tests/throw_on_error/promote_warning_in_user_function.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
throw_on_error declare statement must promote warning emit in user defined function
--FILE--
<?php
declare(throw_on_error=1);

function foo() {
echo $undef;
}

try {
foo();
} catch (\Exception $e) {
var_dump($e);
}

--EXPECTF--
object(Exception)#1 (7) {
["message":protected]=>
string(25) "Undefined variable $undef"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(2)
["file":protected]=>
string(%d) "%s"
["line":protected]=>
int(5)
["trace":"Exception":private]=>
array(1) {
[0]=>
array(4) {
["file"]=>
string(%d) "%s"
["line"]=>
int(9)
["function"]=>
string(3) "foo"
["args"]=>
array(0) {
}
}
}
["previous":"Exception":private]=>
NULL
}
10 changes: 10 additions & 0 deletions Zend/tests/throw_on_error/statement_must_be_the_first_one.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
throw_on_error declare statement must be before anything else
--FILE--
<?php
echo "Before";

declare(throw_on_error=1);

--EXPECTF--
Fatal error: throw_on_error declaration must be the very first statement in the script in %s on line 4
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
--TEST--
throw_on_error declare statement
--FILE--
<?php
declare(throw_on_error=1);

echo "OK";
--EXPECT--
OK
17 changes: 17 additions & 0 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,23 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
EG(errors)[EG(num_errors)-1] = info;
}

/* Promote E_WARNING to exception when throw_on_error declare is enabled */
if (orig_type == E_WARNING && EG(current_execute_data)) {
zend_execute_data *ex = EG(current_execute_data);
/* Find first non internal execute_data */
while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
ex = ex->prev_execute_data;
}
if (ex->func == NULL) {
goto normal;
}
if ((ex->func->common.fn_flags & ZEND_ACC_THROW_WARNING) != 0) {
zend_throw_exception(NULL, ZSTR_VAL(message), E_WARNING);
return;
}
}
normal:

/* Report about uncaught exception in case of fatal errors */
if (EG(exception)) {
zend_execute_data *ex;
Expand Down
Loading