Skip to content

Commit

Permalink
Limit large inter decoding
Browse files Browse the repository at this point in the history
This can be changed with the decoding_integer_digit_limit compile-time env option
  • Loading branch information
michalmuskala committed Jul 7, 2023
1 parent ed8f1c2 commit 2ce61ea
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 1.4.1 (06.07.2023)

* Add limit to decoded integer sizes of 1024 digits. This can be changed
with the `decoding_integer_digit_limit` app env config.

## 1.4.0 (12.09.2022)

### Enhancements
Expand Down
13 changes: 12 additions & 1 deletion lib/decoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ defmodule Jason.Decoder do
error(original, skip + 1)
end

if function_exported?(Application, :compile_env, 3) do
@integer_digit_limit Application.compile_env(:jason, :decoding_integer_digit_limit, 1024)
else
# use apply to avoid warnings in newer Elixir versions
@integer_digit_limit apply(Application, :get_env, [:jason, :decoding_integer_digit_limit, 1024])
end

defp number(<<byte, rest::bits>>, original, skip, stack, decode, len)
when byte in '0123456789' do
number(rest, original, skip, stack, decode, len + 1)
Expand All @@ -168,7 +175,11 @@ defmodule Jason.Decoder do
number_exp_copy(rest, original, skip + len + 1, stack, decode, prefix)
end
defp number(<<rest::bits>>, original, skip, stack, decode, len) do
int = String.to_integer(binary_part(original, skip, len))
token = binary_part(original, skip, len)
if byte_size(token) > @integer_digit_limit do
token_error(token, skip)
end
int = String.to_integer(token)
continue(rest, original, skip + len, stack, decode, int)
end

Expand Down
5 changes: 5 additions & 0 deletions test/decode_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ defmodule Jason.DecodeTest do
assert parse!(body) == expected
end

test "large integers" do
massive_integer = String.duplicate("1", 2_000)
assert_fail_with(massive_integer, "unexpected sequence at position 0: #{inspect massive_integer}")
end

defp parse!(json, opts \\ []) do
Jason.decode!(json, opts)
end
Expand Down

0 comments on commit 2ce61ea

Please sign in to comment.