Skip to content

Commit 57859d0

Browse files
committed
Improve arg binding when arglist contains expressions
It seems that arglist should always be a list of `Argument` objects. This is not always true and this commit makes the `value_at_index` method more robust to avoid the segfault.
1 parent e119135 commit 57859d0

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

src/ast.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,5 +1952,20 @@ namespace Sass {
19521952
return message();
19531953
}
19541954

1955+
//////////////////////////////////////////////////////////////////////////////////////////
1956+
// Additional method on Lists to retrieve values directly or from an encompassed Argument.
1957+
//////////////////////////////////////////////////////////////////////////////////////////
1958+
Expression* List::value_at_index(size_t i) {
1959+
if (is_arglist_) {
1960+
if (Argument* arg = dynamic_cast<Argument*>((*this)[i])) {
1961+
return arg->value();
1962+
} else {
1963+
return (*this)[i];
1964+
}
1965+
} else {
1966+
return (*this)[i];
1967+
}
1968+
}
1969+
19551970
}
19561971

src/ast.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,11 +1707,6 @@ namespace Sass {
17071707
ATTACH_OPERATIONS()
17081708
};
17091709

1710-
//////////////////////////////////////////////////////////////////////////////////////////
1711-
// Additional method on Lists to retrieve values directly or from an encompassed Argument.
1712-
//////////////////////////////////////////////////////////////////////////////////////////
1713-
inline Expression* List::value_at_index(size_t i) { return is_arglist_ ? ((Argument*)(*this)[i])->value() : (*this)[i]; }
1714-
17151710
/////////////////////////////////////////
17161711
// Abstract base class for CSS selectors.
17171712
/////////////////////////////////////////

src/functions.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,16 +1562,24 @@ namespace Sass {
15621562
List* arglist = SASS_MEMORY_NEW(ctx.mem, List, *ARG("$args", List));
15631563

15641564
Arguments* args = SASS_MEMORY_NEW(ctx.mem, Arguments, pstate);
1565+
std::string full_name(name + "[f]");
1566+
Definition* def = static_cast<Definition*>((d_env)[full_name]);
1567+
Parameters* params = def ? def->parameters() : 0;
1568+
size_t param_size = params ? params->length() : 0;
15651569
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
15661570
Expression* expr = arglist->value_at_index(i);
1571+
Parameter* p = param_size > i ? (*params)[i] : 0;
1572+
if (List* list = dynamic_cast<List*>(expr)) {
1573+
if (p && !p->is_rest_parameter()) expr = (*list)[0];
1574+
}
15671575
if (arglist->is_arglist()) {
1568-
Argument* arg = static_cast<Argument*>((*arglist)[i]);
1576+
Argument* arg = dynamic_cast<Argument*>((*arglist)[i]);
15691577
*args << SASS_MEMORY_NEW(ctx.mem, Argument,
15701578
pstate,
15711579
expr,
15721580
"",
1573-
arg->is_rest_argument(),
1574-
arg->is_keyword_argument());
1581+
arg ? arg->is_rest_argument() : false,
1582+
arg ? arg->is_keyword_argument() : false);
15751583
} else {
15761584
*args << SASS_MEMORY_NEW(ctx.mem, Argument, pstate, expr);
15771585
}

0 commit comments

Comments
 (0)