Skip to content

Commit 261a939

Browse files
committed
Merge branch '3.4' into 4.4
* 3.4: Prevent parsing invalid octal digits as octal numbers [DI] fix ContainerBuilder on PHP8 [Console] Make sure $maxAttempts is an int or null. [VarDumper] Fix caster for invalid SplFileInfo objects on php 8. [Intl] Skip test cases that produce a TypeError on php 8. [PhpUnitBridge] Adjust output parsing for PHPUnit 9.3. [PhpUnitBridge] CoverageListenerTrait update for PHPUnit 8.5/9.x add bosnian (bs) translation [Debug] Parse "x not found" errors correctly on php 8.
2 parents ba61d89 + 91b6739 commit 261a939

File tree

10 files changed

+506
-68
lines changed

10 files changed

+506
-68
lines changed

src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,19 @@ public function test()
2727
$dir = __DIR__.'/../Tests/Fixtures/coverage';
2828
$phpunit = $_SERVER['argv'][0];
2929

30-
exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output);
30+
exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text --colors=never 2> /dev/null", $output);
3131
$output = implode("\n", $output);
32-
$this->assertStringContainsString('FooCov', $output);
32+
$this->assertMatchesRegularExpression('/FooCov\n\s*Methods:\s+100.00%[^\n]+Lines:\s+100.00%/', $output);
3333

