1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
From 1ec3876afc071a79bb2d104b0b79306392e20bc4 Mon Sep 17 00:00:00 2001
From: Marcel Greter <marcel.greter@ocbnet.ch>
Date: Fri, 18 Oct 2019 07:22:52 +0200
Subject: [PATCH] Fix extend issue being stuck in endless loop
Fixes https://github.com/sass/libsass/issues/3006
---
src/eval_selectors.cpp | 6 +++---
src/expand.cpp | 29 +++++++++++++++++++++++------
src/expand.hpp | 3 +++
src/extender.hpp | 4 ++--
4 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/src/eval_selectors.cpp b/src/eval_selectors.cpp
index cc7d3409c..db797e5bd 100644
--- a/src/eval_selectors.cpp
+++ b/src/eval_selectors.cpp
@@ -46,10 +46,10 @@ namespace Sass {
SelectorList* Eval::operator()(ComplexSelector* s)
{
bool implicit_parent = !exp.old_at_root_without_rule;
- if (is_in_selector_schema) exp.pushToSelectorStack({});
+ if (is_in_selector_schema) exp.pushNullSelector();
SelectorListObj other = s->resolve_parent_refs(
- exp.getSelectorStack(), traces, implicit_parent);
- if (is_in_selector_schema) exp.popFromSelectorStack();
+ exp.getOriginalStack(), traces, implicit_parent);
+ if (is_in_selector_schema) exp.popNullSelector();
for (size_t i = 0; i < other->length(); i++) {
ComplexSelectorObj sel = other->at(i);
diff --git a/src/expand.cpp b/src/expand.cpp
index 1b9bf9158..0380e1cec 100644
--- a/src/expand.cpp
+++ b/src/expand.cpp
@@ -62,6 +62,23 @@ namespace Sass {
return 0;
}
+ void Expand::pushNullSelector()
+ {
+ pushToSelectorStack({});
+ pushToOriginalStack({});
+ }
+
+ void Expand::popNullSelector()
+ {
+ popFromOriginalStack();
+ popFromSelectorStack();
+ }
+
+ SelectorStack Expand::getOriginalStack()
+ {
+ return originalStack;
+ }
+
SelectorStack Expand::getSelectorStack()
{
return selector_stack;
@@ -153,15 +170,15 @@ namespace Sass {
Block* bb = operator()(r->block());
Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
if (r->schema()) {
- pushToSelectorStack({});
+ pushNullSelector();
k->name(eval(r->schema()));
- popFromSelectorStack();
+ popNullSelector();
}
else if (r->selector()) {
if (SelectorListObj s = r->selector()) {
- pushToSelectorStack({});
+ pushNullSelector();
k->name(eval(s));
- popFromSelectorStack();
+ popNullSelector();
}
}
@@ -288,10 +305,10 @@ namespace Sass {
Block* ab = a->block();
SelectorList* as = a->selector();
Expression* av = a->value();
- pushToSelectorStack({});
+ pushNullSelector();
if (av) av = av->perform(&eval);
if (as) as = eval(as);
- popFromSelectorStack();
+ popNullSelector();
Block* bb = ab ? operator()(ab) : NULL;
Directive* aa = SASS_MEMORY_NEW(Directive,
a->pstate(),
diff --git a/src/expand.hpp b/src/expand.hpp
index db5852ce4..90edbf4ca 100644
--- a/src/expand.hpp
+++ b/src/expand.hpp
@@ -22,7 +22,10 @@ namespace Sass {
SelectorListObj& selector();
SelectorListObj& original();
SelectorListObj popFromSelectorStack();
+ SelectorStack getOriginalStack();
SelectorStack getSelectorStack();
+ void pushNullSelector();
+ void popNullSelector();
void pushToSelectorStack(SelectorListObj selector);
SelectorListObj popFromOriginalStack();
diff --git a/src/extender.hpp b/src/extender.hpp
index 4b00cc3a0..5f161786a 100644
--- a/src/extender.hpp
+++ b/src/extender.hpp
@@ -126,8 +126,8 @@ namespace Sass {
std::unordered_map<
SimpleSelectorObj,
size_t,
- ObjHash,
- ObjEquality
+ ObjPtrHash,
+ ObjPtrEquality
> sourceSpecificity;
// ##########################################################################
|