Skip to content

Commit

Permalink
Fixed bug #76936
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed Oct 2, 2018
1 parent 56d1578 commit d2477b2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
4 changes: 4 additions & 0 deletions NEWS
Expand Up @@ -7,6 +7,10 @@ PHP NEWS
(Nikita)
. Fixed bug #76946 (Cyclic reference in generator not detected). (Nikita)

- Reflection:
. Fixed bug #76936 (Objects cannot access their private attributes while
handling reflection errors). (Nikita)

11 Oct 2018, PHP 7.2.11

- Core:
Expand Down
6 changes: 6 additions & 0 deletions Zend/zend.c
Expand Up @@ -1117,6 +1117,7 @@ static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list a
zend_stack loop_var_stack;
zend_stack delayed_oplines_stack;
zend_array *symbol_table;
zend_class_entry *orig_fake_scope;

/* Report about uncaught exception in case of fatal errors */
if (EG(exception)) {
Expand Down Expand Up @@ -1271,6 +1272,9 @@ static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list a
CG(in_compilation) = 0;
}

orig_fake_scope = EG(fake_scope);
EG(fake_scope) = NULL;

if (call_user_function_ex(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params, 1, NULL) == SUCCESS) {
if (Z_TYPE(retval) != IS_UNDEF) {
if (Z_TYPE(retval) == IS_FALSE) {
Expand All @@ -1283,6 +1287,8 @@ static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list a
zend_error_cb(type, error_filename, error_lineno, format, args);
}

EG(fake_scope) = orig_fake_scope;

if (in_compilation) {
CG(active_class_entry) = saved_class_entry;
RESTORE_STACK(loop_var_stack);
Expand Down
45 changes: 45 additions & 0 deletions ext/reflection/tests/bug76936.phpt
@@ -0,0 +1,45 @@
--TEST--
Bug #76936: Objects cannot access their private attributes while handling reflection errors
--FILE--
<?php

class Foo {
public $dummy1;
public $dummy2;
}

class ErrorHandler {
private $private = 'THIS IS PRIVATE'."\n";

function __construct() {
set_error_handler(
function ($errno, $errstr, $errfile, $errline) {
$this->handleError($errno, $errstr, $errfile, $errline);
}
);
}

private function handleError($errno, $errstr, $errfile, $errline, $errmodule = null) {
echo __METHOD__. " dealing with error $errstr\n";

// This attribute is no longer accessible in this object. Same for other
// objects and their private attributes once we reach in this state.
echo $this->private;
}
}

$errorHandler = new ErrorHandler();

$f = new Foo;
unset($f->dummy2);

foreach ((new ReflectionObject($f))->getProperties() as $p) {
echo $p->getName() .' = '. $p->getValue($f) ."\n";
}

?>
--EXPECT--
dummy1 =
ErrorHandler::handleError dealing with error Undefined property: Foo::$dummy2
THIS IS PRIVATE
dummy2 =

0 comments on commit d2477b2

Please sign in to comment.