Skip to content

Commit

Permalink
Improve hotfix for interpolation edge case
Browse files Browse the repository at this point in the history
Fixes sass#1115
  • Loading branch information
mgreter committed Apr 26, 2015
1 parent 97eb10b commit 08a00b5
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
3 changes: 3 additions & 0 deletions eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,9 @@ namespace Sass {
{
string acc;
for (size_t i = 0, L = s->length(); i < L; ++i) {
if (String_Quoted* str_quoted = dynamic_cast<String_Quoted*>((*s)[i])) {
if (!str_quoted->is_delayed()) str_quoted->value(unescape_string(str_quoted->value()));
}
acc += interpolation((*s)[i]);
}
String_Quoted* str = new (ctx.mem) String_Quoted(s->pstate(), acc);
Expand Down
55 changes: 55 additions & 0 deletions util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,61 @@ namespace Sass {
return atof(str);
}

string unescape_string(const string& s)
{

string out("");
bool esc = false;
for (size_t i = 0, L = s.length(); i < L; ++i) {
if(s[i] == '\\' && esc == false) {
esc = true;

// escape length
size_t len = 1;

// parse as many sequence chars as possible
// ToDo: Check if ruby aborts after possible max
while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len;

// hex string?
if (len > 1) {

// convert the extracted hex string to code point value
// ToDo: Maybe we could do this without creating a substring
uint32_t cp = strtol(s.substr (i + 1, len - 1).c_str(), nullptr, 16);

if (cp == 0) cp = '?';
if (cp == 0xFFFD) cp = '?';

// assert invalid code points
if (cp >= 1) {

// use a very simple approach to convert via utf8 lib
// maybe there is a more elegant way; maybe we shoud
// convert the whole output from string to a stream!?
// allocate memory for utf8 char and convert to utf8
unsigned char u[5] = {0,0,0,0,0}; utf8::append(cp, u);
for(size_t m = 0; u[m] && m < 5; m++) out.push_back(u[m]);

// skip some more chars?
i += len - 1; esc = false;
if (cp == 10) out += ' ';

}


}

}
else {
out += s[i];
esc = false;
}
}
return out;

}

// double escape every escape sequences
// escape unescaped quotes and backslashes
string string_escape(const string& str)
Expand Down
1 change: 1 addition & 0 deletions util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Sass {
double sass_atof(const char* str);
string string_escape(const string& str);
string string_unescape(const string& str);
string unescape_string(const string& str);
string read_css_string(const string& str);
string evacuate_quotes(const string& str);
string evacuate_escapes(const string& str);
Expand Down

0 comments on commit 08a00b5

Please sign in to comment.