From 1d5c34f6aa04a25fcfc524db13a179a277b524d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Bia=C2=B3as?= Date: Wed, 23 Dec 2020 23:38:32 +0100 Subject: [PATCH 1/4] Fix #38491: fix an abspath() edge case on Windows --- base/path.jl | 14 +++++++++++++- test/path.jl | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/base/path.jl b/base/path.jl index 4e602dde4f98d..2ab2cbdd316e9 100644 --- a/base/path.jl +++ b/base/path.jl @@ -390,7 +390,19 @@ normpath(a::AbstractString, b::AbstractString...) = normpath(joinpath(a,b...)) Convert a path to an absolute path by adding the current directory if necessary. Also normalizes the path as in [`normpath`](@ref). """ -abspath(a::String) = normpath(isabspath(a) ? a : joinpath(pwd(),a)) +function abspath(a::String)::String + if !Sys.iswindows() + return normpath(isabspath(a) ? a : joinpath(pwd(),a)) + else + pwd_drive, _ = splitdrive(pwd()) + a_drive, a_nodrive = splitdrive(a) + if a_drive != "" && lowercase(pwd_drive) != lowercase(a_drive) && !isabspath(a) + return a_drive * normpath(joinpath(path_separator, a_nodrive)) + else + return normpath(isabspath(a) ? a : joinpath(pwd(),a)) + end + end +end """ abspath(path::AbstractString, paths::AbstractString...) -> String diff --git a/test/path.jl b/test/path.jl index bbd9159c59295..310e1843513a6 100644 --- a/test/path.jl +++ b/test/path.jl @@ -9,6 +9,23 @@ @test isabspath(S(homedir())) @test !isabspath(S("foo")) end + if Sys.iswindows() + @testset "issue #38491" begin + pwd_drive = uppercase(splitdrive(pwd())[1]) + drive = if (pwd_drive != "X:") "X:" else "Y:" end + @test abspath("$(lowercase(drive))a\\b\\c") == "$(lowercase(drive))\\a\\b\\c" + @test abspath("$(uppercase(drive))a\\b\\c") == "$(uppercase(drive))\\a\\b\\c" + @test abspath("$(lowercase(drive))a") == "$(lowercase(drive))\\a" + @test abspath("$(uppercase(drive))a") == "$(uppercase(drive))\\a" + @test abspath(lowercase(drive)) == "$(lowercase(drive))\\" + @test abspath(uppercase(drive)) == "$(uppercase(drive))\\" + + @test lowercase(abspath("$(pwd_drive)a\\b\\c")) == lowercase(joinpath(pwd(), "a\\b\\c")) + @test lowercase(abspath("$(pwd_drive)a")) == lowercase(joinpath(pwd(), "a")) + @test lowercase(abspath(lowercase(pwd_drive))) == lowercase("$(pwd())\\") + @test lowercase(abspath(uppercase(pwd_drive))) == lowercase("$(pwd())\\") + end + end @test basename(S("foo$(sep)bar")) == "bar" @test dirname(S("foo$(sep)bar")) == "foo" From d580960f8c49a9a050942a685de5dbeec857ce86 Mon Sep 17 00:00:00 2001 From: Mustafa M Date: Wed, 24 Mar 2021 13:54:35 -0400 Subject: [PATCH 2/4] Update base/path.jl Co-authored-by: Jameson Nash --- base/path.jl | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/base/path.jl b/base/path.jl index 2ab2cbdd316e9..fad07a37682c7 100644 --- a/base/path.jl +++ b/base/path.jl @@ -391,17 +391,20 @@ Convert a path to an absolute path by adding the current directory if necessary. Also normalizes the path as in [`normpath`](@ref). """ function abspath(a::String)::String - if !Sys.iswindows() - return normpath(isabspath(a) ? a : joinpath(pwd(),a)) - else - pwd_drive, _ = splitdrive(pwd()) + if !isabspath(a) + cwd = pwd() a_drive, a_nodrive = splitdrive(a) - if a_drive != "" && lowercase(pwd_drive) != lowercase(a_drive) && !isabspath(a) - return a_drive * normpath(joinpath(path_separator, a_nodrive)) + if a_drive != "" && lowercase(splitdrive(cwd)[1]) != lowercase(a_drive) + cwd = get(ENV, "=" * a_drive, nothing) # check DOS directory + if cwd === nothing || !endswith(cwd, '\\') || !isabspath(cwd) + cwd = a_drive * path_separator + end + a = joinpath(cwd, a_nodrive) else - return normpath(isabspath(a) ? a : joinpath(pwd(),a)) + a = joinpath(cwd, a) end end + return normpath(a) end """ From 2bca0e9411abd56395a2b9e425f7c7d37e960b0e Mon Sep 17 00:00:00 2001 From: Mustafa M Date: Wed, 24 Mar 2021 14:09:14 -0400 Subject: [PATCH 3/4] Update base/path.jl --- base/path.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/base/path.jl b/base/path.jl index fad07a37682c7..82aa5639ee361 100644 --- a/base/path.jl +++ b/base/path.jl @@ -395,10 +395,7 @@ function abspath(a::String)::String cwd = pwd() a_drive, a_nodrive = splitdrive(a) if a_drive != "" && lowercase(splitdrive(cwd)[1]) != lowercase(a_drive) - cwd = get(ENV, "=" * a_drive, nothing) # check DOS directory - if cwd === nothing || !endswith(cwd, '\\') || !isabspath(cwd) - cwd = a_drive * path_separator - end + cwd = a_drive * path_separator a = joinpath(cwd, a_nodrive) else a = joinpath(cwd, a) From b37e29057e643e21760afbd0231d275c10694e86 Mon Sep 17 00:00:00 2001 From: Mustafa M Date: Wed, 24 Mar 2021 14:10:13 -0400 Subject: [PATCH 4/4] Update test/path.jl Co-authored-by: Jameson Nash --- test/path.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/path.jl b/test/path.jl index 310e1843513a6..ca772e24d41de 100644 --- a/test/path.jl +++ b/test/path.jl @@ -12,7 +12,7 @@ if Sys.iswindows() @testset "issue #38491" begin pwd_drive = uppercase(splitdrive(pwd())[1]) - drive = if (pwd_drive != "X:") "X:" else "Y:" end + drive = (pwd_drive == "X:") ? "Y:" : "X:" @test abspath("$(lowercase(drive))a\\b\\c") == "$(lowercase(drive))\\a\\b\\c" @test abspath("$(uppercase(drive))a\\b\\c") == "$(uppercase(drive))\\a\\b\\c" @test abspath("$(lowercase(drive))a") == "$(lowercase(drive))\\a"