Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions lib/plug/conn/cookies.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,40 +49,49 @@ defmodule Plug.Conn.Cookies do

defp decode_kv("", acc), do: acc
defp decode_kv(<<h, t::binary>>, acc) when h in [?\s, ?\t], do: decode_kv(t, acc)
defp decode_kv(kv, acc) when is_binary(kv), do: decode_key(kv, "", acc)
defp decode_kv(kv, acc) when is_binary(kv), do: decode_key(kv, kv, 0, acc)

defp decode_key(<<h, t::binary>>, _key, acc) when h in [?\s, ?\t, ?\r, ?\n, ?\v, ?\f],
do: skip_until_cc(t, acc)
defp decode_key(<<h, t::binary>>, _key_rest, _len, acc)
when h in [?\s, ?\t, ?\r, ?\n, ?\v, ?\f],
do: skip_until_cc(t, acc)

defp decode_key(<<?;, t::binary>>, _key, acc), do: decode_kv(t, acc)
defp decode_key(<<?=, t::binary>>, "", acc), do: skip_until_cc(t, acc)
defp decode_key(<<?=, t::binary>>, key, acc), do: decode_value(t, "", 0, key, acc)
defp decode_key(<<h, t::binary>>, key, acc), do: decode_key(t, <<key::binary, h>>, acc)
defp decode_key(<<>>, _key, acc), do: acc
defp decode_key(<<?;, t::binary>>, _key_rest, _len, acc), do: decode_kv(t, acc)
defp decode_key(<<?=, t::binary>>, _key_rest, 0, acc), do: skip_until_cc(t, acc)

defp decode_value(<<?;, t::binary>>, value, spaces, key, acc),
do: decode_kv(t, [{key, trim_spaces(value, spaces)} | acc])
defp decode_key(<<?=, t::binary>>, key_rest, len, acc) do
key = binary_part(key_rest, 0, len)
decode_value(t, t, 0, 0, key, acc)
end

defp decode_value(<<?\s, t::binary>>, value, spaces, key, acc),
do: decode_value(t, <<value::binary, ?\s>>, spaces + 1, key, acc)
defp decode_key(<<_, t::binary>>, key_rest, len, acc), do: decode_key(t, key_rest, len + 1, acc)
defp decode_key(<<>>, _key_rest, _len, acc), do: acc

defp decode_value(<<h, t::binary>>, _value, _spaces, _key, acc)
defp decode_value(<<?;, t::binary>>, val_rest, len, spaces, key, acc) do
value = binary_part(val_rest, 0, len - spaces)
decode_kv(t, [{key, value} | acc])
end

defp decode_value(<<?\s, t::binary>>, val_rest, len, spaces, key, acc) do
decode_value(t, val_rest, len + 1, spaces + 1, key, acc)
end

defp decode_value(<<h, t::binary>>, _val_rest, _len, _spaces, _key, acc)
when h in [?\t, ?\r, ?\n, ?\v, ?\f],
do: skip_until_cc(t, acc)

defp decode_value(<<h, t::binary>>, value, _spaces, key, acc),
do: decode_value(t, <<value::binary, h>>, 0, key, acc)
defp decode_value(<<_, t::binary>>, val_rest, len, _spaces, key, acc) do
decode_value(t, val_rest, len + 1, 0, key, acc)
end

defp decode_value(<<>>, value, spaces, key, acc),
do: [{key, trim_spaces(value, spaces)} | acc]
defp decode_value(<<>>, val_rest, len, spaces, key, acc) do
value = binary_part(val_rest, 0, len - spaces)
[{key, value} | acc]
end

defp skip_until_cc(<<?;, t::binary>>, acc), do: decode_kv(t, acc)
defp skip_until_cc(<<_, t::binary>>, acc), do: skip_until_cc(t, acc)
defp skip_until_cc(<<>>, acc), do: acc

defp trim_spaces(value, 0), do: value
defp trim_spaces(value, spaces), do: binary_part(value, 0, byte_size(value) - spaces)

@doc """
Encodes the given cookies as expected in a response header.

Expand Down