Skip to content

Commit 3766a4e

Browse files
committed
Wrap options into a SensitiveData struct when crossing process boundaries, closes #340
1 parent f9266ad commit 3766a4e

4 files changed

Lines changed: 48 additions & 6 deletions

File tree

integration_test/cases/after_connect_test.exs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,4 +393,41 @@ defmodule AfterConnectTest do
393393

394394
assert [connect: [_], handle_status: _, handle_status: _] = A.record(agent)
395395
end
396+
397+
test "after_connect raises" do
398+
err = RuntimeError.exception("oops")
399+
400+
stack = [
401+
{:ok, :state},
402+
{:idle, :state},
403+
{:error, err, :new_state},
404+
{:ok, %Q{}, %R{}, :newer_state},
405+
{:idle, :newer_state},
406+
{:ok, %Q{}, %R{}, :newest_state}
407+
]
408+
409+
{:ok, agent} = A.start_link(stack)
410+
parent = self()
411+
412+
after_connect = fn conn ->
413+
send(parent, {:after_connect, self()})
414+
_ = Process.put(:agent, agent)
415+
416+
case P.execute(conn, %Q{}, [:after_connect]) do
417+
{:error, err} -> raise err
418+
{:ok, _, _} -> :ok
419+
end
420+
end
421+
422+
secret = "SHOULD NOT LEAK"
423+
opts = [after_connect: after_connect, agent: agent, parent: self(), secret: secret]
424+
425+
refute ExUnit.CaptureLog.capture_log(fn ->
426+
{:ok, _pool} = P.start_link(opts)
427+
428+
assert_receive {:after_connect, task}
429+
ref = Process.monitor(task)
430+
assert_receive {:DOWN, ^ref, _, _, {%RuntimeError{}, _}}
431+
end) =~ secret
432+
end
396433
end

lib/db_connection.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
defmodule DBConnection.SensitiveData do
2+
@moduledoc false
3+
@derive {Inspect, only: []}
4+
defstruct [:data]
5+
end
6+
17
defmodule DBConnection.Stream do
28
defstruct [:conn, :query, :params, :opts]
39

lib/db_connection/connection.ex

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ defmodule DBConnection.Connection do
99
alias DBConnection.Util
1010

1111
@timeout 15_000
12-
@sensitive_opts [:parameters, :hostname, :port, :username, :password, :database]
1312

1413
@doc false
1514
def start_link(mod, opts, pool, tag) do
1615
start_opts = Keyword.take(opts, [:debug, :spawn_opt])
17-
:gen_statem.start_link(__MODULE__, {mod, opts, pool, tag}, start_opts)
16+
sensitive_options = %DBConnection.SensitiveData{data: opts}
17+
:gen_statem.start_link(__MODULE__, {mod, sensitive_options, pool, tag}, start_opts)
1818
end
1919

2020
@doc false
@@ -48,7 +48,7 @@ defmodule DBConnection.Connection do
4848

4949
@doc false
5050
@impl :gen_statem
51-
def init({mod, opts, pool, tag}) do
51+
def init({mod, %DBConnection.SensitiveData{data: opts}, pool, tag}) do
5252
pool_index = Keyword.get(opts, :pool_index)
5353
label = if pool_index, do: "db_conn_#{pool_index}", else: "db_conn"
5454
Util.set_label(label)
@@ -235,7 +235,6 @@ defmodule DBConnection.Connection do
235235
case apply(mod, :checkout, [state]) do
236236
{:ok, state} ->
237237
opts = [timeout: timeout] ++ opts
238-
opts = Keyword.drop(opts, @sensitive_opts)
239238
{pid, ref} = DBConnection.Task.run_child(mod, state, after_connect, opts)
240239
timer = start_timer(pid, timeout)
241240
s = %{s | client: {ref, :after_connect}, timer: timer, state: state}

lib/db_connection/task.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ defmodule DBConnection.Task do
55
require DBConnection.Holder
66

77
def run_child(mod, state, fun, opts) do
8-
arg = [fun, self(), opts]
8+
arg = [fun, self(), %DBConnection.SensitiveData{data: opts}]
99
{:ok, pid} = Task.Supervisor.start_child(@name, __MODULE__, :init, arg)
1010
ref = Process.monitor(pid)
1111
_ = DBConnection.Holder.update(pid, ref, mod, state)
1212
{pid, ref}
1313
end
1414

15-
def init(fun, parent, opts) do
15+
def init(fun, parent, %DBConnection.SensitiveData{data: opts}) do
1616
try do
1717
Process.link(parent)
1818
catch

0 commit comments

Comments
 (0)