Skip to content

Commit

Permalink
Add ideal file-sniffer analysis implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
angelikatyborska committed Nov 25, 2023
1 parent 1e49ecd commit 7b90090
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 154 deletions.
2 changes: 1 addition & 1 deletion lib/elixir_analyzer/constants.ex
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ defmodule ElixirAnalyzer.Constants do
dna_encoding_use_tail_call_recursion: "elixir.dna-encoding.use_tail_call_recursion",

# File Sniffer Comments
file_sniffer_use_pattern_matching: "elixir.file-sniffer.use_pattern_matching",
file_sniffer_use_bitstring: "elixir.file-sniffer.use_bitstring",

# Freelancer Rates Comments
freelancer_rates_apply_discount_function_reuse:
Expand Down
154 changes: 8 additions & 146 deletions lib/elixir_analyzer/test_suite/file_sniffer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,155 +6,17 @@ defmodule ElixirAnalyzer.TestSuite.FileSniffer do
alias ElixirAnalyzer.Constants
use ElixirAnalyzer.ExerciseTest

feature "use pattern matching for bmp" do
assert_call "use <<>> to pattern match a bitstring in function body" do
type :essential
find :any
comment Constants.file_sniffer_use_pattern_matching()

form do
<<0x42, 0x4D, _ignore>>
end

form do
<<0x42, 0x4D>>
end

form do
<<0x42::8, 0x4D::8, _ignore>>
end

form do
<<0x42::8, 0x4D::8>>
end

form do
<<0x42::size(8), 0x4D::size(8), _ignore>>
end

form do
<<0x42::size(8), 0x4D::size(8)>>
end
end

feature "use pattern matching for png" do
type :essential
find :any
comment Constants.file_sniffer_use_pattern_matching()

form do
<<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, _ignore>>
end

form do
<<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A>>
end

form do
<<0x89::8, 0x50::8, 0x4E::8, 0x47::8, 0x0D::8, 0x0A::8, 0x1A::8, 0x0A::8, _ignore>>
end

form do
<<0x89::8, 0x50::8, 0x4E::8, 0x47::8, 0x0D::8, 0x0A::8, 0x1A::8, 0x0A::8>>
end

form do
<<0x89::size(8), 0x50::size(8), 0x4E::size(8), 0x47::size(8), 0x0D::size(8), 0x0A::size(8),
0x1A::size(8), 0x0A::size(8), _ignore>>
end

form do
<<0x89::size(8), 0x50::size(8), 0x4E::size(8), 0x47::size(8), 0x0D::size(8), 0x0A::size(8),
0x1A::size(8), 0x0A::size(8)>>
end
comment Constants.file_sniffer_use_bitstring()
called_fn module: Kernel, name: :<<>>
calling_fn module: FileSniffer, name: :type_from_binary
end

feature "use pattern matching for jpg" do
assert_call "use :: in bitstrings to specify segment type when pattern matching in function body" do
type :essential
find :any
comment Constants.file_sniffer_use_pattern_matching()

form do
<<0xFF, 0xD8, 0xFF, _ignore>>
end

form do
<<0xFF, 0xD8, 0xFF>>
end

form do
<<0xFF::8, 0xD8::8, 0xFF::8, _ignore>>
end

form do
<<0xFF::8, 0xD8::8, 0xFF::8>>
end

form do
<<0xFF::size(8), 0xD8::size(8), 0xFF::size(8), _ignore>>
end

form do
<<0xFF::size(8), 0xD8::size(8), 0xFF::size(8)>>
end
end

feature "use pattern matching for gif" do
type :essential
find :any
comment Constants.file_sniffer_use_pattern_matching()

form do
<<0x47, 0x49, 0x46, _ignore>>
end

form do
<<0x47, 0x49, 0x46>>
end

form do
<<0x47::8, 0x49::8, 0x46::8, _ignore>>
end

form do
<<0x47::8, 0x49::8, 0x46::8>>
end

form do
<<0x47::size(8), 0x49::size(8), 0x46::size(8), _ignore>>
end

form do
<<0x47::size(8), 0x49::size(8), 0x46::size(8)>>
end
end

feature "use pattern matching for exe" do
type :essential
find :any
comment Constants.file_sniffer_use_pattern_matching()

form do
<<0x7F, 0x45, 0x4C, 0x46, _ignore>>
end

form do
<<0x7F, 0x45, 0x4C, 0x46>>
end

form do
<<0x7F::8, 0x45::8, 0x4C::8, 0x46::8, _ignore>>
end

