Skip to content

Commit 89338a7

Browse files
committed
Merge pull request #1118 from mgreter/bugfix/issue_1115
Fix interpolation edge cases with escapes
2 parents daf9163 + 7df70e6 commit 89338a7

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

debugger.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,8 @@ inline void debug_ast(AST_Node* node, string ind = "", Env* env = 0)
344344
cerr << " (" << pstate_source_position(node) << ")";
345345
cerr << " [name: " << block->name() << "] ";
346346
cerr << " [type: " << (block->type() == Sass::Definition::Type::MIXIN ? "Mixin " : "Function ") << "] ";
347-
cerr << " [signature: " << block->signature() << "] ";
347+
// this seems to lead to segfaults some times?
348+
// cerr << " [signature: " << block->signature() << "] ";
348349
cerr << " [native: " << block->native_function() << "] ";
349350
cerr << " " << block->tabs() << endl;
350351
debug_ast(block->parameters(), ind + " params: ", env);

eval.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,9 @@ namespace Sass {
882882
{
883883
string acc;
884884
for (size_t i = 0, L = s->length(); i < L; ++i) {
885+
if (String_Quoted* str_quoted = dynamic_cast<String_Quoted*>((*s)[i])) {
886+
if (!str_quoted->is_delayed()) str_quoted->value(string_eval_escapes(str_quoted->value()));
887+
}
885888
acc += interpolation((*s)[i]);
886889
}
887890
String_Quoted* str = new (ctx.mem) String_Quoted(s->pstate(), acc);

parser.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1619,8 +1619,9 @@ namespace Sass {
16191619
{
16201620
lex< identifier >();
16211621
string name(lexed);
1622+
ParserState call_pos = pstate;
16221623
Arguments* args = parse_arguments(name == "url");
1623-
return new (ctx.mem) Function_Call(pstate, name, args);
1624+
return new (ctx.mem) Function_Call(call_pos, name, args);
16241625
}
16251626

16261627
Function_Call_Schema* Parser::parse_function_call_schema()

util.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,59 @@ namespace Sass {
4444
return atof(str);
4545
}
4646

47+
string string_eval_escapes(const string& s)
48+
{
49+
50+
string out("");
51+
bool esc = false;
52+
for (size_t i = 0, L = s.length(); i < L; ++i) {
53+
if(s[i] == '\\' && esc == false) {
54+
esc = true;
55+
56+
// escape length
57+
size_t len = 1;
58+
59+
// parse as many sequence chars as possible
60+
// ToDo: Check if ruby aborts after possible max
61+
while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len;
62+
63+
// hex string?
64+
if (len > 1) {
65+
66+
// convert the extracted hex string to code point value
67+
// ToDo: Maybe we could do this without creating a substring
68+
uint32_t cp = strtol(s.substr (i + 1, len - 1).c_str(), nullptr, 16);
69+
70+
if (cp == 0) cp = 0xFFFD;
71+
72+
// assert invalid code points
73+
if (cp >= 1) {
74+
75+
// use a very simple approach to convert via utf8 lib
76+
// maybe there is a more elegant way; maybe we shoud
77+
// convert the whole output from string to a stream!?
78+
// allocate memory for utf8 char and convert to utf8
79+
unsigned char u[5] = {0,0,0,0,0}; utf8::append(cp, u);
80+
for(size_t m = 0; u[m] && m < 5; m++) out.push_back(u[m]);
81+
82+
// skip some more chars?
83+
i += len - 1; esc = false;
84+
if (cp == 10) out += ' ';
85+
86+
}
87+
88+
}
89+
90+
}
91+
else {
92+
out += s[i];
93+
esc = false;
94+
}
95+
}
96+
return out;
97+
98+
}
99+
47100
// double escape every escape sequences
48101
// escape unescaped quotes and backslashes
49102
string string_escape(const string& str)

util.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace Sass {
1212
double sass_atof(const char* str);
1313
string string_escape(const string& str);
1414
string string_unescape(const string& str);
15+
string string_eval_escapes(const string& str);
1516
string read_css_string(const string& str);
1617
string evacuate_quotes(const string& str);
1718
string evacuate_escapes(const string& str);

0 commit comments

Comments
 (0)