Skip to content

Commit

Permalink
bug #20455 [ClassLoader] Fix ClassCollectionLoader inlining with __ha…
Browse files Browse the repository at this point in the history
…lt_compiler (giosh94mhz)

This PR was squashed before being merged into the 2.7 branch (closes #20455).

Discussion
----------

[ClassLoader] Fix ClassCollectionLoader inlining with __halt_compiler

| Q             | A
| ------------- | ---
| Branch?       | 2.7+
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | |
| License       | MIT
| Doc PR        | |

I have some PHP classes which ends with an `__halt_compiler` call which fail on production.

This is due to the ClassCollectionLoader inlining the class code (which is followed by random binary data) which breaks PHP parsing of the following classes.

I found this issue while using ZendGuardLoader module, but this apply to whatever php class using this function call.

I've made my fix, based on #19859, and tested it with symfony 2.7 and 2.8

Commits
-------

a60cd15 [ClassLoader] Fix ClassCollectionLoader inlining with __halt_compiler
  • Loading branch information
nicolas-grekas committed Nov 15, 2016
2 parents 9a66470 + a60cd15 commit e24cedb
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 7 deletions.
13 changes: 10 additions & 3 deletions src/Symfony/Component/ClassLoader/ClassCollectionLoader.php
Expand Up @@ -104,8 +104,15 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive =
}
}

$c = '(?:\s*+(?:(?:#|//)[^\n]*+\n|/\*(?:(?<!\*/).)++)?+)*+';
$strictTypesRegex = str_replace('.', $c, "'^<\?php\s.declare.\(.strict_types.=.1.\).;'is");
$spacesRegex = '(?:\s*+(?:(?:\#|//)[^\n]*+\n|/\*(?:(?<!\*/).)++)?+)*+';
$dontInlineRegex = <<<REGEX
'(?:
^<\?php\s.declare.\(.strict_types.=.1.\).;
| \b__halt_compiler.\(.\)
| \b__(?:DIR|FILE)__\b
)'isx
REGEX;
$dontInlineRegex = str_replace('.', $spacesRegex, $dontInlineRegex);

$cacheDir = explode(DIRECTORY_SEPARATOR, $cacheDir);
$files = array();
Expand All @@ -118,7 +125,7 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive =
$files[] = $file = $class->getFileName();
$c = file_get_contents($file);

if (preg_match($strictTypesRegex, $c)) {
if (preg_match($dontInlineRegex, $c)) {
$file = explode(DIRECTORY_SEPARATOR, $file);

for ($i = 0; isset($file[$i], $cacheDir[$i]); ++$i) {
Expand Down
Expand Up @@ -235,7 +235,7 @@ public function testCommentStripping()
$strictTypes = defined('HHVM_VERSION') ? '' : "\nnamespace {require __DIR__.'/Fixtures/Namespaced/WithStrictTypes.php';}";

ClassCollectionLoader::load(
array('Namespaced\\WithComments', 'Pearlike_WithComments', $strictTypes ? 'Namespaced\\WithStrictTypes' : 'Namespaced\\WithComments'),
array('Namespaced\\WithComments', 'Pearlike_WithComments', 'Namespaced\\WithDirMagic', 'Namespaced\\WithFileMagic', 'Namespaced\\WithHaltCompiler', $strictTypes ? 'Namespaced\\WithStrictTypes' : 'Namespaced\\WithComments'),
__DIR__,
'bar',
false
Expand Down Expand Up @@ -275,6 +275,9 @@ class Pearlike_WithComments
public static $loaded = true;
}
}
namespace {require __DIR__.'/Fixtures/Namespaced/WithDirMagic.php';}
namespace {require __DIR__.'/Fixtures/Namespaced/WithFileMagic.php';}
namespace {require __DIR__.'/Fixtures/Namespaced/WithHaltCompiler.php';}
EOF
.$strictTypes,
str_replace(array("<?php \n", '\\\\'), array('', '/'), file_get_contents($file))
Expand Down
Expand Up @@ -76,9 +76,11 @@ public function getTestCreateMapTests()
'Namespaced\\Foo' => realpath(__DIR__).'/Fixtures/Namespaced/Foo.php',
'Namespaced\\Baz' => realpath(__DIR__).'/Fixtures/Namespaced/Baz.php',
'Namespaced\\WithComments' => realpath(__DIR__).'/Fixtures/Namespaced/WithComments.php',
'Namespaced\WithStrictTypes' => realpath(__DIR__).'/Fixtures/Namespaced/WithStrictTypes.php',
),
),
'Namespaced\\WithStrictTypes' => realpath(__DIR__).'/Fixtures/Namespaced/WithStrictTypes.php',
'Namespaced\\WithHaltCompiler' => realpath(__DIR__).'/Fixtures/Namespaced/WithHaltCompiler.php',
'Namespaced\\WithDirMagic' => realpath(__DIR__).'/Fixtures/Namespaced/WithDirMagic.php',
'Namespaced\\WithFileMagic' => realpath(__DIR__).'/Fixtures/Namespaced/WithFileMagic.php',
)),
array(__DIR__.'/Fixtures/beta/NamespaceCollision', array(
'NamespaceCollision\\A\\B\\Bar' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Bar.php',
'NamespaceCollision\\A\\B\\Foo' => realpath(__DIR__).'/Fixtures/beta/NamespaceCollision/A/B/Foo.php',
Expand Down
@@ -0,0 +1,15 @@
<?php

/*
* foo
*/

namespace Namespaced;

class WithDirMagic
{
public function getDir()
{
return __DIR__;
}
}
@@ -0,0 +1,15 @@
<?php

/*
* foo
*/

namespace Namespaced;

class WithFileMagic
{
public function getFile()
{
return __FILE__;
}
}
@@ -0,0 +1,18 @@
<?php

/*
* foo
*/

namespace Namespaced;

class WithHaltCompiler
{
}

// the end of the script execution
__halt_compiler(); data
data
data
data
...

0 comments on commit e24cedb

Please sign in to comment.