update unix extra field
This commit is contained in:
@@ -49,6 +49,14 @@ Dotzip.decode(file)
|
|||||||
* https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.3.TXT
|
* https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.3.TXT
|
||||||
* https://en.wikipedia.org/wiki/ZIP_(file_format)
|
* https://en.wikipedia.org/wiki/ZIP_(file_format)
|
||||||
|
|
||||||
|
### Other implementation
|
||||||
|
|
||||||
|
* http://infozip.sourceforge.net/
|
||||||
|
* https://github.com/kuba--/zip
|
||||||
|
* https://github.com/zip-rs/zip
|
||||||
|
* https://github.com/Stuk/jszip
|
||||||
|
* https://github.com/srikanth-lingala/zip4j
|
||||||
|
|
||||||
## Trademarks
|
## Trademarks
|
||||||
|
|
||||||
> PKWARE, PKZIP, SecureZIP, and PKSFX are registered trademarks of
|
> PKWARE, PKZIP, SecureZIP, and PKSFX are registered trademarks of
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
defmodule Dotzip do
|
defmodule Dotzip do
|
||||||
|
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Elixir Implementation of ZIP File Format. https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.3.TXT
|
|
||||||
|
Elixir Implementation of ZIP File Format.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def decode(data) do
|
def decode(data) do
|
||||||
|
|||||||
9
lib/dotzip/extra_field.ex
Normal file
9
lib/dotzip/extra_field.ex
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
defmodule Dotzip.ExtraField do
|
||||||
|
|
||||||
|
def encode() do
|
||||||
|
end
|
||||||
|
|
||||||
|
def decode() do
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
104
lib/dotzip/extra_field/unix.ex
Normal file
104
lib/dotzip/extra_field/unix.ex
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
defmodule Dotzip.ExtraField.Unix do
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
|
||||||
|
This module encode and decode Unix extra field defined in section
|
||||||
|
4.5.7 of the official documentation.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
defstruct atime: 0, mtime: 0, uid: 0, gid: 0, var: 0
|
||||||
|
|
||||||
|
defp tag() do
|
||||||
|
<<0x00, 0x0d>>
|
||||||
|
end
|
||||||
|
|
||||||
|
defp encode_tag({:ok, data, buffer}) do
|
||||||
|
{:ok, data, <<tag::binary-size(2), buffer::bitstring>>}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp encode_tsize({:ok, data, buffer}) do
|
||||||
|
s = byte_size(buffer)
|
||||||
|
{:ok, data, <<s::size(16), buffer::bitstring>>}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp encode_atime({:ok, %{ :atime => atime } = data, buffer}) do
|
||||||
|
{:ok, data, <<atime::size(32), buffer::bitstring>>}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp encode_mtime({:ok, %{ :mtime => mtime } = data, buffer}) do
|
||||||
|
{:ok, data, <<mtime::size(32), buffer::bitstring>>}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp encode_uid({:ok, %{ :uid => uid } = data, buffer}) do
|
||||||
|
{:ok, data, <<uid::size(16), buffer::bitstring>>}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp encode_gid({:ok, %{ :gid => gid } = data, buffer}) do
|
||||||
|
{:ok, data, <<gid::size(16), buffer::bitstring>>}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp encode_var(data) do
|
||||||
|
{:ok, data, <<>>}
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
|
||||||
|
Encode an Unix Extra field.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def encode(data) do
|
||||||
|
encode_var(data)
|
||||||
|
|> encode_gid()
|
||||||
|
|> encode_uid()
|
||||||
|
|> encode_mtime()
|
||||||
|
|> encode_atime()
|
||||||
|
|> encode_tsize()
|
||||||
|
|> encode_tag()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp decode_tag(<<0x00, 0x0d, rest::bitstring>>) do
|
||||||
|
{:ok, %{}, rest}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp decode_tsize({:ok, data, <<tsize::size(16), rest::bitstring>>}) do
|
||||||
|
{:ok, Map.put(data, :tsize, tsize), rest}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp decode_atime({:ok, data, <<atime::size(32), rest::bitstring>>}) do
|
||||||
|
{:ok, Map.put(data, :atime, atime), rest}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp decode_mtime({:ok, data, <<mtime::size(32), rest::bitstring>>}) do
|
||||||
|
{:ok, Map.put(data, :mtime, mtime), rest}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp decode_uid({:ok, data, <<uid::size(16), rest::bitstring>>}) do
|
||||||
|
{:ok, Map.put(data, :uid, uid), rest}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp decode_gid({:ok, data, <<gid::size(16), rest::bitstring>>}) do
|
||||||
|
{:ok, Map.put(data, :gid, gid ), rest}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp decode_var({:ok, data, rest}) do
|
||||||
|
{:ok, data, rest}
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
|
||||||
|
Decode an Unix Extra field.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decode(bitstring) do
|
||||||
|
decode_tag(bitstring)
|
||||||
|
|> decode_tsize()
|
||||||
|
|> decode_atime()
|
||||||
|
|> decode_mtime()
|
||||||
|
|> decode_uid()
|
||||||
|
|> decode_gid()
|
||||||
|
|> decode_var()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
10
lib/dotzip64.ex
Normal file
10
lib/dotzip64.ex
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
defmodule Dotzip64 do
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
|
||||||
|
Elixir Implementation of ZIP64 File Format.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
14
mix.exs
14
mix.exs
@@ -7,22 +7,26 @@ defmodule Dotzip.MixProject do
|
|||||||
version: "0.1.0",
|
version: "0.1.0",
|
||||||
elixir: "~> 1.11",
|
elixir: "~> 1.11",
|
||||||
start_permanent: Mix.env() == :prod,
|
start_permanent: Mix.env() == :prod,
|
||||||
deps: deps()
|
deps: deps(),
|
||||||
|
|
||||||
|
name: "DotZip",
|
||||||
|
source_url: "https://github.com/niamtokik/dotzip",
|
||||||
|
homepage_url: "https://github.com/niamtokik/dotzip",
|
||||||
|
docs: [
|
||||||
|
main: "DotZip"
|
||||||
|
]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run "mix help compile.app" to learn about applications.
|
|
||||||
def application do
|
def application do
|
||||||
[
|
[
|
||||||
extra_applications: [:logger]
|
extra_applications: [:logger]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run "mix help deps" to learn about dependencies.
|
|
||||||
defp deps do
|
defp deps do
|
||||||
[
|
[
|
||||||
# {:dep_from_hexpm, "~> 0.3.0"},
|
{:ex_doc, "~> 0.24", only: :dev, runtime: false}
|
||||||
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
8
mix.lock
Normal file
8
mix.lock
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
%{
|
||||||
|
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
|
||||||
|
"ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"},
|
||||||
|
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
|
||||||
|
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
|
||||||
|
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
|
||||||
|
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
|
||||||
|
}
|
||||||
17
test/dotzip/extra_field/unix_test.exs
Normal file
17
test/dotzip/extra_field/unix_test.exs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
defmodule Dotzip.ExtraField.UnixTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
test "decode an empty Unix field" do
|
||||||
|
struct = %{atime: 0, gid: 0, mtime: 0, uid: 0, tsize: 12}
|
||||||
|
{:ok, struct, data} = Dotzip.ExtraField.Unix.encode(struct)
|
||||||
|
{:ok, decoded_struct, decoded_data} = Dotzip.ExtraField.Unix.decode(data)
|
||||||
|
assert struct == decoded_struct
|
||||||
|
end
|
||||||
|
|
||||||
|
test "encode an empty Unix field" do
|
||||||
|
data = <<0, 13, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>>
|
||||||
|
{:ok, decoded_struct, _} = Dotzip.ExtraField.Unix.decode(data)
|
||||||
|
{:ok, struct, encoded_data} = Dotzip.ExtraField.Unix.encode(decoded_struct)
|
||||||
|
assert struct == decoded_struct
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user