Skip to content

Commit be64aef

Browse files
authored
Merge pull request #2587 from mgreter/bugfix/issue-1294
Fix parsing of block comments to ignore css string rules
2 parents eb07fde + a138fef commit be64aef

File tree

7 files changed

+46
-25
lines changed

7 files changed

+46
-25
lines changed

src/ast.hpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,15 +1779,16 @@ namespace Sass {
17791779
// evaluation phase.
17801780
///////////////////////////////////////////////////////////////////////
17811781
class String_Schema : public String, public Vectorized<Expression_Obj> {
1782-
// ADD_PROPERTY(bool, has_interpolants)
1782+
ADD_PROPERTY(bool, css)
17831783
size_t hash_;
17841784
public:
1785-
String_Schema(ParserState pstate, size_t size = 0, bool has_interpolants = false)
1786-
: String(pstate), Vectorized<Expression_Obj>(size), hash_(0)
1785+
String_Schema(ParserState pstate, size_t size = 0, bool css = true)
1786+
: String(pstate), Vectorized<Expression_Obj>(size), css_(css), hash_(0)
17871787
{ concrete_type(STRING); }
17881788
String_Schema(const String_Schema* ptr)
17891789
: String(ptr),
17901790
Vectorized<Expression_Obj>(*ptr),
1791+
css_(ptr->css_),
17911792
hash_(ptr->hash_)
17921793
{ concrete_type(STRING); }
17931794

@@ -1840,17 +1841,17 @@ namespace Sass {
18401841
value_(ptr->value_),
18411842
hash_(ptr->hash_)
18421843
{ }
1843-
String_Constant(ParserState pstate, std::string val)
1844-
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val)), hash_(0)
1844+
String_Constant(ParserState pstate, std::string val, bool css = true)
1845+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val, css)), hash_(0)
18451846
{ }
1846-
String_Constant(ParserState pstate, const char* beg)
1847-
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg))), hash_(0)
1847+
String_Constant(ParserState pstate, const char* beg, bool css = true)
1848+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg), css)), hash_(0)
18481849
{ }
1849-
String_Constant(ParserState pstate, const char* beg, const char* end)
1850-
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg))), hash_(0)
1850+
String_Constant(ParserState pstate, const char* beg, const char* end, bool css = true)
1851+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg), css)), hash_(0)
18511852
{ }
1852-
String_Constant(ParserState pstate, const Token& tok)
1853-
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end))), hash_(0)
1853+
String_Constant(ParserState pstate, const Token& tok, bool css = true)
1854+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end), css)), hash_(0)
18541855
{ }
18551856
std::string type() const { return "string"; }
18561857
static std::string type_name() { return "string"; }
@@ -1883,8 +1884,8 @@ namespace Sass {
18831884
public:
18841885
String_Quoted(ParserState pstate, std::string val, char q = 0,
18851886
bool keep_utf8_escapes = false, bool skip_unquoting = false,
1886-
bool strict_unquoting = true)
1887-
: String_Constant(pstate, val)
1887+
bool strict_unquoting = true, bool css = true)
1888+
: String_Constant(pstate, val, css)
18881889
{
18891890
if (skip_unquoting == false) {
18901891
value_ = unquote(value_, &quote_mark_, keep_utf8_escapes, strict_unquoting);

src/debugger.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env)
664664
std::cerr << " (" << pstate_source_position(expression) << ")";
665665
std::cerr << " " << expression->concrete_type();
666666
std::cerr << " (" << pstate_source_position(node) << ")";
667+
if (expression->css()) std::cerr << " [css]";
667668
if (expression->is_delayed()) std::cerr << " [delayed]";
668669
if (expression->is_interpolant()) std::cerr << " [is interpolant]";
669670
if (expression->has_interpolant()) std::cerr << " [has interpolant]";

src/eval.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,10 +1258,10 @@ namespace Sass {
12581258
}
12591259
if (!s->is_interpolant()) {
12601260
if (s->length() > 1 && res == "") return SASS_MEMORY_NEW(Null, s->pstate());
1261-
return SASS_MEMORY_NEW(String_Constant, s->pstate(), res);
1261+
return SASS_MEMORY_NEW(String_Constant, s->pstate(), res, s->css());
12621262
}
12631263
// string schema seems to have a special unquoting behavior (also handles "nested" quotes)
1264-
String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), res, 0, false, false, false);
1264+
String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), res, 0, false, false, false, s->css());
12651265
// if (s->is_interpolant()) str->quote_mark(0);
12661266
// String_Constant_Ptr str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res);
12671267
if (str->quote_mark()) str->quote_mark('*');

