Skip to content

Commit

Permalink
Add 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 daf9163 commit 97eb10b
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 5 deletions.
9 changes: 5 additions & 4 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1439,22 +1439,23 @@ namespace Sass {
// Flat strings -- the lowest level of raw textual data.
////////////////////////////////////////////////////////
class String_Constant : public String {
ADD_PROPERTY(bool, from_schema);
ADD_PROPERTY(char, quote_mark);
ADD_PROPERTY(string, value);
protected:
size_t hash_;
public:
String_Constant(ParserState pstate, string val)
: String(pstate), quote_mark_(0), value_(read_css_string(val)), hash_(0)
: String(pstate), from_schema_(false), quote_mark_(0), value_(read_css_string(val)), hash_(0)
{ }
String_Constant(ParserState pstate, const char* beg)
: String(pstate), quote_mark_(0), value_(read_css_string(string(beg))), hash_(0)
: String(pstate), from_schema_(false), quote_mark_(0), value_(read_css_string(string(beg))), hash_(0)
{ }
String_Constant(ParserState pstate, const char* beg, const char* end)
: String(pstate), quote_mark_(0), value_(read_css_string(string(beg, end-beg))), hash_(0)
: String(pstate), from_schema_(false), quote_mark_(0), value_(read_css_string(string(beg, end-beg))), hash_(0)
{ }
String_Constant(ParserState pstate, const Token& tok)
: String(pstate), quote_mark_(0), value_(read_css_string(string(tok.begin, tok.end))), hash_(0)
: String(pstate), from_schema_(false), quote_mark_(0), value_(read_css_string(string(tok.begin, tok.end))), hash_(0)
{ }
string type() { return "string"; }
static string type_name() { return "string"; }
Expand Down
1 change: 1 addition & 0 deletions eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,7 @@ namespace Sass {
if (!str->quote_mark()) {
str->value(string_unescape(str->value()));
} else if (str->quote_mark()) {
str->from_schema(true);
str->quote_mark('*');
}
return str;
Expand Down
7 changes: 6 additions & 1 deletion output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,12 @@ namespace Sass {
void Output::operator()(String_Quoted* s)
{
if (s->quote_mark()) {
append_token(quote(s->value(), s->quote_mark()), s);
if (s->from_schema()) {
append_token(quote(unevacuate_escapes(s->value()), s->quote_mark()), s);
} else {
append_token(quote(s->value(), s->quote_mark()), s);
}

} else if (!in_comment) {
append_token(string_to_output(s->value()), s);
} else {
Expand Down
55 changes: 55 additions & 0 deletions util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,61 @@ namespace Sass {
return out;
}

// unescape all double escape sequences
// needed after all interpolations are done
string unevacuate_escapes(const string& s)
{
string out("");
bool esc = false;

for (size_t i = 0, L = s.length(); i < L; ++i) {

// implement the same strange ruby sass behavior
// an escape sequence can also mean a unicode char
if (s[i] == '\\' && !esc) {
// remember
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);

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

// 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;

}

}

} else {
if (esc) out += '\\';
esc = false;
out += s[i];
}
}
return out;
}

// bell character is replaces with space
string string_to_output(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 @@ -15,6 +15,7 @@ namespace Sass {
string read_css_string(const string& str);
string evacuate_quotes(const string& str);
string evacuate_escapes(const string& str);
string unevacuate_escapes(const string& str);
string string_to_output(const string& str);
string comment_to_string(const string& text);
string normalize_wspace(const string& str);
Expand Down

0 comments on commit 97eb10b

Please sign in to comment.