Skip to content

Commit 3aeb089

Browse files
authored
Merge pull request leafo#686 from Cerdic/Issue/leafo/432
Fix Issue/leafo/432
2 parents 104c2e3 + 1a7a8ec commit 3aeb089

File tree

1 file changed

+48
-20
lines changed

1 file changed

+48
-20
lines changed

src/Compiler.php

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,13 @@ protected function pushCallStack($name = '')
15211521
Parser::SOURCE_LINE => $this->sourceLine,
15221522
Parser::SOURCE_COLUMN => $this->sourceColumn
15231523
];
1524+
// infinite calling loop
1525+
if (count($this->callStack) > 25000) {
1526+
// not displayed but you can var_dump it to deep debug
1527+
$msg = $this->callStackMessage(true, 100);
1528+
$msg = "Infinite calling loop";
1529+
$this->throwError($msg);
1530+
}
15241531
}
15251532

15261533
protected function popCallStack()
@@ -1533,18 +1540,21 @@ protected function popCallStack()
15331540
*
15341541
* @param array $stms
15351542
* @param \Leafo\ScssPhp\Formatter\OutputBlock $out
1543+
* @param string $traceName
15361544
*
15371545
* @return array|null
15381546
*/
1539-
protected function compileChildren($stms, OutputBlock $out)
1547+
protected function compileChildren($stms, OutputBlock $out, $traceName = '')
15401548
{
1549+
$this->pushCallStack($traceName);
15411550
foreach ($stms as $stm) {
15421551
$ret = $this->compileChild($stm, $out);
15431552

15441553
if (isset($ret)) {
15451554
return $ret;
15461555
}
15471556
}
1557+
$this->popCallStack();
15481558

15491559
return null;
15501560
}
@@ -1555,11 +1565,13 @@ protected function compileChildren($stms, OutputBlock $out)
15551565
* @param array $stms
15561566
* @param \Leafo\ScssPhp\Formatter\OutputBlock $out
15571567
* @param \Leafo\ScssPhp\Block $selfParent
1568+
* @param string $traceName
15581569
*
15591570
* @throws \Exception
15601571
*/
1561-
protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent = null)
1572+
protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent = null, $traceName = '')
15621573
{
1574+
$this->pushCallStack($traceName);
15631575
foreach ($stms as $stm) {
15641576
if ($selfParent && isset($stm[1]) && is_object($stm[1]) && $stm[1] instanceof Block) {
15651577
$stm[1]->selfParent = $selfParent;
@@ -1579,6 +1591,7 @@ protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent
15791591
return;
15801592
}
15811593
}
1594+
$this->popCallStack();
15821595
}
15831596

15841597

@@ -2235,18 +2248,15 @@ protected function compileChild($child, OutputBlock $out)
22352248

22362249
$this->env->marker = 'mixin';
22372250

2238-
$this->pushCallStack($this->env->marker . " " . $name);
2239-
$this->compileChildrenNoReturn($mixin->children, $out, $selfParent);
2240-
$this->popCallStack();
2251+
$this->compileChildrenNoReturn($mixin->children, $out, $selfParent, $this->env->marker . " " . $name);
22412252

22422253
$this->storeEnv = $storeEnv;
22432254

22442255
$this->popEnv();
22452256
break;
22462257

22472258
case Type::T_MIXIN_CONTENT:
2248-
$content = $this->get(static::$namespaces['special'] . 'content', false, $this->getStoreEnv())
2249-
?: $this->get(static::$namespaces['special'] . 'content', false, $this->env);
2259+
$content = $this->get(static::$namespaces['special'] . 'content', false, isset($this->storeEnv) ? $this->storeEnv : $this->env);
22502260

22512261
if (! $content) {
22522262
$content = new \stdClass();
@@ -3983,20 +3993,41 @@ public function throwError($msg)
39833993
: "line: $line";
39843994
$msg = "$msg: $loc";
39853995

3986-
if ($this->callStack) {
3987-
$msg .= "\nCall Stack:\n";
3988-
$ncall = 0;
3996+
$callStackMsg = $this->callStackMessage();
3997+
if ($callStackMsg) {
3998+
$msg .= "\nCall Stack:\n" . $callStackMsg;
3999+
}
4000+
4001+
throw new CompilerException($msg);
4002+
}
4003+
4004+
/**
4005+
* @param bool $all
4006+
* @param null $limit
4007+
* @return string
4008+
*/
4009+
protected function callStackMessage($all = false, $limit = null)
4010+
{
4011+
$callStackMsg = [];
4012+
$ncall = 0;
39894013

4014+
if ($this->callStack) {
39904015
foreach (array_reverse($this->callStack) as $call) {
3991-
$msg .= "#" . $ncall++ . " " . $call['n'] . " ";
3992-
$msg .= (isset($this->sourceNames[$call[Parser::SOURCE_INDEX]])
3993-
? $this->sourceNames[$call[Parser::SOURCE_INDEX]]
3994-
: '(unknown file)');
3995-
$msg .= " on line " . $call[Parser::SOURCE_LINE] . "\n";
4016+
if ($all || (isset($call['n']) && $call['n'])) {
4017+
$msg = "#" . $ncall++ . " " . $call['n'] . " ";
4018+
$msg .= (isset($this->sourceNames[$call[Parser::SOURCE_INDEX]])
4019+
? $this->sourceNames[$call[Parser::SOURCE_INDEX]]
4020+
: '(unknown file)');
4021+
$msg .= " on line " . $call[Parser::SOURCE_LINE];
4022+
$callStackMsg[] = $msg;
4023+
if (!is_null($limit) && $ncall>$limit) {
4024+
break;
4025+
}
4026+
}
39964027
}
39974028
}
39984029

3999-
throw new CompilerException($msg);
4030+
return implode("\n", $callStackMsg);
40004031
}
40014032

40024033
/**
@@ -4063,11 +4094,8 @@ protected function callScssFunction($name, $argValues, &$returnValue)
40634094
$tmp->children = [];
40644095

40654096
$this->env->marker = 'function';
4066-
$this->pushCallStack($this->env->marker . " " . $name);
40674097

4068-
$ret = $this->compileChildren($func->children, $tmp);
4069-
4070-
$this->popCallStack();
4098+
$ret = $this->compileChildren($func->children, $tmp, $this->env->marker . " " . $name);
40714099

40724100
$this->storeEnv = $storeEnv;
40734101

0 commit comments

Comments
 (0)