Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Yaml] ParseException: pcre.backtrack_limit reached #22067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 22, 2017

Conversation

nicolas-grekas
Copy link
Member

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

while merging 3.2 into master, I noticed that testCanParseVeryLongValue is triggering this error on master, due to this regexp that we added for handling yaml tags. This regexp needs to be fixed so that we can merge the test case.

ping @GuilhemN

@@ -171,6 +171,7 @@ public function parse($value, $flags = 0)
$this->refs[$isRef] = end($data);
}
} elseif (
// this regexp is backtracking-heavy and makes the parser fail on long strings
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:![^\s]+\s+)?[^ \'"\[\{!].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most quantifiers in this regex could probably become possessive ones actually, to remove backtracking.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the regex to self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{!].*?) *+\:(\s++(?P<value>.+?))?\s*+$#u', $this->currentLine, $values) doesn't seem to be enough.
Do you see another possible improvement?

@nicolas-grekas
Copy link
Member Author

Regexp fixed. PR ready.

@@ -171,7 +171,7 @@ public function parse($value, $flags = 0)
$this->refs[$isRef] = end($data);
}
} elseif (
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:![^\s]+\s+)?[^ \'"\[\{!].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P<value>.+))?$#u', $this->currentLine, $values)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GuilhemN the issue was the last part of the regexp, the related to the last \s* and the ungreedy quantifier just before.

Copy link
Member

@stof stof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -205,7 +205,7 @@ public function parse($value, $flags = 0)
$mergeNode = true;
$allowOverwrite = true;
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
$refName = substr($values['value'], 1);
$refName = substr(rtrim($values['value']), 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rtrim($values['value'], ' ')? tabs should not be trimmed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weren't they previously already, with this \s+$ tail?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's legit then 👍

@fabpot
Copy link
Member

fabpot commented Mar 22, 2017

Thank you @nicolas-grekas.

@fabpot fabpot merged commit f0256f1 into symfony:master Mar 22, 2017
@nicolas-grekas nicolas-grekas deleted the yaml-long-string branch March 22, 2017 20:24
@lcobucci
Copy link
Contributor

@nicolas-grekas @fabpot @stof this change breaks the parser when you a have a trailing space after the colon. Doctrine ORM test suite has it and it started to break after this PR got merged (we use "symfony/yaml": "~2.3|~3.0" on require-dev).

I've discovered that by adding the following to the ParserTest.php:

    public function testCanParseContentWithTrailingSpaces()
    {
        $yaml = <<<YAML
items: 
  foo: bar
YAML;

        $expected = [
            'items' => ['foo' => 'bar'],
        ];

        $this->assertEquals($expected, $this->parser->parse($yaml));
    }

I'm not sure if having a trailing space is valid according to the YAML syntax rules, however it was working before.

@nicolas-grekas
Copy link
Member Author

Valid report, please open an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants