minor #32736 [Console] avoid using huge amount of memory when formatting long exception (paxal)

This PR was submitted for the master branch but it was merged into the 4.4 branch instead (closes #32736).

Discussion
----------

[Console] avoid using huge amount of memory when formatting long exception

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | none
| License       | MIT

When formatting exceptions, `preg_split('//u')` is used to iterate over utf8 characters. When the exception is long, the amount of memory used is huge and can reach `memory_limit`.

This PR uses a `Generator` to iterate over the string instead of splitting it, thus reducing the amount of memory.

Commits
-------

47ffbad82d Avoid using huge amount of memory when formatting long exception
This commit is contained in:
Robin Chalas 2019-07-27 05:02:48 +02:00
commit 29ba2e1e06

View File

@ -1149,15 +1149,21 @@ class Application implements ResetInterface
$utf8String = mb_convert_encoding($string, 'utf8', $encoding);
$lines = [];
$line = '';
foreach (preg_split('//u', $utf8String) as $char) {
// test if $char could be appended to current line
if (mb_strwidth($line.$char, 'utf8') <= $width) {
$line .= $char;
continue;
$offset = 0;
while (preg_match('/.{1,10000}/u', $utf8String, $m, 0, $offset)) {
$offset += \strlen($m[0]);
foreach (preg_split('//u', $m[0]) as $char) {
// test if $char could be appended to current line
if (mb_strwidth($line.$char, 'utf8') <= $width) {
$line .= $char;
continue;
}
// if not, push current line to array and make new line
$lines[] = str_pad($line, $width);
$line = $char;
}
// if not, push current line to array and make new line
$lines[] = str_pad($line, $width);
$line = $char;
}
$lines[] = \count($lines) ? str_pad($line, $width) : $line;