Bug #77615 [Asn]: Undefined class constant 'self::DOES_EXIST'

From: Date: Fri, 15 Feb 2019 13:50:22 +0000
Subject: Bug #77615 [Asn]: Undefined class constant 'self::DOES_EXIST'
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-219596@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=77615&edit=1

 ID:                 77615
 Updated by:         nikic@php.net
 Reported by:        mberchtold at gmail dot com
 Summary:            Undefined class constant 'self::DOES_EXIST'
 Status:             Assigned
 Type:               Bug
 Package:            opcache
 Operating System:   Windows 10 x64
 PHP Version:        7.4
 Assigned To:        dmitry
 Block user comment: N
 Private report:     N

 New Comment:

I've fixed the exception issue in https://github.com/php/php-src/commit/ade9d5e95b879def3ce5b2b0c117ce1258c211ee.

However, there is still some issue for the following case (run under valgrind):

trait T {
    public function test() {
        return 123;
    }
}

class A {
    const C = UNDEF;
    use T;
}

I believe the problem is that T::test() is shared with A, but one of the classes is preloaded while
the other isn't. Depending on where we encounter it first, we might treat it as immutable or
not. But not sure what exactly is happening here.


Previous Comments:
------------------------------------------------------------------------
[2019-02-15 09:56:36] nikic@php.net

@dmitry: I believe the properties_info_table issue should be fixed with https://github.com/php/php-src/commit/ffc7e953ea908f05703d573faadc51707936321c.

However, this doesn't resolve the original issue. Something like

class Foo {
    const A = self::DOES_NOT_EXIST;
}

is enough to reproduce a crash. When we call zend_update_constant_ex it may throw an Error, but this
of course doesn't work during preloading.

------------------------------------------------------------------------
[2019-02-14 14:54:24] dmitry@php.net

This is not a Widows related problem.
The problem introduces by "typed properties" that allocate
"ce->properties_info_table" at ARENA.

See https://github.com/php/php-src/blob/master/ext/opcache/zend_persist_calc.c#L391

Then assert traps, because we can't keep direct pointer from shared to process memory.

Nikita, can you please take a look.

------------------------------------------------------------------------
[2019-02-14 14:45:48] dmitry@php.net

"Typed properties" conflict with "preloading" (even if they are not used).

------------------------------------------------------------------------
[2019-02-13 19:56:55] mberchtold at gmail dot com

This is the preload.php script I'm using:

<?php
function _preload($preload, string $pattern = "/\.php$/", array $ignore = []) {
  if (is_array($preload)) {
    foreach ($preload as $path) {
      _preload($path, $pattern, $ignore);
    }
  } else if (is_string($preload)) {
    $path = $preload;
    if (!in_array($path, $ignore)) {
      if (is_dir($path)) {
        if ($dh = opendir($path)) {
          while (($file = readdir($dh)) !== false) {
            if ($file !== "." && $file !== "..") {
              _preload($path . DIRECTORY_SEPARATOR . $file, $pattern, $ignore);
            }
          }
          closedir($dh);
        }
      } else if (is_file($path) && preg_match($pattern, $path)) {
      	
      	// HACK: skip classes with possible reserved names
      	// PHP Fatal error:  Cannot use 'Float' as class name as it is reserved in
\vendor\zendframework\zend-db\src\Sql\Ddl\Column\Float.php on line 22
      	$basename = basename($path);
      	if ($basename != 'Float.php'
      		&& $basename != 'Int.php'
      		&& $basename != 'Null.php'
      		&& $basename != 'Object.php'
      		)
      	{
        	if (!opcache_compile_file($path)) {
	          trigger_error("Preloading Failed", E_USER_ERROR);
        	}
      	}
      }
    }
  }
}
_preload(['C:\vendor\zendframework\zend-validator\src']);

------------------------------------------------------------------------
[2019-02-13 19:54:33] mberchtold at gmail dot com

To reproduce it, it is sufficient to preload the zend-validator\src folder from ZF3:
_preload(['C:\vendor\zendframework\zend-validator\src']);

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=77615


--
Edit this bug report at https://bugs.php.net/bug.php?id=77615&edit=1


Thread (8 messages)

« previous php.bugs (#219596) next »