From 7ffd3247993ea1ef9a065be15998a723dbea8126 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Mon, 16 Apr 2012 19:58:52 -0500 Subject: Only ignore slashes in cookie values for the path * Ensures cookie encoding errors are caught earlier * Fix separator misspelling --- src/cowboy_cookies.erl | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/cowboy_cookies.erl b/src/cowboy_cookies.erl index 6818a86..5ab27e2 100644 --- a/src/cowboy_cookies.erl +++ b/src/cowboy_cookies.erl @@ -96,7 +96,7 @@ cookie(Key, Value, Options) when is_binary(Key) undefined -> <<"">>; Path -> - <<"; Path=", (quote(Path))/binary>> + <<"; Path=", (quote(Path, true))/binary>> end, HttpOnlyPart = case proplists:get_value(http_only, Options) of @@ -119,7 +119,7 @@ is_whitespace($\r) -> true; is_whitespace($\n) -> true; is_whitespace(_) -> false. -%% @doc Check if a character is a seperator. +%% @doc Check if a character is a separator. -spec is_separator(char()) -> boolean(). is_separator(C) when C < 32 -> true; is_separator($\s) -> true; @@ -143,34 +143,39 @@ is_separator(${) -> true; is_separator($}) -> true; is_separator(_) -> false. -%% @doc Check if a binary has an ASCII seperator character. --spec has_seperator(binary()) -> boolean(). -has_seperator(<<>>) -> +%% @doc Check if a binary has an ASCII separator character. +-spec has_separator(binary(), boolean()) -> boolean(). +has_separator(<<>>, _) -> false; -has_seperator(<<$/, Rest/binary>>) -> - has_seperator(Rest); -has_seperator(<>) -> +has_separator(<<$/, Rest/binary>>, true) -> + has_separator(Rest, true); +has_separator(<>, IgnoreSlash) -> case is_separator(C) of true -> true; false -> - has_seperator(Rest) + has_separator(Rest, IgnoreSlash) end. %% @doc Convert to a binary and raise an error if quoting is required. Quoting %% is broken in different ways for different browsers. Its better to simply %% avoiding doing it at all. %% @end --spec quote(term()) -> binary(). -quote(V0) -> +-spec quote(term(), boolean()) -> binary(). +quote(V0, IgnoreSlash) -> V = any_to_binary(V0), - case has_seperator(V) of + case has_separator(V, IgnoreSlash) of true -> erlang:error({cookie_quoting_required, V}); false -> V end. +%% @equiv quote(Bin, false) +-spec quote(term()) -> binary(). +quote(V0) -> + quote(V0, false). + -spec add_seconds(integer(), calendar:datetime()) -> calendar:datetime(). add_seconds(Secs, LocalTime) -> Greg = calendar:datetime_to_gregorian_seconds(LocalTime), @@ -265,7 +270,7 @@ binary_splitwith(F, Head, Tail) -> binary_splitwith(F, String) -> binary_splitwith(F, <<>>, String). -%% @doc Split the binary when the next seperator is found. +%% @doc Split the binary when the next separator is found. -spec read_token(binary()) -> {binary(), binary()}. read_token(String) -> binary_splitwith(fun is_separator/1, String). @@ -301,6 +306,9 @@ quote_test() -> catch error:{cookie_quoting_required, <<":wq">>} -> ok end, ?assertEqual(<<"foo">>,quote(foo)), + _ = try quote(<<"/test/slashes/">>) + catch error:{cookie_quoting_required, <<"/test/slashes/">>} -> ok + end, ok. parse_cookie_test() -> -- cgit v1.2.3