@@ -1001,12 +1001,12 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
10011001 p .push (num (float64 (length )))
10021002
10031003 case compiler .BuiltinLengthArg :
1004- s := p .toString ( p . peekTop () )
1004+ s := p .peekTop ()
10051005 var length int
10061006 if p .chars {
1007- length = utf8 . RuneCountInString ( s )
1007+ length = len ( s . runes ( p . convertFormat ) )
10081008 } else {
1009- length = len (s )
1009+ length = len (p . toString ( s ) )
10101010 }
10111011 p .replaceTop (num (float64 (length )))
10121012
@@ -1066,9 +1066,18 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
10661066 sValue , posValue := p .peekPop ()
10671067 pos := int (posValue .num ())
10681068 s := p .toString (sValue )
1069- var substr string
1069+ var substr value
10701070 if p .chars {
1071- substr = substrChars (s , pos )
1071+ runes := sValue .runes (p .convertFormat )
1072+ if pos > len (runes ) {
1073+ pos = len (runes ) + 1
1074+ }
1075+ if pos < 1 {
1076+ pos = 1
1077+ }
1078+ length := len (runes ) - pos + 1
1079+ runes = runes [pos - 1 : pos - 1 + length ]
1080+ substr = strFromRunes (runes )
10721081 } else {
10731082 if pos > len (s ) {
10741083 pos = len (s ) + 1
@@ -1077,19 +1086,34 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
10771086 pos = 1
10781087 }
10791088 length := len (s ) - pos + 1
1080- substr = s [pos - 1 : pos - 1 + length ]
1089+ substr = str ( s [pos - 1 : pos - 1 + length ])
10811090 }
1082- p .replaceTop (str ( substr ) )
1091+ p .replaceTop (substr )
10831092
10841093 case compiler .BuiltinSubstrLength :
10851094 posValue , lengthValue := p .popTwo ()
10861095 length := int (lengthValue .num ())
10871096 pos := int (posValue .num ())
1088- s := p .toString ( p . peekTop () )
1089- var substr string
1097+ sValue := p .peekTop ()
1098+ var substr value
10901099 if p .chars {
1091- substr = substrLengthChars (s , pos , length )
1100+ runes := sValue .runes (p .convertFormat )
1101+ if pos > len (runes ) {
1102+ pos = len (runes ) + 1
1103+ }
1104+ if pos < 1 {
1105+ pos = 1
1106+ }
1107+ maxLength := len (runes ) - pos + 1
1108+ if length < 0 {
1109+ length = 0
1110+ }
1111+ if length > maxLength {
1112+ length = maxLength
1113+ }
1114+ substr = strFromRunes (runes [pos - 1 : pos - 1 + length ])
10921115 } else {
1116+ s := p .toString (sValue )
10931117 if pos > len (s ) {
10941118 pos = len (s ) + 1
10951119 }
@@ -1103,9 +1127,9 @@ func (p *interp) callBuiltin(builtinOp compiler.BuiltinOp) error {
11031127 if length > maxLength {
11041128 length = maxLength
11051129 }
1106- substr = s [pos - 1 : pos - 1 + length ]
1130+ substr = str ( s [pos - 1 : pos - 1 + length ])
11071131 }
1108- p .replaceTop (str ( substr ) )
1132+ p .replaceTop (substr )
11091133
11101134 case compiler .BuiltinSystem :
11111135 if p .noExec {
0 commit comments