Skip to content

Commit 6df5dfc

Browse files
author
José Valim
committed
Ensure File.cwd works with utf-8 file names
1 parent 5643dbd commit 6df5dfc

File tree

8 files changed

+56
-38
lines changed

8 files changed

+56
-38
lines changed

lib/elixir/lib/file.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ defmodule File do
922922
"""
923923
def cwd() do
924924
case F.get_cwd do
925-
{ :ok, cwd } -> { :ok, list_to_binary(cwd) }
925+
{ :ok, cwd } -> { :ok, :unicode.characters_to_binary(cwd) }
926926
{ :error, _ } = error -> error
927927
end
928928
end
@@ -932,7 +932,7 @@ defmodule File do
932932
"""
933933
def cwd!() do
934934
case F.get_cwd do
935-
{ :ok, cwd } -> list_to_binary(cwd)
935+
{ :ok, cwd } -> :unicode.characters_to_binary(cwd)
936936
{ :error, reason } ->
937937
raise File.Error, reason: reason, action: "get current working directory"
938938
end

lib/elixir/lib/kernel/cli.ex

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ defmodule Kernel.CLI do
88

99
# This is the API invoked by Elixir boot process.
1010
@doc false
11-
def main(options) do
12-
{ config, argv } = process_argv(options, Kernel.CLI.Config.new)
13-
11+
def main(argv) do
1412
argv = lc arg inlist argv, do: list_to_binary(arg)
13+
14+
{ config, argv } = process_argv(argv, Kernel.CLI.Config.new)
1515
:gen_server.call(:elixir_code_server, { :argv, argv })
1616

1717
run fn ->
@@ -98,7 +98,7 @@ defmodule Kernel.CLI do
9898
end
9999

100100
defp invalid_option(option) do
101-
IO.puts(:stderr, "Unknown option #{list_to_binary(option)}")
101+
IO.puts(:stderr, "Unknown option #{option}")
102102
System.halt(1)
103103
end
104104

@@ -113,44 +113,44 @@ defmodule Kernel.CLI do
113113

114114
# Process shared options
115115

116-
defp process_shared(['-v'|t], config) do
116+
defp process_shared(["-v"|t], config) do
117117
IO.puts "Elixir #{System.version}"
118118
process_shared t, config
119119
end
120120

121-
defp process_shared(['--app',h|t], config) do
121+
defp process_shared(["--app",h|t], config) do
122122
process_shared t, config.update_commands [{:app,h}|&1]
123123
end
124124

125-
defp process_shared(['--no-halt'|t], config) do
125+
defp process_shared(["--no-halt"|t], config) do
126126
process_shared t, config.halt(false)
127127
end
128128

129-
defp process_shared(['-e',h|t], config) do
129+
defp process_shared(["-e",h|t], config) do
130130
process_shared t, config.update_commands [{:eval,h}|&1]
131131
end
132132

133-
defp process_shared(['-pa',h|t], config) do
133+
defp process_shared(["-pa",h|t], config) do
134134
Enum.each Path.wildcard(Path.expand(h)), Code.prepend_path(&1)
135135
process_shared t, config
136136
end
137137

138-
defp process_shared(['-pz',h|t], config) do
138+
defp process_shared(["-pz",h|t], config) do
139139
Enum.each Path.wildcard(Path.expand(h)), Code.append_path(&1)
140140
process_shared t, config
141141
end
142142

143-
defp process_shared(['-r',h|t], config) do
143+
defp process_shared(["-r",h|t], config) do
144144
process_shared t, Enum.reduce(Path.wildcard(h), config, fn path, config ->
145145
config.update_commands [{:require,path}|&1]
146146
end)
147147
end
148148

149-
defp process_shared(['-pr',h|t], config) do
149+
defp process_shared(["-pr",h|t], config) do
150150
process_shared t, config.update_commands [{:parallel_require,h}|&1]
151151
end
152152

153-
defp process_shared([erl,_|t], config) when erl in ['--erl', '--sname', '--remsh', '--name'] do
153+
defp process_shared([erl,_|t], config) when erl in ["--erl", "--sname", "--remsh", "--name"] do
154154
process_shared t, config
155155
end
156156

@@ -160,15 +160,15 @@ defmodule Kernel.CLI do
160160

161161
# Process init options
162162

163-
defp process_argv(['--'|t], config) do
163+
defp process_argv(["--"|t], config) do
164164
{ config, t }
165165
end
166166

167-
defp process_argv(['--compile'|t], config) do
167+
defp process_argv(["--compile"|t], config) do
168168
process_compiler t, config
169169
end
170170

171-
defp process_argv(['-S',h|t], config) do
171+
defp process_argv(["-S",h|t], config) do
172172
exec = System.find_executable(h)
173173
if exec do
174174
{ config.update_commands([{:require,exec}|&1]), t }
@@ -180,7 +180,7 @@ defmodule Kernel.CLI do
180180

181181
defp process_argv([h|t] = list, config) do
182182
case h do
183-
'-' ++ _ ->
183+
"-" <> _ ->
184184
shared_option? list, config, process_argv(&1, &2)
185185
_ ->
186186
{ config.update_commands([{:require,h}|&1]), t }
@@ -193,32 +193,31 @@ defmodule Kernel.CLI do
193193

194194
# Process compiler options
195195

196-
defp process_compiler(['--'|t], config) do
196+
defp process_compiler(["--"|t], config) do
197197
{ config, t }
198198
end
199199

