Fix Unicode issue in Slicestr and Substr

Fixes #1333
This commit is contained in:
Bjørn Erik Pedersen 2015-08-07 08:52:22 +02:00
parent de7dd70bbc
commit c7aa881d90
2 changed files with 22 additions and 16 deletions

View file

@ -141,19 +141,21 @@ func Slicestr(a interface{}, startEnd ...int) (string, error) {
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 @@ func Substr(a interface{}, nums ...interface{}) (string, error) {
}
}
asRunes := []rune(aStr)
switch len(nums) {
case 0:
return "", errors.New("too less arguments")
@ -201,7 +205,7 @@ func Substr(a interface{}, nums ...interface{}) (string, error) {
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 @@ func Substr(a interface{}, nums ...interface{}) (string, error) {
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 @@ func Substr(a interface{}, nums ...interface{}) (string, error) {
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
}

View file

@ -368,6 +368,7 @@ func TestSlicestr(t *testing.T) {
{"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 @@ func TestSubstr(t *testing.T) {
{"abcdef", 2.0, nil, false},
{"abcdef", 2.0, 2, false},
{"abcdef", 2, 2.0, false},
{"ĀĀĀ", 1, 2, "ĀĀ"}, // # issue 1333
} {
var result string
n = i