Skip to content

Commit cc14b4d

Browse files
bug #60529 [AssetMapper] Fix SequenceParser possible infinite loop (smnandre)
This PR was merged into the 7.3 branch. Discussion ---------- [AssetMapper] Fix SequenceParser possible infinite loop | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #60516 | License | MIT Commits ------- 73ebb39 [AssetMapper] Fix SequenceParser possible infinite loop
2 parents 15cbc27 + 73ebb39 commit cc14b4d

File tree

2 files changed

+25
-21
lines changed

2 files changed

+25
-21
lines changed

src/Symfony/Component/AssetMapper/Compiler/Parser/JavascriptSequenceParser.php

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -133,36 +133,35 @@ public function parseUntil(int $position): void
133133
continue;
134134
}
135135

136-
// Single-line string
137-
if ('"' === $matchChar || "'" === $matchChar) {
138-
if (false === $endPos = strpos($this->content, $matchChar, $matchPos + 1)) {
139-
$this->endsWithSequence(self::STATE_STRING, $position);
140-
141-
return;
142-
}
143-
while (false !== $endPos && '\\' == $this->content[$endPos - 1]) {
144-
$endPos = strpos($this->content, $matchChar, $endPos + 1);
136+
if ('"' === $matchChar || "'" === $matchChar || '`' === $matchChar) {
137+
$endPos = $matchPos + 1;
138+
while (false !== $endPos = strpos($this->content, $matchChar, $endPos)) {
139+
$backslashes = 0;
140+
$i = $endPos - 1;
141+
while ($i >= 0 && $this->content[$i] === '\\') {
142+
$backslashes++;
143+
$i--;
144+
}
145+
146+
if (0 === $backslashes % 2) {
147+
break;
148+
}
149+
150+
$endPos++;
145151
}
146152

147-
$this->cursor = min($endPos + 1, $position);
148-
$this->setSequence(self::STATE_STRING, $endPos + 1);
149-
continue;
150-
}
151-
152-
// Multi-line string
153-
if ('`' === $matchChar) {
154-
if (false === $endPos = strpos($this->content, $matchChar, $matchPos + 1)) {
153+
if (false === $endPos) {
155154
$this->endsWithSequence(self::STATE_STRING, $position);
156-
157155
return;
158156
}
159-
while (false !== $endPos && '\\' == $this->content[$endPos - 1]) {
160-
$endPos = strpos($this->content, $matchChar, $endPos + 1);
161-
}
162157

163158
$this->cursor = min($endPos + 1, $position);
164159
$this->setSequence(self::STATE_STRING, $endPos + 1);
160+
continue;
165161
}
162+
163+
// Fallback
164+
$this->cursor = $matchPos + 1;
166165
}
167166
}
168167

src/Symfony/Component/AssetMapper/Tests/Compiler/Parser/JavascriptSequenceParserTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,5 +230,10 @@ public static function provideStringCases(): iterable
230230
3,
231231
false,
232232
];
233+
yield 'after unclosed string' => [
234+
'"hello',
235+
6,
236+
true,
237+
];
233238
}
234239
}

0 commit comments

Comments
 (0)