From ba4f622c7903c4b360378e06e702bee861c5ef4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20F=C3=B6hring?= Date: Sat, 4 May 2024 21:28:04 +0200 Subject: [PATCH] Rework last merge to work with older Elixir versions Refs #1127 --- lib/credo/check/warning/forbidden_module.ex | 36 +++++++------------- lib/credo/check/warning/leaky_environment.ex | 24 +++++++------ lib/credo/check/warning/unsafe_exec.ex | 9 +++-- 3 files changed, 29 insertions(+), 40 deletions(-) diff --git a/lib/credo/check/warning/forbidden_module.ex b/lib/credo/check/warning/forbidden_module.ex index ab9a747d1..29745758f 100644 --- a/lib/credo/check/warning/forbidden_module.ex +++ b/lib/credo/check/warning/forbidden_module.ex @@ -25,18 +25,18 @@ defmodule Credo.Check.Warning.ForbiddenModule do @impl Credo.Check def run(%SourceFile{} = source_file, params) do - modules = Params.get(params, :modules, __MODULE__) - - modules = - if Keyword.keyword?(modules) do - Enum.map(modules, fn {key, value} -> {Name.full(key), value} end) - else - Enum.map(modules, fn key -> {Name.full(key), nil} end) - end + forbidden_modules = + params + |> Params.get(:modules, __MODULE__) + |> Enum.map(fn + {key, value} -> {Name.full(key), value} + key -> {Name.full(key), nil} + end) + |> Map.new() Credo.Code.prewalk( source_file, - &traverse(&1, &2, modules, IssueMeta.for(source_file, params)) + &traverse(&1, &2, forbidden_modules, IssueMeta.for(source_file, params)) ) end @@ -58,6 +58,7 @@ defmodule Credo.Check.Warning.ForbiddenModule do Enum.reduce(aliases, issues, fn {:__aliases__, meta, module}, issues -> full_module = Name.full([base_alias, module]) module = Name.full(module) + put_issue_if_forbidden(issues, issue_meta, meta, full_module, forbidden_modules, module) end) @@ -67,21 +68,15 @@ defmodule Credo.Check.Warning.ForbiddenModule do defp traverse(ast, issues, _, _), do: {ast, issues} defp put_issue_if_forbidden(issues, issue_meta, meta, module, forbidden_modules, trigger) do - forbidden_module_names = Enum.map(forbidden_modules, &elem(&1, 0)) - - if found_module?(forbidden_module_names, module) do + if Map.has_key?(forbidden_modules, module) do [issue_for(issue_meta, meta, module, forbidden_modules, trigger) | issues] else issues end end - defp found_module?(forbidden_module_names, module) do - Enum.member?(forbidden_module_names, module) - end - defp issue_for(issue_meta, meta, module, forbidden_modules, trigger) do - message = message(forbidden_modules, module) || "The `#{trigger}` module is not allowed." + message = forbidden_modules[module] || "The `#{trigger}` module is not allowed." format_issue( issue_meta, @@ -91,11 +86,4 @@ defmodule Credo.Check.Warning.ForbiddenModule do column: meta[:column] ) end - - defp message(forbidden_modules, module) do - Enum.find_value(forbidden_modules, fn - {^module, message} -> message - _ -> nil - end) - end end diff --git a/lib/credo/check/warning/leaky_environment.ex b/lib/credo/check/warning/leaky_environment.ex index 1a56628f5..94bbac92d 100644 --- a/lib/credo/check/warning/leaky_environment.ex +++ b/lib/credo/check/warning/leaky_environment.ex @@ -27,8 +27,7 @@ defmodule Credo.Check.Warning.LeakyEnvironment do Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta)) end - @colon_and_dot_length 2 - defp traverse({{:., _, call}, meta, args} = ast, issues, issue_meta) do + defp traverse({{:., meta, call}, _, args} = ast, issues, issue_meta) do case get_forbidden_call(call, args) do nil -> {ast, issues} @@ -36,13 +35,10 @@ defmodule Credo.Check.Warning.LeakyEnvironment do {trigger, meta} -> {ast, [issue_for(issue_meta, meta, trigger) | issues]} - trigger -> + "" <> trigger -> [module, _function] = call - len = module |> Atom.to_string() |> String.length() - column = meta[:column] - len - @colon_and_dot_length - meta = Keyword.put(meta, :column, column) - {ast, [issue_for(issue_meta, meta, trigger) | issues]} + {ast, [issue_for(issue_meta, meta, trigger, module) | issues]} end end @@ -61,8 +57,7 @@ defmodule Credo.Check.Warning.LeakyEnvironment do end end - defp get_forbidden_call([:erlang, :open_port], [_, opts]) - when is_list(opts) do + defp get_forbidden_call([:erlang, :open_port], [_, opts]) when is_list(opts) do if not Keyword.has_key?(opts, :env) do ":erlang.open_port" end @@ -72,13 +67,20 @@ defmodule Credo.Check.Warning.LeakyEnvironment do nil end - defp issue_for(issue_meta, meta, trigger) do + defp issue_for(issue_meta, meta, trigger, erlang_module \\ nil) do + column = + if erlang_module do + meta[:column] - String.length(":#{erlang_module}") + else + meta[:column] + end + format_issue( issue_meta, message: "When using #{trigger}, clear or overwrite sensitive environment variables.", trigger: trigger, line_no: meta[:line], - column: meta[:column] + column: column ) end end diff --git a/lib/credo/check/warning/unsafe_exec.ex b/lib/credo/check/warning/unsafe_exec.ex index 373b81074..9796dbce2 100644 --- a/lib/credo/check/warning/unsafe_exec.ex +++ b/lib/credo/check/warning/unsafe_exec.ex @@ -34,10 +34,11 @@ defmodule Credo.Check.Warning.UnsafeExec do Credo.Code.prewalk(source_file, &traverse(&1, &2, issue_meta)) end - defp traverse({{:., _loc, call}, meta, args} = ast, issues, issue_meta) do + defp traverse({{:., meta, call}, _, args} = ast, issues, issue_meta) do case get_forbidden_call(call, args) do {bad, suggestion, trigger} -> [module, _function] = call + {ast, [issue_for(bad, suggestion, trigger, meta, module, issue_meta) | issues]} nil -> @@ -66,10 +67,8 @@ defmodule Credo.Check.Warning.UnsafeExec do nil end - @colon_and_dot_length 2 - defp issue_for(call, suggestion, trigger, meta, module, issue_meta) do - len = module |> Atom.to_string() |> String.length() - column = meta[:column] - len - @colon_and_dot_length + defp issue_for(call, suggestion, trigger, meta, erlang_module, issue_meta) do + column = meta[:column] - String.length(":#{erlang_module}") format_issue(issue_meta, message: "Prefer #{suggestion} over #{call} to prevent command injection.",