From 8a3e64f00eb104671bf3aa75408d280906889733 Mon Sep 17 00:00:00 2001 From: flywind Date: Mon, 21 Jun 2021 18:50:47 +0800 Subject: [PATCH] fixes #17768 [backport:1.4] (#18317) * fixes #17768 [backport:1.4] * tiny (cherry picked from commit 2deb7011f5388559a70617c398360639102724c4) --- lib/pure/unicode.nim | 10 ++++------ tests/stdlib/tunicode.nim | 9 ++++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index a28e98cafb..44c0daa3fb 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -333,7 +333,7 @@ proc runeReverseOffset*(s: string, rev: Positive): (int, int) = ## from the end (starting with 1) and the total ## number of runes in the string. ## - ## Returns a negative value for offset if there are to few runes in + ## Returns a negative value for offset if there are too few runes in ## the string to satisfy the request. ## ## **Beware:** This can lead to unoptimized code and slow execution! @@ -346,16 +346,14 @@ proc runeReverseOffset*(s: string, rev: Positive): (int, int) = a = rev.int o = 0 x = 0 + let times = 2*rev.int-s.runeLen # transformed from rev.int - a < s.runeLen - rev.int while o < s.len: let r = runeLenAt(s, o) o += r - if a < 0: + if a > times: x += r dec a - - if a > 0: - return (-a, rev.int-a) - return (x, -a+rev.int) + result = if a > 0: (-a, rev.int-a) else: (x, -a+rev.int) proc runeAtPos*(s: string, pos: int): Rune = ## Returns the rune at position ``pos``. diff --git a/tests/stdlib/tunicode.nim b/tests/stdlib/tunicode.nim index a346106f9f..33405cf385 100644 --- a/tests/stdlib/tunicode.nim +++ b/tests/stdlib/tunicode.nim @@ -1,4 +1,4 @@ -import unicode +import std/unicode proc asRune(s: static[string]): Rune = @@ -213,3 +213,10 @@ block differentSizes: doAssert swapCase("ⱥbCd") == "ȺBcD" doAssert swapCase("XyꟆaB") == "xYᶎAb" doAssert swapCase("aᵹcᲈd") == "AꝽCꙊD" + +block: # bug #17768 + let s1 = "abcdef" + let s2 = "abcdéf" + + doAssert s1.runeSubstr(0, -1) == "abcde" + doAssert s2.runeSubstr(0, -1) == "abcdé"