200-
defp process_compiler(['-o',h|t], config) do
201-
process_compiler t, config.output(list_to_binary(h))
200+
defp process_compiler(["-o",h|t], config) do
201+
process_compiler t, config.output(h)
202202
end
203203

204-
defp process_compiler(['--no-docs'|t], config) do
204+
defp process_compiler(["--no-docs"|t], config) do
205205
process_compiler t, config.update_compiler_options([{:docs,false}|&1])
206206
end
207207

208-
defp process_compiler(['--no-debug-info'|t], config) do
208+
defp process_compiler(["--no-debug-info"|t], config) do
209209
process_compiler t, config.update_compiler_options([{:debug_info,false}|&1])
210210
end
211211

212-
defp process_compiler(['--ignore-module-conflict'|t], config) do
212+
defp process_compiler(["--ignore-module-conflict"|t], config) do
213213
process_compiler t, config.update_compiler_options([{:ignore_module_conflict,true}|&1])
214214
end
215215

216216
defp process_compiler([h|t] = list, config) do
217217
case h do
218-
'-' ++ _ ->
218+
"-" <> _ ->
219219
shared_option? list, config, process_compiler(&1, &2)
220220
_ ->
221-
h = list_to_binary(h)
222221
pattern = if File.dir?(h), do: "#{h}/**/*.ex", else: h
223222
process_compiler t, config.update_compile [pattern|&1]
224223
end
@@ -230,12 +229,12 @@ defmodule Kernel.CLI do
230229

231230
# Process commands
232231

233-
defp process_command({:eval, expr}, _config) when is_list(expr) do
232+
defp process_command({:eval, expr}, _config) when is_binary(expr) do
234233
Code.eval(expr, [])
235234
end
236235

237-
defp process_command({:app, app}, _config) when is_list(app) do
238-
case Application.Behaviour.start(list_to_atom(app)) do
236+
defp process_command({:app, app}, _config) when is_binary(app) do
237+
case Application.Behaviour.start(binary_to_atom(app)) do
239238
{ :error, reason } ->
240239
IO.puts(:stderr, "Could not start application #{app}: #{inspect reason}")
241240
System.halt(1)
@@ -244,12 +243,12 @@ defmodule Kernel.CLI do
244243
end
245244
end
246245

247-
defp process_command({:require, file}, _config) when is_list(file) do
248-
Code.require_file(list_to_binary(file))
246+
defp process_command({:require, file}, _config) when is_binary(file) do
247+
Code.require_file(file)
249248
end
250249

251-
defp process_command({:parallel_require, pattern}, _config) when is_list(pattern) do
252-
files = Path.wildcard(list_to_binary(pattern))
250+
defp process_command({:parallel_require, pattern}, _config) when is_binary(pattern) do
251+
files = Path.wildcard(pattern)
253252
files = Enum.uniq(files)
254253
files = Enum.filter files, File.regular?(&1)
255254
Kernel.ParallelRequire.files(files)

lib/elixir/lib/path.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,12 @@ defmodule Path do
309309
310310
"""
311311
def wildcard(glob) when is_binary(glob) do
312-
paths = :elixir_glob.wildcard binary_to_list(glob)
313-
Enum.map paths, list_to_binary(&1)
312+
paths = :elixir_glob.wildcard :unicode.characters_to_list(glob)
313+
Enum.map paths, :unicode.characters_to_binary(&1)
314314
end
315315

316316
def wildcard(glob) when is_list(glob) do
317-
:elixir_glob.wildcard(glob)
317+
Enum.map wildcard(list_to_binary(glob)), binary_to_list(&1)
318318
end
319319

320320
## Helpers

lib/elixir/lib/system.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ defmodule System do
5959
"""
6060
def cwd do
6161
case :file.get_cwd do
62-
{ :ok, list } -> list_to_binary(list)
62+
{ :ok, list } -> :unicode.characters_to_binary(list)
6363
_ -> nil
6464
end
6565
end

lib/elixir/test/elixir/file_test.exs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,12 @@ defmodule FileTest do
10471047
end
10481048
end
10491049

1050+
test :cwd_and_cd_with_utf8 do
1051+
File.cd!(fixture_path("héllò"), fn ->
1052+
assert Path.basename(File.cwd!) == "héllò"
1053+
end)
1054+
end
1055+
10501056
test :invalid_cd do
10511057
assert File.cd(fixture_path("file.txt")) == { :error, :enotdir }
10521058
end

lib/elixir/test/elixir/fixtures/héllò/.gitkeep

Whitespace-only changes.

lib/elixir/test/elixir/path_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ Code.require_file "../test_helper.exs", __FILE__
33
defmodule PathTest do
44
use ExUnit.Case, async: true
55

6+
test :wildcard do
7+
import PathHelpers
8+
assert Path.wildcard(fixture_path("héllò")) == [fixture_path("héllò")]
9+
end
10+
611
test :absname_with_binary do
712
assert Path.absname("/foo/bar") == "/foo/bar"
813
assert Path.absname("/foo/bar/") == "/foo/bar"

lib/elixir/test/elixir/system_test.exs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ defmodule SystemTest do
1717
assert is_binary System.cwd!
1818
end
1919

20+
test :cwd_with_utf8 do
21+
import PathHelpers
22+
23+
File.cd!(fixture_path("héllò"), fn ->
24+
assert Path.basename(System.cwd!) == "héllò"
25+
end)
26+
end
27+
2028
test :user_home do
2129
assert is_binary System.user_home
2230
assert is_binary System.user_home!

0 commit comments

Comments
 (0)