src/parser.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ namespace Sass {
10261026
while (lex< block_comment >()) {
10271027
bool is_important = lexed.begin[2] == '!';
10281028
// flag on second param is to skip loosely over comments
1029-
String_Obj contents = parse_interpolated_chunk(lexed, true);
1029+
String_Obj contents = parse_interpolated_chunk(lexed, true, false);
10301030
block->append(SASS_MEMORY_NEW(Comment, pstate, contents, is_important));
10311031
}
10321032
}
@@ -1049,7 +1049,7 @@ namespace Sass {
10491049
}
10501050
bool is_indented = true;
10511051
const std::string property(lexed);
1052-
if (!lex_css< one_plus< exactly<':'> > >()) error("property \"" + property + "\" must be followed by a ':'", pstate);
1052+
if (!lex_css< one_plus< exactly<':'> > >()) error("property \"" + escape_string(property) + "\" must be followed by a ':'", pstate);
10531053
if (!is_custom_property && match< sequence< optional_css_comments, exactly<';'> > >()) error("style declaration must contain a value", pstate);
10541054
if (match< sequence< optional_css_comments, exactly<'{'> > >()) is_indented = false; // don't indent if value is empty
10551055
if (is_custom_property) {
@@ -1721,28 +1721,28 @@ namespace Sass {
17211721

17221722
// this parses interpolation inside other strings
17231723
// means the result should later be quoted again
1724-
String_Obj Parser::parse_interpolated_chunk(Token chunk, bool constant)
1724+
String_Obj Parser::parse_interpolated_chunk(Token chunk, bool constant, bool css)
17251725
{
17261726
const char* i = chunk.begin;
17271727
// see if there any interpolants
17281728
const char* p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :
17291729
find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
17301730

17311731
if (!p) {
1732-
String_Quoted_Ptr str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end));
1732+
String_Quoted_Ptr str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end), 0, false, false, true, css);
17331733
if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');
17341734
return str_quoted;
17351735
}
17361736

1737-
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1737+
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate, 0, css);
17381738
schema->is_interpolant(true);
17391739
while (i < chunk.end) {
17401740
p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :
17411741
find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
17421742
if (p) {
17431743
if (i < p) {
17441744
// accumulate the preceding segment if it's nonempty
1745-
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p)));
1745+
schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p), css));
17461746
}
17471747
// we need to skip anything inside strings
17481748
// create a new target in parser/prelexer
@@ -1764,7 +1764,7 @@ namespace Sass {
17641764
}
17651765
else { // no interpolants left; add the last segment if nonempty
17661766
// check if we need quotes here (was not sure after merge)
1767-
if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, chunk.end)));
1767+
if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, chunk.end), css));
17681768
break;
17691769
}
17701770
++ i;

src/parser.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ namespace Sass {
283283
Function_Call_Schema_Obj parse_function_call_schema();
284284
String_Obj parse_url_function_string();
285285
String_Obj parse_url_function_argument();
286-
String_Obj parse_interpolated_chunk(Token, bool constant = false);
286+
String_Obj parse_interpolated_chunk(Token, bool constant = false, bool css = true);
287287
String_Obj parse_string();
288288
String_Constant_Obj parse_static_value();
289289
String_Schema_Obj parse_css_variable_value(bool top_level = true);

src/util.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ namespace Sass {
9696
}
9797

9898
// read css string (handle multiline DELIM)
99-
std::string read_css_string(const std::string& str)
99+
std::string read_css_string(const std::string& str, bool css)
100100
{
101+
if (!css) return str;
101102
std::string out("");
102103
bool esc = false;
103104
for (auto i : str) {
@@ -180,6 +181,23 @@ namespace Sass {
180181
return out;
181182
}
182183

184+
std::string escape_string(const std::string& str)
185+
{
186+
std::string out("");
187+
for (auto i : str) {
188+
if (i == '\n') {
189+
out += "\\n";
190+
} else if (i == '\r') {
191+
out += "\\r";
192+
} else if (i == '\t') {
193+
out += "\\t";
194+
} else {
195+
out += i;
196+
}
197+
}
198+
return out;
199+
}
200+
183201
std::string comment_to_string(const std::string& text)
184202
{
185203
std::string str = "";

src/util.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ namespace Sass {
2222
const char* safe_str(const char *, const char* = "");
2323
void free_string_array(char **);
2424
char **copy_strings(const std::vector<std::string>&, char ***, int = 0);
25-
std::string read_css_string(const std::string& str);
25+
std::string read_css_string(const std::string& str, bool css = true);
2626
std::string evacuate_escapes(const std::string& str);
2727
std::string string_to_output(const std::string& str);
2828
std::string comment_to_string(const std::string& text);
2929
std::string read_hex_escapes(const std::string& str);
30+
std::string escape_string(const std::string& str);
3031
void newline_to_space(std::string& str);
3132

3233
std::string quote(const std::string&, char q = 0);

0 commit comments

Comments
 (0)