Skip to content

Commit d3a4b00

Browse files
[Yaml] Fix pcre.backtrack_limit reached
1 parent eca1dd6 commit d3a4b00

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

Parser.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public function parse($value, $flags = 0)
171171
$this->refs[$isRef] = end($data);
172172
}
173173
} elseif (
174-
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:![^\s]+\s+)?[^ \'"\[\{!].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)
174+
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P<value>.+))?$#u', $this->currentLine, $values)
175175
&& (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))
176176
) {
177177
if ($context && 'sequence' == $context) {
@@ -205,7 +205,7 @@ public function parse($value, $flags = 0)
205205
$mergeNode = true;
206206
$allowOverwrite = true;
207207
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
208-
$refName = substr($values['value'], 1);
208+
$refName = substr(rtrim($values['value']), 1);
209209
if (!array_key_exists($refName, $this->refs)) {
210210
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
211211
}
@@ -246,15 +246,15 @@ public function parse($value, $flags = 0)
246246
$data += $parsed; // array union
247247
}
248248
}
249-
} elseif (isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
249+
} elseif (isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u', $values['value'], $matches)) {
250250
$isRef = $matches['ref'];
251251
$values['value'] = $matches['value'];
252252
}
253253

254254
$subTag = null;
255255
if ($mergeNode) {
256256
// Merge keys
257-
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#') || (null !== $subTag = $this->getLineTag(ltrim($values['value'], ' '), $flags))) {
257+
} elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags))) {
258258
// hash
259259
// if next line is less indented or equal, then it means that the current value is null
260260
if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
@@ -286,7 +286,7 @@ public function parse($value, $flags = 0)
286286
}
287287
}
288288
} else {
289-
$value = $this->parseValue($values['value'], $flags, $context);
289+
$value = $this->parseValue(rtrim($values['value']), $flags, $context);
290290
// Spec: Keys MUST be unique; first one wins.
291291
// But overwriting is allowed when a merge node is used in current block.
292292
if ($allowOverwrite || !isset($data[$key])) {

Tests/ParserTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,17 @@ private function loadTestsFromFixtureFiles($testsFile)
16691669

16701670
return $tests;
16711671
}
1672+
1673+
public function testCanParseVeryLongValue()
1674+
{
1675+
$longStringWithSpaces = str_repeat('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ', 20000);
1676+
$trickyVal = array('x' => $longStringWithSpaces);
1677+
1678+
$yamlString = Yaml::dump($trickyVal);
1679+
$arrayFromYaml = $this->parser->parse($yamlString);
1680+
1681+
$this->assertEquals($trickyVal, $arrayFromYaml);
1682+
}
16721683
}
16731684

16741685
class B

0 commit comments

Comments
 (0)