Skip to content

Commit 1d74dda

Browse files
author
José Valim
committed
Handle corner cases for small strings in rstrp
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
1 parent c1e3d4f commit 1d74dda

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

lib/elixir/test/elixir/string_test.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ defmodule StringTest do
135135

136136
test :rstrip do
137137
assert String.rstrip("") == ""
138+
assert String.rstrip("1\n") == "1"
139+
assert String.rstrip("\r\n") == ""
138140
assert String.rstrip(" abc ") == " abc"
139141
assert String.rstrip(" abc a") == " abc a"
140142
assert String.rstrip("a abc a\n\n") == "a abc a"

lib/elixir/unicode/unicode.ex

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ defmodule String.Unicode do
8888
end
8989

9090
# Strip
91-
9291
def lstrip(""), do: ""
9392

9493
for codepoint <- whitespace do
@@ -101,35 +100,41 @@ defmodule String.Unicode do
101100

102101
@whitespace_max_size 3
103102
for codepoint <- whitespace do
104-
# We need to increment @whitespace_max_size
105-
# if we add a new entry here.
103+
# We need to increment @whitespace_max_size as well
104+
# as the small table (_s) if we add a new entry here.
106105
case byte_size(codepoint) do
107106
3 ->
108-
defp do_rstrip(unquote(codepoint)), do: -3
107+
defp do_rstrip_l(unquote(codepoint)), do: -3
109108
2 ->
110-
defp do_rstrip(<<_, unquote(codepoint)>>), do: -2
109+
defp do_rstrip_l(<<_, unquote(codepoint)>>), do: -2
110+
111+
defp do_rstrip_s(unquote(codepoint)), do: <<>>
111112
1 ->
112-
defp do_rstrip(<<unquote(codepoint), unquote(codepoint), unquote(codepoint)>>), do: -3
113-
defp do_rstrip(<<_, unquote(codepoint), unquote(codepoint)>>), do: -2
114-
defp do_rstrip(<<_, _, unquote(codepoint)>>), do: -1
113+
defp do_rstrip_l(<<unquote(codepoint), unquote(codepoint), unquote(codepoint)>>), do: -3
114+
defp do_rstrip_l(<<_, unquote(codepoint), unquote(codepoint)>>), do: -2
115+
defp do_rstrip_l(<<_, _, unquote(codepoint)>>), do: -1
116+
117+
defp do_rstrip_s(<<x, unquote(codepoint)>>), do: do_rstrip_s(<<x>>)
118+
defp do_rstrip_s(unquote(codepoint)), do: <<>>
115119
end
116120
end
117121

118-
defp do_rstrip(_), do: 0
122+
defp do_rstrip_l(_), do: 0
123+
defp do_rstrip_s(o), do: o
119124

120125
def rstrip(string) when is_binary(string) do
121-
size = byte_size(string)
126+
rstrip(string, byte_size(string))
127+
end
122128

123-
trail =
124-
if size < @whitespace_max_size do
125-
string
126-
else
127-
binary_part(string, size, -@whitespace_max_size)
128-
end
129+
defp rstrip(string, size) when size < @whitespace_max_size do
130+
do_rstrip_s(string)
131+
end
129132

130-
case do_rstrip(trail) do
133+
defp rstrip(string, size) do
134+
trail = binary_part(string, size, -@whitespace_max_size)
135+
case do_rstrip_l(trail) do
131136
0 -> string
132-
x -> rstrip(binary_part(string, 0, size + x))
137+
x -> rstrip(binary_part(string, 0, size + x), size + x)
133138
end
134139
end
135140

0 commit comments

Comments
 (0)