aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_static.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2016-06-06 17:39:06 +0200
committerLoïc Hoguin <[email protected]>2016-06-06 17:39:06 +0200
commitf14c45151d786058bd774b4cf5ccd0f3e1ee2a08 (patch)
tree8105e3f0612ca29b7d66a7ac3b4abe08aa7b5607 /src/cowboy_static.erl
parenta82495fa5ccefb71a1996fca84abd9b306ed986c (diff)
downloadcowboy-f14c45151d786058bd774b4cf5ccd0f3e1ee2a08.tar.gz
cowboy-f14c45151d786058bd774b4cf5ccd0f3e1ee2a08.tar.bz2
cowboy-f14c45151d786058bd774b4cf5ccd0f3e1ee2a08.zip
Escape reserved filename characters
Note that this commit has currently only been tested on Linux. It might be incomplete for other platforms.
Diffstat (limited to 'src/cowboy_static.erl')
-rw-r--r--src/cowboy_static.erl17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/cowboy_static.erl b/src/cowboy_static.erl
index 62f7b52..d13db62 100644
--- a/src/cowboy_static.erl
+++ b/src/cowboy_static.erl
@@ -81,7 +81,7 @@ init_dir(Req, Path, Extra) when is_list(Path) ->
init_dir(Req, Path, Extra) ->
Dir = fullpath(filename:absname(Path)),
PathInfo = cowboy_req:path_info(Req),
- Filepath = filename:join([Dir|PathInfo]),
+ Filepath = filename:join([Dir|[escape_reserved(P, <<>>) || P <- PathInfo]]),
Len = byte_size(Dir),
case fullpath(Filepath) of
<< Dir:Len/binary, $/, _/binary >> ->
@@ -92,6 +92,21 @@ init_dir(Req, Path, Extra) ->
{cowboy_rest, Req, error}
end.
+%% We escape the slash found in path segments because
+%% a segment corresponds to a directory entry, and
+%% therefore those slashes are expected to be part of
+%% the directory name.
+%%
+%% Note that on most systems the slash is prohibited
+%% and cannot appear in filenames, which means the
+%% requested file will end up being not found.
+escape_reserved(<<>>, Acc) ->
+ Acc;
+escape_reserved(<< $/, Rest/bits >>, Acc) ->
+ escape_reserved(Rest, << Acc/binary, $\\, $/ >>);
+escape_reserved(<< C, Rest/bits >>, Acc) ->
+ escape_reserved(Rest, << Acc/binary, C >>).
+
fullpath(Path) ->
fullpath(filename:split(Path), []).
fullpath([], Acc) ->