# Relative path sanitization

**URL:** <https://discourse.julialang.org/t/relative-path-sanitization/6696>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 26, 2017, 9:10am UTC](https://discourse.julialang.org/t/relative-path-sanitization/6696 "2017-10-26T09:10:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 26, 2017, 9:10am UTC](https://discourse.julialang.org/t/relative-path-sanitization/6696/1 "2017-10-26T09:10:09Z")

</div>

I am trying to write a function that resolves a path (provided by the user) relative to a directory, _ensuring that the result is inside the directory_. The one below seems to work, but I am counting on community eyeballs to tell me if I left any holes in it, or that I overcomplicated it 😉 Does not need to be super-secure (just to prevent users shooting themselves in the foot), but portability would be nice. I tested on Linux. OS X and windows tests would be welcome.

```julia
"""
    ensure_proper_subpath(dir, subpath)

Return the normalized `dir/subpath`, ensuring that it is inside `dir`, otherwise
raising an error. *None of the paths are required to exist, the function operates
on paths, not the filesystem.*
"""
function ensure_proper_subpath(dir, subpath)
    norm_dir = normpath(dir)
    norm_subpath = normpath(joinpath(norm_dir, subpath))
    @assert startswith(norm_subpath, norm_dir) "$(subpath) not in $(dir)."
    norm_subpath
end

ensure_proper_subpath("/tmp", "foo") # "/tmp/foo"
ensure_proper_subpath("/tmp/dir/", "foo") # "/tmp/dir/foo"
ensure_proper_subpath("/tmp/dir/", "../foo") # ERROR
ensure_proper_subpath("/tmp/", "dir/../foo") # "/tmp/foo"
ensure_proper_subpath("/tmp/", "dir/../../foo") # ERROR

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 26, 2017, 12:02pm UTC](https://discourse.julialang.org/t/relative-path-sanitization/6696/2 "2017-10-26T12:02:33Z")

</div>

You may want `realpath`, not `normpath`, since otherwise you can be fooled by symbolic links or case changes (on case-insensitive filesystems)

`realpath` requires that the path actually exists, however.

Note also that you should not use `@assert` to check for incorrect user input — you should throw a different exception. `@assert` should only be used to check for bugs (i.e. to assert things that should always be true if your code is functioning as intended).
