diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch index 2f3783f..8ca3fcc 100644 --- a/coreutils-i18n-expand-unexpand.patch +++ b/coreutils-i18n-expand-unexpand.patch @@ -23,11 +23,11 @@ Co-authored-by: Pádraig Brady lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++ m4/mbfile.m4 | 14 +++ src/expand.c | 43 +++++--- - src/unexpand.c | 57 ++++++---- + src/unexpand.c | 59 ++++++---- tests/expand/mb.sh | 98 +++++++++++++++++ tests/local.mk | 2 + - tests/unexpand/mb.sh | 105 ++++++++++++++++++ - 10 files changed, 545 insertions(+), 35 deletions(-) + tests/unexpand/mb.sh | 114 +++++++++++++++++++ + 10 files changed, 555 insertions(+), 36 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -35,7 +35,7 @@ Co-authored-by: Pádraig Brady create mode 100755 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index fcf29dc23..3eaedc3a5 100644 +index fcf29dc..3eaedc3 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -153,6 +153,7 @@ gnulib_modules=" @@ -47,7 +47,7 @@ index fcf29dc23..3eaedc3a5 100644 mbrtowc mbsalign diff --git a/configure.ac b/configure.ac -index 9b1ead085..c24ce2aad 100644 +index 9b1ead0..c24ce2a 100644 --- a/configure.ac +++ b/configure.ac @@ -439,6 +439,8 @@ fi @@ -61,7 +61,7 @@ index 9b1ead085..c24ce2aad 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 -index 000000000..b0a468efa +index 0000000..b0a468e --- /dev/null +++ b/lib/mbfile.c @@ -0,0 +1,3 @@ @@ -70,7 +70,7 @@ index 000000000..b0a468efa +#include "mbfile.h" diff --git a/lib/mbfile.h b/lib/mbfile.h new file mode 100644 -index 000000000..11f1b1242 +index 0000000..11f1b12 --- /dev/null +++ b/lib/mbfile.h @@ -0,0 +1,255 @@ @@ -331,7 +331,7 @@ index 000000000..11f1b1242 +#endif /* _MBFILE_H */ diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 -index 000000000..858990213 +index 0000000..8589902 --- /dev/null +++ b/m4/mbfile.m4 @@ -0,0 +1,14 @@ @@ -350,7 +350,7 @@ index 000000000..858990213 + : +]) diff --git a/src/expand.c b/src/expand.c -index 6183fb820..34a559bcd 100644 +index 6183fb8..34a559b 100644 --- a/src/expand.c +++ b/src/expand.c @@ -37,6 +37,9 @@ @@ -459,7 +459,7 @@ index 6183fb820..34a559bcd 100644 } diff --git a/src/unexpand.c b/src/unexpand.c -index 8fdd80f18..d12e36d7d 100644 +index 8fdd80f..8701eca 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -38,6 +38,9 @@ @@ -526,7 +526,7 @@ index 8fdd80f18..d12e36d7d 100644 if (blank) { -@@ -180,16 +193,16 @@ unexpand (void) +@@ -180,30 +193,31 @@ unexpand (void) if (next_tab_column < column) die (EXIT_FAILURE, 0, _("input line is too long")); @@ -544,9 +544,10 @@ index 8fdd80f18..d12e36d7d 100644 - column++; + column += mb_width (c); - if (! (prev_blank && column == next_tab_column)) +- if (! (prev_blank && column == next_tab_column)) ++ if (! (prev_blank && column >= next_tab_column)) { -@@ -197,13 +210,14 @@ unexpand (void) + /* It is not yet known whether the pending blanks will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -620,7 +621,7 @@ index 8fdd80f18..d12e36d7d 100644 diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh new file mode 100755 -index 000000000..dab27b479 +index 0000000..dab27b4 --- /dev/null +++ b/tests/expand/mb.sh @@ -0,0 +1,98 @@ @@ -723,7 +724,7 @@ index 000000000..dab27b479 + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index fb74b5dd0..1f19f1b01 100644 +index fb74b5d..1f19f1b 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -561,6 +561,7 @@ all_tests = \ @@ -744,10 +745,10 @@ index fb74b5dd0..1f19f1b01 100644 # See tests/factor/create-test.sh. diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh new file mode 100755 -index 000000000..4b797034f +index 0000000..5b4252d --- /dev/null +++ b/tests/unexpand/mb.sh -@@ -0,0 +1,105 @@ +@@ -0,0 +1,114 @@ +#!/bin/sh + +# Copyright (C) 2012-2015 Free Software Foundation, Inc. @@ -852,6 +853,15 @@ index 000000000..4b797034f + test "$ret" = 1 || test "$ret" = 0 || { cat err; fail=1; } +done + ++# A blank whose display width exceeds the tab distance must not overrun ++# the pending-blank buffer. With -t1 every column is a tab stop, so a ++# width-2 ideographic space steps over the stop without landing on it; ++# the run of blanks then grew pending_blank without bound. ++ideo_space=$(env printf '\u3000') ++{ yes "$ideo_space" | head -n 40000 | tr -d '\n'; echo; } | ++ unexpand -t1 >out 2>err; ret=$? ++test "$ret" = 0 || { cat err; fail=1; } ++ +Exit $fail -- 2.54.0 diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch index 36de7b8..e2e51f1 100644 --- a/coreutils-i18n-un-expand-BOM.patch +++ b/coreutils-i18n-un-expand-BOM.patch @@ -13,7 +13,7 @@ Subject: [PATCH] coreutils-i18n-un-expand-BOM.patch 6 files changed, 341 insertions(+), 2 deletions(-) diff --git a/src/expand-common.c b/src/expand-common.c -index 20ab02350..e1c8943fd 100644 +index 20ab023..e1c8943 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -145,7 +145,7 @@ index 20ab02350..e1c8943fd 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index cd32509a6..2ecf5e656 100644 +index cd32509..2ecf5e6 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -34,6 +34,18 @@ extern size_t max_column_width; @@ -168,7 +168,7 @@ index cd32509a6..2ecf5e656 100644 extern void add_tab_stop (uintmax_t tabval); diff --git a/src/expand.c b/src/expand.c -index 52d6ec155..50a4590f5 100644 +index 52d6ec1..50a4590 100644 --- a/src/expand.c +++ b/src/expand.c @@ -103,11 +103,33 @@ expand (void) @@ -235,7 +235,7 @@ index 52d6ec155..50a4590f5 100644 } else diff --git a/src/unexpand.c b/src/unexpand.c -index ce57c1334..41b1ed55b 100644 +index a818773..b37b319 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -116,16 +116,36 @@ unexpand (void) @@ -305,7 +305,7 @@ index ce57c1334..41b1ed55b 100644 } else diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -index 3a5eb95c2..6d6497a3d 100755 +index 3a5eb95..6d6497a 100755 --- a/tests/expand/mb.sh +++ b/tests/expand/mb.sh @@ -109,4 +109,75 @@ env printf '12345678 @@ -385,12 +385,12 @@ index 3a5eb95c2..6d6497a3d 100755 + Exit $fail diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -index 0ff44c508..17a149d1c 100755 +index b1f0b2e..4d31ffd 100755 --- a/tests/unexpand/mb.sh +++ b/tests/unexpand/mb.sh -@@ -118,4 +118,62 @@ for mb_mul in 4 6; do - test "$ret" = 1 || test "$ret" = 0 || { cat err; fail=1; } - done +@@ -127,4 +127,62 @@ ideo_space=$(env printf '\u3000') + unexpand -t1 >out 2>err; ret=$? + test "$ret" = 0 || { cat err; fail=1; } +#BOM header test 1 +printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ diff --git a/coreutils.spec b/coreutils.spec index 49b4e86..9b8d129 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 19%{?dist} +Release: 20%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -296,6 +296,9 @@ fi %license COPYING %changelog +* Wed Jun 10 2026 Lukáš Zaoral - 8.30-20 +- unexpand: fix heap overflow when a wide blank overshoots a tab stop (RHEL-182699) + * Mon Jun 08 2026 Lukáš Zaoral - 8.30-19 - unexpand: fix stack overflow with large tabsizes (RHEL-182699)