Skip to content

Commit

Permalink
Merge pull request #3156 from mgreter/feature/harden-endless-extend
Browse files Browse the repository at this point in the history
Fix extend edge case going endlessly
  • Loading branch information
mgreter authored May 21, 2021
2 parents f158280 + 8f1a5d9 commit f6afdbb
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/ast_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace Sass {
// Implement compare and hashing operations for AST Nodes
// ###########################################################################

// TODO: get rid of funtions and use ObjEquality<T>
// TODO: get rid of functions and use ObjEquality<T>

template <class T>
// Hash the raw pointer instead of object
Expand Down
2 changes: 1 addition & 1 deletion src/ast_sel_unify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Sass {
SASS_ASSERT(!complexes.empty(), "Can't unify empty list");
if (complexes.size() == 1) return complexes;

CompoundSelectorObj unifiedBase = SASS_MEMORY_NEW(CompoundSelector, SourceSpan("[phony]"));
CompoundSelectorObj unifiedBase = SASS_MEMORY_NEW(CompoundSelector, SourceSpan("[unify]"));
for (auto complex : complexes) {
SelectorComponentObj base = complex.back();
if (CompoundSelector * comp = base->getCompound()) {
Expand Down
6 changes: 6 additions & 0 deletions src/error_handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ namespace Sass {
msg = "stack level too deep";
}

EndlessExtendError::EndlessExtendError(Backtraces traces, const AST_Node& node)
: Base(node.pstate(), def_msg, traces), node(node)
{
msg = "Extend is creating an absurdly big selector, aborting!";
}

IncompatibleUnits::IncompatibleUnits(const Units& lhs, const Units& rhs)
{
msg = "Incompatible units: '" + rhs.unit() + "' and '" + lhs.unit() + "'.";
Expand Down
9 changes: 9 additions & 0 deletions src/error_handling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ namespace Sass {
virtual ~StackError() throw() {};
};

class EndlessExtendError : public Base {
protected:
const AST_Node& node;
public:
EndlessExtendError(Backtraces traces, const AST_Node& node);
virtual const char* errtype() const { return "EndlessExtendError"; }
virtual ~EndlessExtendError() throw() {};
};

/* common virtual base class (has no pstate or trace) */
class OperationError : public std::runtime_error {
protected:
Expand Down
19 changes: 15 additions & 4 deletions src/extender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ namespace Sass {

for (sass::vector<SelectorComponentObj>& components : weaved) {

ComplexSelectorObj cplx = SASS_MEMORY_NEW(ComplexSelector, "[phony]");
ComplexSelectorObj cplx = SASS_MEMORY_NEW(ComplexSelector, complex->pstate());
cplx->hasPreLineFeed(complex->hasPreLineFeed());
for (auto& pp : path) {
if (pp->hasPreLineFeed()) {
Expand All @@ -643,7 +643,18 @@ namespace Sass {
}
first = false;

result.push_back(cplx);
auto it = result.begin();
while (it != result.end()) {
if (ObjEqualityFn(*it, cplx)) break;
it += 1;
}
if (it == result.end()) {
result.push_back(cplx);
}

if (result.size() > 500) {
throw Exception::EndlessExtendError(traces, complex);
}

}

Expand Down Expand Up @@ -838,7 +849,7 @@ namespace Sass {
}
if (!originals.empty()) {
CompoundSelectorObj merged =
SASS_MEMORY_NEW(CompoundSelector, "[phony]");
SASS_MEMORY_NEW(CompoundSelector, "[compound]");
merged->concat(originals);
toUnify.insert(toUnify.begin(), { merged });
}
Expand Down Expand Up @@ -1050,7 +1061,7 @@ namespace Sass {
}
}

SelectorListObj list = SASS_MEMORY_NEW(SelectorList, "[phony]");
SelectorListObj list = SASS_MEMORY_NEW(SelectorList, "[pseudo]");
list->concat(expanded);
return { pseudo->withSelector(list) };

Expand Down
2 changes: 1 addition & 1 deletion src/fn_selectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ namespace Sass {

for (auto& complex : sel->elements()) {
if (complex->empty()) {
complex->append(SASS_MEMORY_NEW(CompoundSelector, "[phony]"));
complex->append(SASS_MEMORY_NEW(CompoundSelector, "[append]"));
}
if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {
comp->hasRealParent(true);
Expand Down
1 change: 1 addition & 0 deletions src/sass_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ namespace Sass {
// now create the code trace (ToDo: maybe have util functions?)
if (e.pstate.position.line != sass::string::npos &&
e.pstate.position.column != sass::string::npos &&
e.pstate.getRawData() != nullptr &&
e.pstate.source != nullptr) {
Offset offset(e.pstate.position);
size_t lines = offset.line;
Expand Down

0 comments on commit f6afdbb

Please sign in to comment.