34-
exec("$php $phpunit -c $dir/phpunit-with-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output);
34+
exec("$php $phpunit -c $dir/phpunit-with-listener.xml.dist $dir/tests/ --coverage-text --colors=never 2> /dev/null", $output);
3535
$output = implode("\n", $output);
36-
$this->assertStringNotContainsString('FooCov', $output);
36+
37+
if (false === strpos($output, 'FooCov')) {
38+
$this->addToAssertionCount(1);
39+
} else {
40+
$this->assertMatchesRegularExpression('/FooCov\n\s*Methods:\s+0.00%[^\n]+Lines:\s+0.00%/', $output);
41+
}
42+
3743
$this->assertStringContainsString("SutNotFoundTest::test\nCould not find the tested class.", $output);
3844
$this->assertStringNotContainsString("CoversTest::test\nCould not find the tested class.", $output);
3945
$this->assertStringNotContainsString("CoversDefaultClassTest::test\nCould not find the tested class.", $output);

src/Symfony/Component/Console/Question/Question.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,11 @@ public function getValidator()
220220
*/
221221
public function setMaxAttempts($attempts)
222222
{
223-
if (null !== $attempts && $attempts < 1) {
224-
throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
223+
if (null !== $attempts) {
224+
$attempts = (int) $attempts;
225+
if ($attempts < 1) {
226+
throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
227+
}
225228
}
226229

227230
$this->attempts = $attempts;

src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -33,50 +33,34 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
3333
*/
3434
public function handleError(array $error, FatalErrorException $exception)
3535
{
36-
$messageLen = \strlen($error['message']);
37-
$notFoundSuffix = '\' not found';
38-
$notFoundSuffixLen = \strlen($notFoundSuffix);
39-
if ($notFoundSuffixLen > $messageLen) {
36+
if (!preg_match('/^(Class|Interface|Trait) [\'"]([^\'"]+)[\'"] not found$/', $error['message'], $matches)) {
4037
return null;
4138
}
42-
43-
if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
44-
return null;
39+
$typeName = strtolower($matches[1]);
40+
$fullyQualifiedClassName = $matches[2];
41+
42+
if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
43+
$className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
44+
$namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
45+
$message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
46+
$tail = ' for another namespace?';
47+
} else {
48+
$className = $fullyQualifiedClassName;
49+
$message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
50+
$tail = '?';
4551
}
4652

47-
foreach (['class', 'interface', 'trait'] as $typeName) {
48-
$prefix = ucfirst($typeName).' \'';
49-
$prefixLen = \strlen($prefix);
50-
if (0 !== strpos($error['message'], $prefix)) {
51-
continue;
52-
}
53-
54-
$fullyQualifiedClassName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
55-
if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
56-
$className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
57-
$namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
58-
$message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
59-
$tail = ' for another namespace?';
53+
if ($candidates = $this->getClassCandidates($className)) {
54+
$tail = array_pop($candidates).'"?';
55+
if ($candidates) {
56+
$tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
6057
} else {
61-
$className = $fullyQualifiedClassName;
62-
$message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
63-
$tail = '?';
58+
$tail = ' for "'.$tail;
6459
}
65-
66-
if ($candidates = $this->getClassCandidates($className)) {
67-
$tail = array_pop($candidates).'"?';
68-
if ($candidates) {
69-
$tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
70-
} else {
71-
$tail = ' for "'.$tail;
72-
}
73-
}
74-
$message .= "\nDid you forget a \"use\" statement".$tail;
75-
76-
return new ClassNotFoundException($message, $exception);
7760
}
61+
$message .= "\nDid you forget a \"use\" statement".$tail;
7862

79-
return null;
63+
return new ClassNotFoundException($message, $exception);
8064
}
8165

8266
/**

src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ public function provideClassNotFoundData()
8383
$debugClassLoader = new DebugClassLoader([$autoloader, 'loadClass']);
8484

8585
return [
86+
[
87+
[
88+
'type' => 1,
89+
'line' => 12,
90+
'file' => 'foo.php',
91+
'message' => 'Class "WhizBangFactory" not found',
92+
],
93+
"/^Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement\?$/",
94+
],
8695
[
8796
[
8897
'type' => 1,
@@ -101,6 +110,33 @@ public function provideClassNotFoundData()
101110
],
102111
"Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
103112
],
113+
[
114+
[
115+
'type' => 1,
116+
'line' => 12,
117+
'file' => 'foo.php',
118+
'message' => 'Class "Foo\\Bar\\WhizBangFactory" not found',
119+
],
120+
"/^Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/",
121+
],
122+
[
123+
[
124+
'type' => 1,
125+
'line' => 12,
126+
'file' => 'foo.php',
127+
'message' => 'Interface "Foo\\Bar\\WhizBangInterface" not found',
128+
],
129+
"/^Attempted to load interface \"WhizBangInterface\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/",
130+
],
131+
[
132+
[
133+
'type' => 1,
134+
'line' => 12,
135+
'file' => 'foo.php',
136+
'message' => 'Trait "Foo\\Bar\\WhizBangTrait" not found',
137+
],
138+
"/^Attempted to load trait \"WhizBangTrait\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/",
139+
],
104140
[
105141
[
106142
'type' => 1,

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ private function createService(Definition $definition, array &$inlineServices, b
11411141
} else {
11421142
$r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));
11431143

1144-
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
1144+
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs(array_values($arguments));
11451145

11461146
if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
11471147
@trigger_error(sprintf('The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name), \E_USER_DEPRECATED);

src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -377,14 +377,16 @@ public function testFormatFractionDigits($value, $expected, $fractionDigits = nu
377377

378378
public function formatFractionDigitsProvider()
379379
{
380-
return [
381-
[1.123, '1.123', null, 0],
382-
[1.123, '1', 0, 0],
383-
[1.123, '1.1', 1, 1],
384-
[1.123, '1.12', 2, 2],
385-
[1.123, '1.123', -1, 0],
386-
[1.123, '1', 'abc', 0],
387-
];
380+
yield [1.123, '1.123', null, 0];
381+
yield [1.123, '1', 0, 0];
382+
yield [1.123, '1.1', 1, 1];
383+
yield [1.123, '1.12', 2, 2];
384+
yield [1.123, '1.123', -1, 0];
385+
386+
if (\PHP_VERSION_ID < 80000) {
387+
// This dataset will produce a TypeError on php 8.
388+
yield [1.123, '1', 'abc', 0];
389+
}
388390
}
389391

390392
/**
@@ -410,14 +412,16 @@ public function testFormatGroupingUsed($value, $expected, $groupingUsed = null,
410412

411413
public function formatGroupingUsedProvider()
412414
{
413-
return [
414-
[1000, '1,000', null, 1],
415-
[1000, '1000', 0, 0],
416-
[1000, '1,000', 1, 1],
417-
[1000, '1,000', 2, 1],
418-
[1000, '1000', 'abc', 0],
419-
[1000, '1,000', -1, 1],
420-
];
415+
yield [1000, '1,000', null, 1];
416+
yield [1000, '1000', 0, 0];
417+
yield [1000, '1,000', 1, 1];
418+
yield [1000, '1,000', 2, 1];
419+
yield [1000, '1,000', -1, 1];
420+
421+
if (\PHP_VERSION_ID < 80000) {
422+
// This dataset will produce a TypeError on php 8.
423+
yield [1000, '1000', 'abc', 0];
424+
}
421425
}
422426

423427
/**

0 commit comments

Comments
 (0)