0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Escape reserved filename characters

Note that this commit has currently only been tested on Linux.
It might be incomplete for other platforms.
This commit is contained in:
Loïc Hoguin 2016-06-06 17:39:06 +02:00
parent a82495fa5c
commit f14c45151d

View file

@ -81,7 +81,7 @@ init_dir(Req, Path, Extra) when is_list(Path) ->
init_dir(Req, Path, Extra) -> init_dir(Req, Path, Extra) ->
Dir = fullpath(filename:absname(Path)), Dir = fullpath(filename:absname(Path)),
PathInfo = cowboy_req:path_info(Req), PathInfo = cowboy_req:path_info(Req),
Filepath = filename:join([Dir|PathInfo]), Filepath = filename:join([Dir|[escape_reserved(P, <<>>) || P <- PathInfo]]),
Len = byte_size(Dir), Len = byte_size(Dir),
case fullpath(Filepath) of case fullpath(Filepath) of
<< Dir:Len/binary, $/, _/binary >> -> << Dir:Len/binary, $/, _/binary >> ->
@ -92,6 +92,21 @@ init_dir(Req, Path, Extra) ->
{cowboy_rest, Req, error} {cowboy_rest, Req, error}
end. 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(Path) ->
fullpath(filename:split(Path), []). fullpath(filename:split(Path), []).
fullpath([], Acc) -> fullpath([], Acc) ->