From 20b4513bbcc108e8c18f96dc8eb7a94f880611a8 Mon Sep 17 00:00:00 2001 From: Alex Gubarev Date: Tue, 21 Jul 2026 19:00:05 +0300 Subject: [PATCH] Fix String.reverse/1 grapheme ordering around invalid utf8 bytes --- lib/elixir/lib/string.ex | 2 +- lib/elixir/test/elixir/string_test.exs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/elixir/lib/string.ex b/lib/elixir/lib/string.ex index a5389c1792c..16cf7901534 100644 --- a/lib/elixir/lib/string.ex +++ b/lib/elixir/lib/string.ex @@ -1784,7 +1784,7 @@ defmodule String do do: :unicode.characters_to_binary(acc) defp do_reverse({:error, <>}, acc), - do: :unicode.characters_to_binary(acc) <> <> <> do_reverse(:unicode_util.gc(rest), []) + do: do_reverse(:unicode_util.gc(rest), []) <> <> <> :unicode.characters_to_binary(acc) @doc """ Returns a string `subject` repeated `n` times. diff --git a/lib/elixir/test/elixir/string_test.exs b/lib/elixir/test/elixir/string_test.exs index 40a6fe8b574..de4f3833a4d 100644 --- a/lib/elixir/test/elixir/string_test.exs +++ b/lib/elixir/test/elixir/string_test.exs @@ -444,6 +444,7 @@ defmodule StringTest do assert String.reverse("Hello World") == "dlroW olleH" assert String.reverse("Hello ∂og") == "go∂ olleH" assert String.reverse("Ā̀stute") == "etutsĀ̀" + assert String.reverse("ab" <> <<254, 255>> <> "cd") == "dc" <> <<255, 254>> <> "ba" assert String.reverse(String.reverse("Hello World")) == "Hello World" assert String.reverse(String.reverse("Hello \r\n World")) == "Hello \r\n World" end