Skip to content

Commit fc4b39e

Browse files
committed
Merge pull request #1047 from mgreter/bugfix/str-slice-function
Fix `str-slice` function to work with utf8 strings
2 parents 1823a09 + 3467e60 commit fc4b39e

File tree

1 file changed

+16
-19
lines changed

1 file changed

+16
-19
lines changed

functions.cpp

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -916,28 +916,25 @@ namespace Sass {
916916
string newstr;
917917
try {
918918
String_Constant* s = ARG("$string", String_Constant);
919-
Number* n = ARG("$start-at", Number);
920-
Number* m = ARG("$end-at", Number);
919+
double start_at = ARG("$start-at", Number)->value();
920+
double end_at = ARG("$end-at", Number)->value();
921921

922922
string str = unquote(s->value());
923923

924-
// normalize into 0-based indices
925-
size_t start = UTF_8::offset_at_position(str, UTF_8::normalize_index(static_cast<int>(n->value()), UTF_8::code_point_count(str)));
926-
size_t end = UTF_8::offset_at_position(str, UTF_8::normalize_index(static_cast<int>(m->value()), UTF_8::code_point_count(str)));
927-
928-
// `str-slice` should always return an empty string when $end-at == 0
929-
// `normalize_index` normalizes 1 -> 0 so we need to check the original value
930-
if(m->value() == 0) {
931-
if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
932-
if(!ss->quote_mark()) return new (ctx.mem) Null(pstate);
933-
} else {
934-
return new (ctx.mem) Null(pstate);
935-
}
936-
newstr = "";
937-
} else if(start == end && m->value() != 0) {
938-
newstr = str.substr(start, 1);
939-
} else if(end > start) {
940-
newstr = str.substr(start, end - start + UTF_8::code_point_size_at_offset(str, end));
924+
size_t size = utf8::distance(str.begin(), str.end());
925+
if (end_at <= size * -1.0) { end_at += size; }
926+
if (end_at < 0) { end_at += size + 1; }
927+
if (end_at > size) { end_at = size; }
928+
if (start_at < 0) { start_at += size + 1; }
929+
else if (start_at == 0) { ++ start_at; }
930+
931+
if (start_at <= end_at)
932+
{
933+
string::iterator start = str.begin();
934+
utf8::advance(start, start_at - 1, str.end());
935+
string::iterator end = start;
936+
utf8::advance(end, end_at - start_at + 1, str.end());
937+
newstr = string(start, end);
941938
}
942939
if (String_Quoted* ss = dynamic_cast<String_Quoted*>(s)) {
943940
if(ss->quote_mark()) newstr = quote(newstr);

0 commit comments

Comments
 (0)