form do
<<0x7F::8, 0x45::8, 0x4C::8, 0x46::8>>
end

form do
<<0x7F::size(8), 0x45::size(8), 0x4C::size(8), 0x46::size(8), _ignore>>
end

form do
<<0x7F::size(8), 0x45::size(8), 0x4C::size(8), 0x46::size(8)>>
end
comment Constants.file_sniffer_use_bitstring()
called_fn module: Kernel, name: :"::"
calling_fn module: FileSniffer, name: :type_from_binary
end
end
64 changes: 57 additions & 7 deletions test/elixir_analyzer/test_suite/file_sniffer_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -147,40 +147,90 @@ defmodule ElixirAnalyzer.ExerciseTest.FileSnifferTest do
"image/gif"
end
end
end,
defmodule FileSniffer do
@exe_type "application/octet-stream"
@bmp_type "image/bmp"
@png_type "image/png"
@jpg_type "image/jpg"
@gif_type "image/gif"

def type_from_binary(<<"\dELF", _rest::binary>>), do: @exe_type
def type_from_binary(<<"BM", _rest::binary>>), do: @bmp_type
def type_from_binary(<<"\x89PNG\r\n\x1A\n", _rest::binary>>), do: @png_type
def type_from_binary(<<"\xFF\xD8\xFF", _rest::binary>>), do: @jpg_type
def type_from_binary(<<"GIF", _rest::binary>>), do: @gif_type
end,
defmodule FileSniffer do
def type_from_binary(<<signature::binary-size(2), _rest::binary>>)
when <<0x42, 0x4D>> == signature,
do: "image/bmp"

def type_from_binary(<<signature::binary-size(8), _rest::binary>>)
when <<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A>> == signature,
do: "image/png"

def type_from_binary(<<signature::binary-size(3), _rest::binary>>)
when <<0xFF, 0xD8, 0xFF>> == signature,
do: "image/jpg"

def type_from_binary(<<signature::binary-size(3), _rest::binary>>)
when <<0x47, 0x49, 0x46>> == signature,
do: "image/gif"

def type_from_binary(<<signature::binary-size(4), _rest::binary>>)
when <<0x7F, 0x45, 0x4C, 0x46>> == signature,
do: "application/octet-stream"

def type_from_binary(_binary), do: nil
end,
defmodule FileSniffer do
def type_from_binary(<<66, 77, 30, _::binary>>), do: type_from_extension("bmp")

def type_from_binary(<<71, 73, 70, 56, 57, 97, _::binary>>),
do: type_from_extension("gif")

def type_from_binary(<<255, 216, 255, 219, _::binary>>), do: type_from_extension("jpg")

def type_from_binary(<<137, 80, 78, 71, 13, 10, 26, 10, _::binary>>),
do: type_from_extension("png")

def type_from_binary(<<127, 69, 76, 70, _::binary>>), do: type_from_extension("exe")
def type_from_binary(file), do: type_from_extension(file)
end
]
end

test_exercise_analysis "doesn't use pattern matching",
comments: [Constants.file_sniffer_use_pattern_matching()] do
test_exercise_analysis "doesn't use <<>> nor ::",
comments: [Constants.file_sniffer_use_bitstring()] do
[
defmodule FileSniffer do
def type_from_binary(file) do
cond do
String.starts_with?(file, "BM") ->
"image/bmp"

String.starts_with?(file, <<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A>>) ->
String.starts_with?(file, "\x89PNG\r\n\x1A\n") ->
"image/png"

String.starts_with?(file, <<0xFF, 0xD8, 0xFF>>) ->
String.starts_with?(file, "\xFF\xD8\xFF") ->
"image/jpg"

String.starts_with?(file, "GIF") ->
"image/gif"

String.starts_with?(file, <<0x7F, 0x45, 0x4C, 0x46>>) ->
String.starts_with?(file, "\dELF") ->
"application/octet-stream"
end
end
end,
defmodule FileSniffer do
def type_from_binary("BM" <> _rest), do: "image/bmp"

def type_from_binary(<<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, _::binary>>),
def type_from_binary("\x89PNG\r\n\x1A\n" <> _rest),
do: "image/png"

def type_from_binary(<<0xFF, 0xD8, 0xFF, _::binary>>), do: "image/jpg"
def type_from_binary("\xFF\xD8\xFF" <> _rest), do: "image/jpg"
def type_from_binary("GIF" <> _rest), do: "image/gif"
def type_from_binary("\dELF" <> _rest), do: "application/octet-stream"
end
Expand Down

0 comments on commit 7b90090

Please sign in to comment.