diff --git a/dev-lang/elixir/elixir-1.17.3-r2.ebuild b/dev-lang/elixir/elixir-1.17.3-r2.ebuild new file mode 100644 index 0000000000000..86502dcc48c12 --- /dev/null +++ b/dev-lang/elixir/elixir-1.17.3-r2.ebuild @@ -0,0 +1,43 @@ +# Copyright 1999-2026 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +DESCRIPTION="Elixir programming language" +HOMEPAGE="https://elixir-lang.org" +SRC_URI="https://github.com/elixir-lang/elixir/archive/v${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="Apache-2.0 ErlPL-1.1" +SLOT="0" +KEYWORDS="~amd64 ~arm ~arm64 ~ppc ~riscv ~sparc ~x86" +IUSE="test" + +RESTRICT="!test? ( test )" + +# https://hexdocs.pm/elixir/compatibility-and-deprecations.html#between-elixir-and-erlang-otp +DEPEND=" + >=dev-lang/erlang-25:0=[ssl] + +Date: Tue, 25 Aug 2026 11:27:54 +0200 +Subject: [PATCH] Fix recursion on charlist error path + +--- + lib/elixir/lib/inspect.ex | 30 ++++++++++++++++++++----- + lib/elixir/lib/inspect/algebra.ex | 4 ++-- + lib/elixir/lib/list.ex | 4 ++-- + lib/elixir/test/elixir/inspect_test.exs | 17 +++++++++++++- + lib/elixir/test/elixir/list_test.exs | 12 ++++++++++ + 5 files changed, 57 insertions(+), 10 deletions(-) + +diff --git a/lib/elixir/lib/inspect.ex b/lib/elixir/lib/inspect.ex +index 637bca8a6..d5b876fcf 100644 +--- a/lib/elixir/lib/inspect.ex ++++ b/lib/elixir/lib/inspect.ex +@@ -264,13 +264,20 @@ def inspect(term, opts) do + close = color("]", :list, opts) + + cond do +- lists == :as_charlists or (lists == :infer and List.ascii_printable?(term, printable_limit)) -> +- inspected = +- case Identifier.escape(IO.chardata_to_string(term), ?", printable_limit) do +- {escaped, ""} -> [?~, ?c, ?", escaped, ?"] +- {escaped, _} -> [?~, ?c, ?", escaped, ?", " ++ ..."] ++ (lists == :as_charlists and unicode_list?(term, printable_limit)) or ++ (lists == :infer and List.ascii_printable?(term, printable_limit)) -> ++ {split, tail} = ++ if is_integer(printable_limit) do ++ case Enum.split(term, printable_limit) do ++ {split, []} -> {split, []} ++ {split, _} -> {split, " ++ ..."} ++ end ++ else ++ {term, []} + end + ++ {escaped, _} = Identifier.escape(IO.chardata_to_string(split), ?") ++ inspected = [?~, ?c, ?", escaped, ?" | tail] + color(IO.iodata_to_binary(inspected), :charlist, opts) + + keyword?(term) -> +@@ -281,6 +288,19 @@ def inspect(term, opts) do + end + end + ++ defp unicode_list?(_, 0), do: true ++ ++ defp unicode_list?([char | rest], counter) ++ when char in 0..0xD7FF or char in 0xE000..0x10FFFF, ++ do: unicode_list?(rest, decrement(counter)) ++ ++ defp unicode_list?([], _counter), do: true ++ defp unicode_list?(_, _counter), do: false ++ ++ @compile {:inline, decrement: 1} ++ defp decrement(:infinity), do: :infinity ++ defp decrement(counter), do: counter - 1 ++ + @doc false + def keyword({key, value}, opts) do + key = color(Macro.inspect_atom(:key, key), :atom, opts) +diff --git a/lib/elixir/lib/inspect/algebra.ex b/lib/elixir/lib/inspect/algebra.ex +index 5e213b377..941aa5525 100644 +--- a/lib/elixir/lib/inspect/algebra.ex ++++ b/lib/elixir/lib/inspect/algebra.ex +@@ -17,8 +17,8 @@ defmodule Inspect.Opts do + is `:decimal` and if it is printable, otherwise in bit syntax. See + `String.printable?/1` to learn when a string is printable. + +- * `:charlists` - when `:as_charlists` all lists will be printed as charlists, +- non-printable elements will be escaped. ++ * `:charlists` - when `:as_charlists` all charlists will be printed as charlists, ++ non-printable code points will be escaped. Other lists will be printed as lists. + + When `:as_lists` all lists will be printed as lists. + +diff --git a/lib/elixir/lib/list.ex b/lib/elixir/lib/list.ex +index a8155deed..ea4a69abd 100644 +--- a/lib/elixir/lib/list.ex ++++ b/lib/elixir/lib/list.ex +@@ -1093,7 +1093,7 @@ def to_string(list) when is_list(list) do + + Please check the given list or call inspect/1 to get the list representation, got: + +- #{inspect(list)} ++ #{inspect(list, charlists: :as_lists)} + """ + else + result when is_binary(result) -> +@@ -1145,7 +1145,7 @@ def to_charlist(list) when is_list(list) do + + Please check the given list or call inspect/1 to get the list representation, got: + +- #{inspect(list)} ++ #{inspect(list, charlists: :as_lists)} + """ + else + result when is_list(result) -> +diff --git a/lib/elixir/test/elixir/inspect_test.exs b/lib/elixir/test/elixir/inspect_test.exs +index a8c12c36e..f90b69a2c 100644 +--- a/lib/elixir/test/elixir/inspect_test.exs ++++ b/lib/elixir/test/elixir/inspect_test.exs +@@ -276,10 +276,15 @@ test "printable" do + + test "printable limit" do + assert inspect(~c"hello world", printable_limit: 4) == ~s(~c"hell" ++ ...) ++ assert inspect(~c"hello", printable_limit: :infinity) == ~s(~c"hello") + # Non printable characters after the limit don't matter + assert inspect(~c"hello world" ++ [0], printable_limit: 4) == ~s(~c"hell" ++ ...) + # Non printable strings aren't affected by printable limit + assert inspect([0, 1, 2, 3, 4], printable_limit: 3) == ~s([0, 1, 2, 3, 4]) ++ # Ensure a non-printable value after limit does not crash ++ assert inspect(~c"hello world" ++ [nil], printable_limit: 4) == ~s(~c"hell" ++ ...) ++ # Ensure a non-printable value after default limit does not hang ++ assert String.ends_with?(inspect(List.duplicate(?a, 5000) ++ [nil]), "\" ++ ...") + end + + test "keyword" do +@@ -304,10 +309,20 @@ test "opt infer" do + assert inspect([0], charlists: :infer) == "[0]" + end + +- test "opt as strings" do ++ test "opt as charlists" do + assert inspect(~c"john" ++ [0] ++ ~c"doe", charlists: :as_charlists) == ~s(~c"john\\0doe") + assert inspect(~c"john", charlists: :as_charlists) == ~s(~c"john") + assert inspect([0], charlists: :as_charlists) == ~s(~c"\\0") ++ assert inspect([nil], charlists: :as_charlists) == "[nil]" ++ assert inspect([0xD800], charlists: :as_charlists) == "[55296]" ++ assert inspect([1_114_112], charlists: :as_charlists) == "[1114112]" ++ assert inspect([[?a]], charlists: :as_charlists) == ~s([~c"a"]) ++ ++ assert inspect([?a, ?b, ?c | nil], charlists: :as_charlists, printable_limit: 4) == ++ "[97, 98, 99 | nil]" ++ ++ assert inspect([?a, ?b, ?c | nil], charlists: :as_charlists, printable_limit: 3) == ++ ~s(~c"abc" ++ ...) + end + + test "opt as lists" do +diff --git a/lib/elixir/test/elixir/list_test.exs b/lib/elixir/test/elixir/list_test.exs +index ee02a072a..ec4725877 100644 +--- a/lib/elixir/test/elixir/list_test.exs ++++ b/lib/elixir/test/elixir/list_test.exs +@@ -309,6 +309,12 @@ test "to_string/1" do + assert_raise ArgumentError, ~r"cannot convert the given list to a string", fn -> + List.to_string([:a, :b]) + end ++ ++ invalid = List.duplicate(?a, 4096) ++ [nil] ++ ++ assert_raise ArgumentError, ~r/got:\n\n\[97, 97, .*\.\.\.\]\n\z/s, fn -> ++ List.to_string(invalid) ++ end + end + + test "to_charlist/1" do +@@ -327,6 +333,12 @@ test "to_charlist/1" do + assert_raise ArgumentError, ~r"cannot convert the given list to a charlist", fn -> + List.to_charlist([:a, :b]) + end ++ ++ invalid = List.duplicate(?a, 4096) ++ [nil] ++ ++ assert_raise ArgumentError, ~r/got:\n\n\[97, 97, .*\.\.\.\]\n\z/s, fn -> ++ List.to_charlist(invalid) ++ end + end + + describe "myers_difference/2" do +-- +2.52.0 +