shithub: hugo

Download patch

ref: c7aa881d902811ced207458b04f388e6fb1b5190
parent: de7dd70bbc1ac533f137e5f788e1b337d6ba6b8c
author: Bjørn Erik Pedersen <[email protected]>
date: Fri Aug 7 04:52:22 EDT 2015

Fix Unicode issue in Slicestr and Substr

Fixes #1333

--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -141,19 +141,21 @@
 		return "", errors.New("too many arguments")
 	}
 
-	if len(startEnd) > 0 && (startEnd[0] < 0 || startEnd[0] >= len(aStr)) {
+	asRunes := []rune(aStr)
+
+	if len(startEnd) > 0 && (startEnd[0] < 0 || startEnd[0] >= len(asRunes)) {
 		return "", errors.New("slice bounds out of range")
 	}
 
 	if len(startEnd) == 2 {
-		if startEnd[1] < 0 || startEnd[1] > len(aStr) {
+		if startEnd[1] < 0 || startEnd[1] > len(asRunes) {
 			return "", errors.New("slice bounds out of range")
 		}
-		return aStr[startEnd[0]:startEnd[1]], nil
+		return string(asRunes[startEnd[0]:startEnd[1]]), nil
 	} else if len(startEnd) == 1 {
-		return aStr[startEnd[0]:], nil
+		return string(asRunes[startEnd[0]:]), nil
 	} else {
-		return aStr[:], nil
+		return string(asRunes[:]), nil
 	}
 
 }
@@ -194,6 +196,8 @@
 		}
 	}
 
+	asRunes := []rune(aStr)
+
 	switch len(nums) {
 	case 0:
 		return "", errors.New("too less arguments")
@@ -201,7 +205,7 @@
 		if start, err = toInt(nums[0], "start argument must be integer"); err != nil {
 			return "", err
 		}
-		length = len(aStr)
+		length = len(asRunes)
 	case 2:
 		if start, err = toInt(nums[0], "start argument must be integer"); err != nil {
 			return "", err
@@ -213,10 +217,10 @@
 		return "", errors.New("too many arguments")
 	}
 
-	if start < -len(aStr) {
+	if start < -len(asRunes) {
 		start = 0
 	}
-	if start > len(aStr) {
+	if start > len(asRunes) {
 		return "", errors.New(fmt.Sprintf("start position out of bounds for %d-byte string", len(aStr)))
 	}
 
@@ -225,24 +229,24 @@
 		s = start
 		e = start + length
 	} else if start < 0 && length >= 0 {
-		s = len(aStr) + start - length + 1
-		e = len(aStr) + start + 1
+		s = len(asRunes) + start - length + 1
+		e = len(asRunes) + start + 1
 	} else if start >= 0 && length < 0 {
 		s = start
-		e = len(aStr) + length
+		e = len(asRunes) + length
 	} else {
-		s = len(aStr) + start
-		e = len(aStr) + length
+		s = len(asRunes) + start
+		e = len(asRunes) + length
 	}
 
 	if s > e {
 		return "", errors.New(fmt.Sprintf("calculated start position greater than end position: %d > %d", s, e))
 	}
-	if e > len(aStr) {
-		e = len(aStr)
+	if e > len(asRunes) {
+		e = len(asRunes)
 	}
 
-	return aStr[s:e], nil
+	return string(asRunes[s:e]), nil
 
 }
 
--- a/tpl/template_funcs_test.go
+++ b/tpl/template_funcs_test.go
@@ -368,6 +368,7 @@
 		{"abcdef", []int{-1, 7}, false},
 		{"abcdef", []int{1, -1}, false},
 		{tstNoStringer{}, []int{0, 1}, false},
+		{"ĀĀĀ", []int{0, 1}, "Ā"}, // issue #1333
 	} {
 		result, err := Slicestr(this.v1, this.v2...)
 
@@ -422,6 +423,7 @@
 		{"abcdef", 2.0, nil, false},
 		{"abcdef", 2.0, 2, false},
 		{"abcdef", 2, 2.0, false},
+		{"ĀĀĀ", 1, 2, "ĀĀ"}, // # issue 1333
 	} {
 		var result string
 		n = i