diff --git a/lib/plug/conn.ex b/lib/plug/conn.ex index 92ea6653..2d73ce33 100644 --- a/lib/plug/conn.ex +++ b/lib/plug/conn.ex @@ -658,11 +658,12 @@ defmodule Plug.Conn do conn end - def merge_resp_headers(%Conn{resp_headers: current} = conn, headers) do + def merge_resp_headers(%Conn{resp_headers: current, adapter: adapter} = conn, headers) do headers = - Enum.reduce headers, current, fn - {key, value}, acc when is_binary(key) and is_binary(value) -> - List.keystore(acc, key, 0, {key, value}) + Enum.reduce headers, current, fn {key, value}, acc when is_binary(key) and is_binary(value) -> + validate_header_key_if_test!(adapter, key) + validate_header_value!(key, value) + List.keystore(acc, key, 0, {key, value}) end %{conn | resp_headers: headers} end diff --git a/test/plug/conn_test.exs b/test/plug/conn_test.exs index 961854e4..47ce0af9 100644 --- a/test/plug/conn_test.exs +++ b/test/plug/conn_test.exs @@ -409,6 +409,16 @@ defmodule Plug.ConnTest do end end + test "merge_resp_header/3 raises when invalid header value given" do + assert_raise Plug.Conn.InvalidHeaderError, ~S[value for header "x-sample" contains control feed (\r) or newline (\n): "value\rBAR"], fn -> + merge_resp_headers(conn(:get, "foo"), [{"x-sample", "value\rBAR"}]) + end + + assert_raise Plug.Conn.InvalidHeaderError, ~S[value for header "x-sample" contains control feed (\r) or newline (\n): "value\n\nBAR"], fn -> + merge_resp_headers(conn(:get, "foo"), [{"x-sample", "value\n\nBAR"}]) + end + end + test "merge_resp_headers/3" do conn1 = merge_resp_headers(conn(:head, "/foo"), %{"x-foo" => "bar", "x-bar" => "baz"}) assert get_resp_header(conn1, "x-foo") == ["bar"]