summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/system.nim11
-rw-r--r--tests/stdlib/tstring.nim55
2 files changed, 60 insertions, 6 deletions
diff --git a/lib/system.nim b/lib/system.nim
index 75014ff26..09d48fd12 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -3252,19 +3252,18 @@ proc `/`*(x, y: int): float {.inline, noSideEffect.} =
 
 template spliceImpl(s, a, L, b: untyped): untyped =
   # make room for additional elements or cut:
-  var slen = s.len
-  var shift = b.len - L
-  var newLen = slen + shift
+  var shift = b.len - max(0,L)  # ignore negative slice size
+  var newLen = s.len + shift
   if shift > 0:
     # enlarge:
     setLen(s, newLen)
-    for i in countdown(newLen-1, a+shift+1): shallowCopy(s[i], s[i-shift])
+    for i in countdown(newLen-1, a+b.len): shallowCopy(s[i], s[i-shift])
   else:
-    for i in countup(a+b.len, s.len-1+shift): shallowCopy(s[i], s[i-shift])
+    for i in countup(a+b.len, newLen-1): shallowCopy(s[i], s[i-shift])
     # cut down:
     setLen(s, newLen)
   # fill the hole:
-  for i in 0 .. <b.len: s[i+a] = b[i]
+  for i in 0 .. <b.len: s[a+i] = b[i]
 
 when hasAlloc or defined(nimscript):
   proc `[]`*(s: string, x: Slice[int]): string {.inline.} =
diff --git a/tests/stdlib/tstring.nim b/tests/stdlib/tstring.nim
new file mode 100644
index 000000000..ddf533a17
--- /dev/null
+++ b/tests/stdlib/tstring.nim
@@ -0,0 +1,55 @@
+discard """
+  file: "tstring.nim"
+  output: "OK"
+"""
+const characters = "abcdefghijklmnopqrstuvwxyz"
+const numbers = "1234567890"
+
+var s: string
+
+proc test_string_slice() =
+  # test "slice of length == len(characters)":
+  # replace characters completely by numbers
+  s = characters
+  s[0..^1] = numbers
+  doAssert s == numbers
+
+  # test "slice of length > len(numbers)":
+  # replace characters by slice of same length
+  s = characters
+  s[1..16] = numbers
+  doAssert s == "a1234567890rstuvwxyz"
+
+  # test "slice of length == len(numbers)":
+  # replace characters by slice of same length
+  s = characters
+  s[1..10] = numbers
+  doAssert s == "a1234567890lmnopqrstuvwxyz"
+
+  # test "slice of length < len(numbers)":
+  # replace slice of length. and insert remaining chars
+  s = characters
+  s[1..4] = numbers
+  doAssert s == "a1234567890fghijklmnopqrstuvwxyz"
+
+  # test "slice of length == 1":
+  # replace first character. and insert remaining 9 chars
+  s = characters
+  s[1..1] = numbers
+  doAssert s == "a1234567890cdefghijklmnopqrstuvwxyz"
+
+  # test "slice of length == 0":
+  # insert chars at slice start index
+  s = characters
+  s[2..1] = numbers
+  doAssert s == "ab1234567890cdefghijklmnopqrstuvwxyz"
+
+  # test "slice of negative length":
+  # same as slice of zero length
+  s = characters
+  s[2..0] = numbers
+  doAssert s == "ab1234567890cdefghijklmnopqrstuvwxyz"
+
+  echo("OK")
+
+test_string_slice()