Skip to content

Commit 08c5c9e

Browse files
authored
Prevent crash when using unknown hex repo (#127)
1 parent dd90f14 commit 08c5c9e

File tree

4 files changed

+120
-2
lines changed

4 files changed

+120
-2
lines changed

lib/mix_dependency_submission/scm/hex/scm.ex

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ defmodule MixDependencySubmission.SCM.Hex.SCM do
4040
qualifiers =
4141
case repository_url do
4242
"https://repo.hex.pm" -> %{}
43+
# Unknown repository URL, do not include it in the qualifiers
44+
# to avoid exposing it in the PURL.
45+
nil -> %{}
4346
^repository_url -> %{"repository_url" => repository_url}
4447
end
4548

@@ -102,16 +105,31 @@ defmodule MixDependencySubmission.SCM.Hex.SCM do
102105
end
103106

104107
qualifiers = %{
105-
"checksum" => "sha256:#{outer_checksum}",
106-
"download_url" => "#{repository_url}/tarballs/#{package_name}-#{version}.tar.gz"
108+
"checksum" => "sha256:#{outer_checksum}"
107109
}
108110

109111
qualifiers =
110112
case repository_url do
111113
"https://repo.hex.pm" -> qualifiers
114+
# Unknown repository URL, do not include it in the qualifiers
115+
# to avoid exposing it in the PURL.
116+
nil -> qualifiers
112117
^repository_url -> Map.put(qualifiers, "repository_url", repository_url)
113118
end
114119

120+
qualifiers =
121+
case repository_url do
122+
nil ->
123+
qualifiers
124+
125+
^repository_url ->
126+
Map.put(
127+
qualifiers,
128+
"download_url",
129+
"#{repository_url}/tarballs/#{package_name}-#{version}.tar.gz"
130+
)
131+
end
132+
115133
Purl.new!(%Purl{
116134
type: "hex",
117135
namespace: hex_namespace(repo),

test/fixtures/private_repo/mix.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
defmodule AppNameToReplace.MixProject do
2+
use Mix.Project
3+
4+
def project do
5+
[
6+
app: :app_name_to_replace,
7+
version: "0.0.0-dev",
8+
deps: [
9+
# Using 0ban instead of oban to not confuse actual oban users
10+
{:oban_pro, "~> 1.5", repo: "0ban"}
11+
]
12+
]
13+
end
14+
end

test/fixtures/private_repo/mix.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
%{
2+
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
3+
"decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"},
4+
"ecto": {:hex, :ecto, "3.12.5", "4a312960ce612e17337e7cefcf9be45b95a3be6b36b6f94dfb3d8c361d631866", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6eb18e80bef8bb57e17f5a7f068a1719fbda384d40fc37acb8eb8aeca493b6ea"},
5+
"ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"},
6+
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
7+
"oban": {:hex, :oban, "2.19.4", "045adb10db1161dceb75c254782f97cdc6596e7044af456a59decb6d06da73c1", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:igniter, "~> 0.5", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5fcc6219e6464525b808d97add17896e724131f498444a292071bf8991c99f97"},
8+
"oban_pro": {:hex, :oban_pro, "1.5.4", "15421189431d1d9d1c0bb614ea7a153a36b3036febfcb24f766deb9c725bcfab", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:oban, "~> 2.19", [hex: :oban, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}], "0ban", "f4e57237b17110f9ec55d332aa0c090e17137d2328d8a787350b1772ae64eb57"},
9+
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
10+
}

test/mix_dependency_submission_test.exs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,82 @@ defmodule MixDependencySubmissionTest do
5959
)
6060
end
6161

62+
@tag :tmp_dir
63+
@tag fixture_app: "private_repo"
64+
test "generates valid submission for 'private_repo' fixture", %{app_path: app_path} do
65+
Mix.Task.rerun("hex.repo", ["remove", "0ban"])
66+
67+
assert %Submission{manifests: %{"mix.exs" => %Submission.Manifest{resolved: resolved}}} =
68+
MixDependencySubmission.submission(
69+
github_job_id: "github_job_id",
70+
github_workflow: "github_workflow",
71+
sha: "sha",
72+
ref: "ref",
73+
project_path: app_path,
74+
paths_relative_to: app_path,
75+
install_deps?: false
76+
)
77+
78+
assert %{
79+
"oban_pro" => %Dependency{
80+
scope: :runtime,
81+
metadata: %{},
82+
dependencies: _deps,
83+
relationship: :direct,
84+
package_url: %Purl{
85+
type: "hex",
86+
namespace: ["0ban"],
87+
name: "oban_pro",
88+
version: "1.5.4",
89+
qualifiers: %{
90+
"checksum" => "sha256:f4e57237b17110f9ec55d332aa0c090e17137d2328d8a787350b1772ae64eb57"
91+
}
92+
}
93+
}
94+
} = resolved
95+
96+
Mix.Task.rerun("hex.repo", [
97+
"add",
98+
"0ban",
99+
"https://getoban.pro/repo",
100+
"--fetch-public-key",
101+
"SHA256:4/OSKi0NRF91QVVXlGAhb/BIMLnK8NHcx/EWs+aIWPc",
102+
"--auth-key",
103+
"invalid"
104+
])
105+
106+
assert %Submission{manifests: %{"mix.exs" => %Submission.Manifest{resolved: resolved}}} =
107+
MixDependencySubmission.submission(
108+
github_job_id: "github_job_id",
109+
github_workflow: "github_workflow",
110+
sha: "sha",
111+
ref: "ref",
112+
project_path: app_path,
113+
paths_relative_to: app_path,
114+
install_deps?: false
115+
)
116+
117+
assert %{
118+
"oban_pro" => %Dependency{
119+
scope: :runtime,
120+
metadata: %{},
121+
dependencies: _deps,
122+
relationship: :direct,
123+
package_url: %Purl{
124+
type: "hex",
125+
namespace: ["0ban"],
126+
name: "oban_pro",
127+
version: "1.5.4",
128+
qualifiers: %{
129+
"checksum" => "sha256:f4e57237b17110f9ec55d332aa0c090e17137d2328d8a787350b1772ae64eb57",
130+
"download_url" => "https://getoban.pro/repo/tarballs/oban_pro-1.5.4.tar.gz",
131+
"repository_url" => "https://getoban.pro/repo"
132+
}
133+
}
134+
}
135+
} = resolved
136+
end
137+
62138
@tag :tmp_dir
63139
test "empty submission for project without mix.exs", %{tmp_dir: tmp_dir} do
64140
Util.in_project(tmp_dir, fn _mix_module ->

0 commit comments

Comments
 (0)