dependabot-hex 0.95.47 → 0.95.48

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +0,0 @@
1
- defmodule Jason.Fragment do
2
- defstruct [:encode]
3
-
4
- def new(iodata) when is_list(iodata) or is_binary(iodata) do
5
- %__MODULE__{encode: fn _ -> iodata end}
6
- end
7
-
8
- def new(encode) when is_function(encode, 1) do
9
- %__MODULE__{encode: encode}
10
- end
11
- end
@@ -1,90 +0,0 @@
1
- defmodule Jason.Helpers do
2
- @moduledoc """
3
- Provides macro facilities for partial compile-time encoding of JSON.
4
- """
5
-
6
- alias Jason.{Codegen, Fragment}
7
-
8
- @doc ~S"""
9
- Encodes a JSON map from a compile-time keyword.
10
-
11
- Encodes the keys at compile time and strives to create as flat iodata
12
- structure as possible to achieve maximum efficiency. Does encoding
13
- right at the call site, but returns an `%Jason.Fragment{}` struct
14
- that needs to be passed to one of the "main" encoding functions -
15
- for example `Jason.encode/2` for final encoding into JSON - this
16
- makes it completely transparent for most uses.
17
-
18
- Only allows keys that do not require escaping in any of the supported
19
- encoding modes. This means only ASCII characters from the range
20
- 0x1F..0x7F excluding '\', '/' and '"' are allowed - this also excludes
21
- all control characters like newlines.
22
-
23
- Preserves the order of the keys.
24
-
25
- ## Example
26
-
27
- iex> fragment = json_map(foo: 1, bar: 2)
28
- iex> Jason.encode!(fragment)
29
- "{\"foo\":1,\"bar\":2}"
30
-
31
- """
32
- defmacro json_map(kv) do
33
- escape = quote(do: escape)
34
- encode_map = quote(do: encode_map)
35
- encode_args = [escape, encode_map]
36
- kv_iodata = Codegen.build_kv_iodata(Macro.expand(kv, __CALLER__), encode_args)
37
-
38
- quote do
39
- %Fragment{
40
- encode: fn {unquote(escape), unquote(encode_map)} ->
41
- unquote(kv_iodata)
42
- end
43
- }
44
- end
45
- end
46
-
47
- @doc ~S"""
48
- Encodes a JSON map from a variable containing a map and a compile-time
49
- list of keys.
50
-
51
- It is equivalent to calling `Map.take/2` before encoding. Otherwise works
52
- similar to `json_map/2`.
53
-
54
- ## Example
55
-
56
- iex> map = %{a: 1, b: 2, c: 3}
57
- iex> fragment = json_map_take(map, [:c, :b])
58
- iex> Jason.encode!(fragment)
59
- "{\"c\":3,\"b\":2}"
60
-
61
- """
62
- defmacro json_map_take(map, take) do
63
- take = Macro.expand(take, __CALLER__)
64
- kv = Enum.map(take, &{&1, generated_var(&1, Codegen)})
65
- escape = quote(do: escape)
66
- encode_map = quote(do: encode_map)
67
- encode_args = [escape, encode_map]
68
- kv_iodata = Codegen.build_kv_iodata(kv, encode_args)
69
-
70
- quote do
71
- case unquote(map) do
72
- %{unquote_splicing(kv)} ->
73
- %Fragment{
74
- encode: fn {unquote(escape), unquote(encode_map)} ->
75
- unquote(kv_iodata)
76
- end
77
- }
78
-
79
- other ->
80
- raise ArgumentError,
81
- "expected a map with keys: #{unquote(inspect(take))}, got: #{inspect(other)}"
82
- end
83
- end
84
- end
85
-
86
- # The same as Macro.var/2 except it sets generated: true
87
- defp generated_var(name, context) do
88
- {name, [generated: true], context}
89
- end
90
- end
@@ -1,228 +0,0 @@
1
- defmodule Jason do
2
- @moduledoc """
3
- A blazing fast JSON parser and generator in pure Elixir.
4
- """
5
-
6
- alias Jason.{Encode, Decoder, DecodeError, EncodeError, Formatter}
7
-
8
- @type escape :: :json | :unicode_safe | :html_safe | :javascript_safe
9
- @type maps :: :naive | :strict
10
-
11
- @type encode_opt :: {:escape, escape} | {:maps, maps} | {:pretty, true | Formatter.opts()}
12
-
13
- @type keys :: :atoms | :atoms! | :strings | :copy | (String.t() -> term)
14
-
15
- @type strings :: :reference | :copy
16
-
17
- @type decode_opt :: {:keys, keys} | {:strings, strings}
18
-
19
- @doc """
20
- Parses a JSON value from `input` iodata.
21
-
22
- ## Options
23
-
24
- * `:keys` - controls how keys in objects are decoded. Possible values are:
25
-
26
- * `:strings` (default) - decodes keys as binary strings,
27
- * `:atoms` - keys are converted to atoms using `String.to_atom/1`,
28
- * `:atoms!` - keys are converted to atoms using `String.to_existing_atom/1`,
29
- * custom decoder - additionally a function accepting a string and returning a key
30
- is accepted.
31
-
32
- * `:strings` - controls how strings (including keys) are decoded. Possible values are:
33
-
34
- * `:reference` (default) - when possible tries to create a sub-binary into the original
35
- * `:copy` - always copies the strings. This option is especially useful when parts of the
36
- decoded data will be stored for a long time (in ets or some process) to avoid keeping
37
- the reference to the original data.
38
-
39
- ## Decoding keys to atoms
40
-
41
- The `:atoms` option uses the `String.to_atom/1` call that can create atoms at runtime.
42
- Since the atoms are not garbage collected, this can pose a DoS attack vector when used
43
- on user-controlled data.
44
-
45
- ## Examples
46
-
47
- iex> Jason.decode("{}")
48
- {:ok, %{}}
49
-
50
- iex> Jason.decode("invalid")
51
- {:error, %Jason.DecodeError{data: "invalid", position: 0, token: nil}}
52
- """
53
- @spec decode(iodata, [decode_opt]) :: {:ok, term} | {:error, DecodeError.t()}
54
- def decode(input, opts \\ []) do
55
- input = IO.iodata_to_binary(input)
56
- Decoder.parse(input, format_decode_opts(opts))
57
- end
58
-
59
- @doc """
60
- Parses a JSON value from `input` iodata.
61
-
62
- Similar to `decode/2` except it will unwrap the error tuple and raise
63
- in case of errors.
64
-
65
- ## Examples
66
-
67
- iex> Jason.decode!("{}")
68
- %{}
69
-
70
- iex> Jason.decode!("invalid")
71
- ** (Jason.DecodeError) unexpected byte at position 0: 0x69 ('i')
72
-
73
- """
74
- @spec decode!(iodata, [decode_opt]) :: term | no_return
75
- def decode!(input, opts \\ []) do
76
- case decode(input, opts) do
77
- {:ok, result} -> result
78
- {:error, error} -> raise error
79
- end
80
- end
81
-
82
- @doc """
83
- Generates JSON corresponding to `input`.
84
-
85
- The generation is controlled by the `Jason.Encoder` protocol,
86
- please refer to the module to read more on how to define the protocol
87
- for custom data types.
88
-
89
- ## Options
90
-
91
- * `:escape` - controls how strings are encoded. Possible values are:
92
-
93
- * `:json` (default) - the regular JSON escaping as defined by RFC 7159.
94
- * `:javascript_safe` - additionally escapes the LINE SEPARATOR (U+2028)
95
- and PARAGRAPH SEPARATOR (U+2029) characters to make the produced JSON
96
- valid JavaSciprt.
97
- * `:html_safe` - similar to `:javascript`, but also escapes the `/`
98
- caracter to prevent XSS.
99
- * `:unicode_safe` - escapes all non-ascii characters.
100
-
101
- * `:maps` - controls how maps are encoded. Possible values are:
102
-
103
- * `:strict` - checks the encoded map for duplicate keys and raises
104
- if they appear. For example `%{:foo => 1, "foo" => 2}` would be
105
- rejected, since both keys would be encoded to the string `"foo"`.
106
- * `:naive` (default) - does not perform the check.
107
-
108
- * `:pretty` - controls pretty printing of the output. Possible values are:
109
-
110
- * `true` to pretty print with default configuration
111
- * a keyword of options as specified by `Jason.Formatter.pretty_print/2`.
112
-
113
- ## Examples
114
-
115
- iex> Jason.encode(%{a: 1})
116
- {:ok, ~S|{"a":1}|}
117
-
118
- iex> Jason.encode("\\xFF")
119
- {:error, %Jason.EncodeError{message: "invalid byte 0xFF in <<255>>"}}
120
-
121
- """
122
- @spec encode(term, [encode_opt]) ::
123
- {:ok, String.t()} | {:error, EncodeError.t() | Exception.t()}
124
- def encode(input, opts \\ []) do
125
- case do_encode(input, format_encode_opts(opts)) do
126
- {:ok, result} -> {:ok, IO.iodata_to_binary(result)}
127
- {:error, error} -> {:error, error}
128
- end
129
- end
130
-
131
- @doc """
132
- Generates JSON corresponding to `input`.
133
-
134
- Similar to `encode/1` except it will unwrap the error tuple and raise
135
- in case of errors.
136
-
137
- ## Examples
138
-
139
- iex> Jason.encode!(%{a: 1})
140
- ~S|{"a":1}|
141
-
142
- iex> Jason.encode!("\\xFF")
143
- ** (Jason.EncodeError) invalid byte 0xFF in <<255>>
144
-
145
- """
146
- @spec encode!(term, [encode_opt]) :: String.t() | no_return
147
- def encode!(input, opts \\ []) do
148
- case do_encode(input, format_encode_opts(opts)) do
149
- {:ok, result} -> IO.iodata_to_binary(result)
150
- {:error, error} -> raise error
151
- end
152
- end
153
-
154
- @doc """
155
- Generates JSON corresponding to `input` and returns iodata.
156
-
157
- This function should be preferred to `encode/2`, if the generated
158
- JSON will be handed over to one of the IO functions or sent
159
- over the socket. The Erlang runtime is able to leverage vectorised
160
- writes and avoid allocating a continuous buffer for the whole
161
- resulting string, lowering memory use and increasing performance.
162
-
163
- ## Examples
164
-
165
- iex> {:ok, iodata} = Jason.encode_to_iodata(%{a: 1})
166
- iex> IO.iodata_to_binary(iodata)
167
- ~S|{"a":1}|
168
-
169
- iex> Jason.encode_to_iodata("\\xFF")
170
- {:error, %Jason.EncodeError{message: "invalid byte 0xFF in <<255>>"}}
171
-
172
- """
173
- @spec encode_to_iodata(term, [encode_opt]) ::
174
- {:ok, iodata} | {:error, EncodeError.t() | Exception.t()}
175
- def encode_to_iodata(input, opts \\ []) do
176
- do_encode(input, format_encode_opts(opts))
177
- end
178
-
179
- @doc """
180
- Generates JSON corresponding to `input` and returns iodata.
181
-
182
- Similar to `encode_to_iodata/1` except it will unwrap the error tuple
183
- and raise in case of errors.
184
-
185
- ## Examples
186
-
187
- iex> iodata = Jason.encode_to_iodata!(%{a: 1})
188
- iex> IO.iodata_to_binary(iodata)
189
- ~S|{"a":1}|
190
-
191
- iex> Jason.encode_to_iodata!("\\xFF")
192
- ** (Jason.EncodeError) invalid byte 0xFF in <<255>>
193
-
194
- """
195
- @spec encode_to_iodata!(term, [encode_opt]) :: iodata | no_return
196
- def encode_to_iodata!(input, opts \\ []) do
197
- case do_encode(input, format_encode_opts(opts)) do
198
- {:ok, result} -> result
199
- {:error, error} -> raise error
200
- end
201
- end
202
-
203
- defp do_encode(input, %{pretty: true} = opts) do
204
- case Encode.encode(input, opts) do
205
- {:ok, encoded} -> {:ok, Formatter.pretty_print_to_iodata(encoded)}
206
- other -> other
207
- end
208
- end
209
-
210
- defp do_encode(input, %{pretty: pretty} = opts) when pretty !== false do
211
- case Encode.encode(input, opts) do
212
- {:ok, encoded} -> {:ok, Formatter.pretty_print_to_iodata(encoded, pretty)}
213
- other -> other
214
- end
215
- end
216
-
217
- defp do_encode(input, opts) do
218
- Encode.encode(input, opts)
219
- end
220
-
221
- defp format_encode_opts(opts) do
222
- Enum.into(opts, %{escape: :json, maps: :naive})
223
- end
224
-
225
- defp format_decode_opts(opts) do
226
- Enum.into(opts, %{keys: :strings, strings: :reference})
227
- end
228
- end
@@ -1,92 +0,0 @@
1
- defmodule Jason.Mixfile do
2
- use Mix.Project
3
-
4
- @version "1.1.2"
5
-
6
- def project() do
7
- [
8
- app: :jason,
9
- version: @version,
10
- elixir: "~> 1.4",
11
- start_permanent: Mix.env() == :prod,
12
- consolidate_protocols: Mix.env() != :test,
13
- deps: deps(),
14
- aliases: aliases(),
15
- preferred_cli_env: ["bench.encode": :bench, "bench.decode": :bench, docs: :docs],
16
- dialyzer: dialyzer(),
17
- description: description(),
18
- package: package(),
19
- docs: docs()
20
- ]
21
- end
22
-
23
- def application() do
24
- [
25
- extra_applications: []
26
- ]
27
- end
28
-
29
- defp deps() do
30
- [
31
- {:decimal, "~> 1.0", optional: true},
32
- {:benchee, "~> 0.8", only: :bench},
33
- {:benchee_html, "~> 0.1", only: :bench, github: "michalmuskala/benchee_html"},
34
- {:poison, "~> 3.0", only: :bench},
35
- {:exjsx, "~> 4.0", only: :bench},
36
- {:tiny, "~> 1.0", only: :bench},
37
- {:jsone, "~> 1.4", only: :bench},
38
- {:jiffy, "~> 0.14", only: :bench},
39
- {:json, "~> 1.0", only: :bench},
40
- {:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false},
41
- {:ex_doc, "~> 0.18", only: :docs},
42
- ] ++ maybe_stream_data()
43
- end
44
-
45
- defp maybe_stream_data() do
46
- if Version.match?(System.version(), "~> 1.5") do
47
- [{:stream_data, "~> 0.4", only: :test}]
48
- else
49
- []
50
- end
51
- end
52
-
53
- defp aliases() do
54
- [
55
- "bench.encode": ["run bench/encode.exs"],
56
- "bench.decode": ["run bench/decode.exs"]
57
- ]
58
- end
59
-
60
- defp dialyzer() do
61
- [
62
- ignore_warnings: "dialyzer.ignore"
63
- ]
64
- end
65
-
66
- defp description() do
67
- """
68
- A blazing fast JSON parser and generator in pure Elixir.
69
- """
70
- end
71
-
72
- defp package() do
73
- [
74
- maintainers: ["Michał Muskała"],
75
- licenses: ["Apache 2.0"],
76
- links: %{"GitHub" => "https://github.com/michalmuskala/jason"}
77
- ]
78
- end
79
-
80
- defp docs() do
81
- [
82
- main: "readme",
83
- name: "Jason",
84
- source_ref: "v#{@version}",
85
- canonical: "http://hexdocs.pm/jason",
86
- source_url: "https://github.com/michalmuskala/jason",
87
- extras: [
88
- "README.md"
89
- ]
90
- ]
91
- end
92
- end