From 0b1e6d49896c552d72e7748206c859bd2306ac27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 15 Jun 2023 15:39:03 +0200 Subject: [PATCH] Limit integers to less than 32 digits --- lib/ecto/changeset.ex | 4 +++- lib/ecto/type.ex | 10 ++++++---- test/ecto/type_test.exs | 4 ++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/ecto/changeset.ex b/lib/ecto/changeset.ex index 228aa45284..6f9f3b0330 100644 --- a/lib/ecto/changeset.ex +++ b/lib/ecto/changeset.ex @@ -1259,7 +1259,9 @@ defmodule Ecto.Changeset do end end - defp key_as_int({key, val}) when is_binary(key) do + # We check for the byte size to avoid creating unecessary large integers + # which would never map to a database key (u64 is 20 digits only). + defp key_as_int({key, val}) when is_binary(key) and byte_size(key) < 32 do case Integer.parse(key) do {key, ""} -> {key, val} _ -> {key, val} diff --git a/lib/ecto/type.ex b/lib/ecto/type.ex index 7cc4db7215..0a811999a6 100644 --- a/lib/ecto/type.ex +++ b/lib/ecto/type.ex @@ -806,7 +806,9 @@ defmodule Ecto.Type do end end - defp cast_integer(term) when is_binary(term) do + # We check for the byte size to avoid creating unecessary large integers + # which would never map to a database key (u64 is 20 digits only). + defp cast_integer(term) when is_binary(term) and byte_size(term) < 32 do case Integer.parse(term) do {integer, ""} -> {:ok, integer} _ -> :error @@ -1329,14 +1331,14 @@ defmodule Ecto.Type do {:ok, acc} end - defp to_i(nil), do: nil - defp to_i(int) when is_integer(int), do: int - defp to_i(bin) when is_binary(bin) do + defp to_i(bin) when is_binary(bin) and byte_size(bin) < 32 do case Integer.parse(bin) do {int, ""} -> int _ -> nil end end + defp to_i(int) when is_integer(int), do: int + defp to_i(_), do: nil defp maybe_truncate_usec({:ok, struct}), do: {:ok, truncate_usec(struct)} defp maybe_truncate_usec(:error), do: :error diff --git a/test/ecto/type_test.exs b/test/ecto/type_test.exs index 86da28ffa5..73344548de 100644 --- a/test/ecto/type_test.exs +++ b/test/ecto/type_test.exs @@ -216,6 +216,10 @@ defmodule Ecto.TypeTest do refute match?(:string, {:param, :any_datetime}) end + test "integer" do + assert cast(:integer, String.duplicate("1", 64)) == :error + end + test "decimal" do assert cast(:decimal, "1.0") == {:ok, Decimal.new("1.0")} assert cast(:decimal, 1.0) == {:ok, Decimal.new("1.0")}