8000 [VarExporter] Fix exporting default values involving global constants · symfony/symfony@cf25382 · GitHub
[go: up one dir, main page]

Skip to content

Commit cf25382

Browse files
kylekatarnlsnicolas-grekas
authored andcommitted
[VarExporter] Fix exporting default values involving global constants
1 parent e4bd593 commit cf25382

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

src/Symfony/Component/VarExporter/ProxyHelper.php

+23-7
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,14 @@ public static function exportSignature(\ReflectionFunctionAbstract $function, bo
219219
$args = '';
220220
$param = null;
221221
$parameters = [];
222+
$namespace = $function instanceof \ReflectionMethod ? $function->class : $function->getNamespaceName().'\\';
223+
$namespace = substr($namespace, 0, strrpos($namespace, '\\') ?: 0);
222224
foreach ($function->getParameters() as $param) {
223225
$parameters[] = ($param->getAttributes(\SensitiveParameter::class) ? '#[\SensitiveParameter] ' : '')
224226
.($withParameterTypes && $param->hasType() ? self::exportType($param).' ' : '')
225227
.($param->isPassedByReference() ? '&' : '')
226228
.($param->isVariadic() ? '...' : '').'$'.$param->name
227-
.($param->isOptional() && !$param->isVariadic() ? ' = '.self::exportDefault($param) : '');
229+
.($param->isOptional() && !$param->isVariadic() ? ' = '.self::exportDefault($param, $namespace) : '');
228230
if ($param->isPassedByReference()) {
229231
$byRefIndex = 1 + $param->getPosition();
230232
}
@@ -333,7 +335,7 @@ private static function exportPropertyScopes(string $parent): string
333335
return $propertyScopes;
334336
}
335337

336-
private static function exportDefault(\ReflectionParameter $param): string
338+
private static function exportDefault(\ReflectionParameter $param, $namespace): string
337339
{
338340
$default = rtrim(substr(explode('$'.$param->name.' = ', (string) $param, 2)[1] ?? '', 0, -2));
339341

@@ -347,26 +349,40 @@ private static function exportDefault(\ReflectionParameter $param): string
347349
$regexp = "/(\"(?:[^\"\\\\]*+(?:\\\\.)*+)*+\"|'(?:[^'\\\\]*+(?:\\\\.)*+)*+')/";
348350
$parts = preg_split($regexp, $default, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
349351

350-
$regexp = '/([\[\( ]|^)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z0-9_\x7f-\xff]++)*+)(?!: )/';
352+
$regexp = '/([\[\( ]|^)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z0-9_\x7f-\xff]++)*+)(\(?)(?!: )/';
351353
$callback = (false !== strpbrk($default, "\\:('") && $class = $param->getDeclaringClass())
352354
? fn ($m) => $m[1].match ($m[2]) {
353355
'new', 'false', 'true', 'null' => $m[2],
354356
'NULL' => 'null',
355357
'self' => '\\'.$class->name,
356358
'namespace\\parent',
357359
'parent' => ($parent = $class->getParentClass()) ? '\\'.$parent->name : 'parent',
358-
default => '\\'.$m[2],
359-
}
360+
default => self::exportSymbol($m[2], '(' !== $m[3], $namespace),
361+
}.$m[3]
360362
: fn ($m) => $m[1].match ($m[2]) {
361363
'new', 'false', 'true', 'null', 'self', 'parent' => $m[2],
362364
'NULL' => 'null',
363-
default => '\\'.$m[2],
364-
};
365+
default => self::exportSymbol($m[2], '(' !== $m[3], $namespace),
366+
}.$m[3];
365367

366368
return implode('', array_map(fn ($part) => match ($part[0]) {
367369
'"' => $part, // for internal classes only
368370
"'" => false !== strpbrk($part, "\\\0\r\n") ? '"'.substr(str_replace(['$', "\0", "\r", "\n"], ['\$', '\0', '\r', '\n'], $part), 1, -1).'"' : $part,
369371
default => preg_replace_callback($regexp, $callback, $part),
370372
}, $parts));
371373
}
374+
375+
private static function exportSymbol(string $symbol, bool $mightBeRootConst, string $namespace): string
376+
{
377+
if (!$mightBeRootConst
378+
|| false === ($ns = strrpos($symbol, '\\'))
379+
|| substr($symbol, 0, $ns) !== $namespace
380+
|| defined($symbol)
381+
|| !defined(substr($symbol, $ns + 1))
382+
) {
383+
return '\\'.$symbol;
384+
}
385+
386+
return '\\'.substr($symbol, $ns + 1);
387+
}
372388
}

src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public static function provideExportSignature()
3737
$expected = str_replace(['.', ' . . . ', '\'$a\', \'$a\n\', "\$a\n"'], [' . ', '...', '\'$a\', "\$a\\\n", "\$a\n"'], $expected);
3838
$expected = str_replace('Bar', '\\'.Bar::class, $expected);
3939
$expected = str_replace('self', '\\'.TestForProxyHelper::class, $expected);
40+
$expected = str_replace('= [M_PI, new M_PI]', '= [\M_PI, new \Symfony\Component\VarExporter\Tests\M_PI()]', $expected);
4041

4142
yield [$expected, $method];
4243
}
@@ -237,6 +238,10 @@ public static function foo8()
237238
public function foo9($a = self::BOB, $b = ['$a', '$a\n', "\$a\n"], $c = ['$a', '$a\n', "\$a\n", new \stdClass()])
238239
{
239240
}
241+
242+
public function foo10($a = [M_PI, new M_PI])
243+
{
244+
}
240245
}
241246

242247
interface TestForProxyHelperInterface1

0 commit comments

Comments
 (0)
0