Skip to content

Commit

Permalink
minor #32736 [Console] avoid using huge amount of memory when formatt…
Browse files Browse the repository at this point in the history
…ing 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
-------

47ffbad Avoid using huge amount of memory when formatting long exception
  • Loading branch information
Robin Chalas committed Jul 27, 2019
2 parents 9216cb7 + 47ffbad commit 29ba2e1
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions src/Symfony/Component/Console/Application.php
Expand Up @@ -1149,15 +1149,21 @@ private function splitStringByWidth($string, $width)
$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;
Expand Down

0 comments on commit 29ba2e1

Please sign in to comment.