From 51aa4abfc1c85167ba88f615b9d06c6b77e8f3eb Mon Sep 17 00:00:00 2001 From: Sam James Date: Sun, 21 Jun 2026 08:40:46 +0100 Subject: [PATCH] app-shells/dash: fix read misbehaviour Closes: https://bugs.gentoo.org/977650 Thanks-to: Kerin Millar Signed-off-by: Sam James --- app-shells/dash/dash-0.5.13.4-r2.ebuild | 71 +++++++++ ...overeager-NUL-deletion-in-SMALL-mode.patch | 147 ++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 app-shells/dash/dash-0.5.13.4-r2.ebuild create mode 100644 app-shells/dash/files/0003-input-Fix-overeager-NUL-deletion-in-SMALL-mode.patch diff --git a/app-shells/dash/dash-0.5.13.4-r2.ebuild b/app-shells/dash/dash-0.5.13.4-r2.ebuild new file mode 100644 index 0000000000000..df961a6bef42a --- /dev/null +++ b/app-shells/dash/dash-0.5.13.4-r2.ebuild @@ -0,0 +1,71 @@ +# Copyright 1999-2026 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +inherit flag-o-matic toolchain-funcs + +DESCRIPTION="Debian Almquist Shell" +HOMEPAGE="http://gondor.apana.org.au/~herbert/dash/" +if [[ ${PV} == 9999 ]] ; then + EGIT_REPO_URI="https://git.kernel.org/pub/scm/utils/dash/dash.git" + inherit autotools git-r3 +else + SRC_URI="http://gondor.apana.org.au/~herbert/dash/files/${P}.tar.gz" + KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~arm64-macos ~x64-macos ~x64-solaris" +fi + +LICENSE="BSD" +SLOT="0" +IUSE="libedit static" + +BDEPEND="virtual/pkgconfig" +RDEPEND="!static? ( libedit? ( dev-libs/libedit ) )" +DEPEND=" + ${RDEPEND} + libedit? ( static? ( dev-libs/libedit[static-libs] ) ) +" + +PATCHES=( + "${FILESDIR}"/0001-builtin-Fix-octal-escapes-in-dollar-single-quotes.patch + "${FILESDIR}"/0002-builtin-Fix-unaligned-access-in-conv_escape.patch + "${FILESDIR}"/0003-input-Fix-overeager-NUL-deletion-in-SMALL-mode.patch +) + +src_prepare() { + default + + [[ ${PV} == 9999 ]] && eautoreconf + + # Use pkg-config for libedit linkage + sed -i \ + -e "/LIBS/s:-ledit:\`$(tc-getPKG_CONFIG) --libs libedit $(usex static --static '')\`:" \ + configure || die +} + +src_configure() { + if [[ ${CHOST} == *-solaris* ]] ; then + # don't redefine stat, open, dirent, etc. on Solaris + export ac_cv_func_stat64=yes + export ac_cv_func_open64=yes + fi + + if [[ ${CHOST} == powerpc-*-darwin* ]] ; then + sed -i -e 's/= stpncpy(s, \([^,]\+\), \([0-9]\+\))/+= snprintf(s, \2, "%s", \1)/' \ + src/jobs.c || die + fi + + use static && append-ldflags -static + + append-cppflags -DJOBS=$(usex libedit 1 0) + + # Do not pass --enable-glob due to #443552. + local myeconfargs=( + CC_FOR_BUILD="$(tc-getBUILD_CC)" + --bindir="${EPREFIX}"/bin + --enable-fnmatch + $(use_with libedit) + ) + + econf "${myeconfargs[@]}" +} diff --git a/app-shells/dash/files/0003-input-Fix-overeager-NUL-deletion-in-SMALL-mode.patch b/app-shells/dash/files/0003-input-Fix-overeager-NUL-deletion-in-SMALL-mode.patch new file mode 100644 index 0000000000000..6e17a9d031bc8 --- /dev/null +++ b/app-shells/dash/files/0003-input-Fix-overeager-NUL-deletion-in-SMALL-mode.patch @@ -0,0 +1,147 @@ +From e170d9a49b3652460d6272bba9cd20afbb8140f2 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Sat, 20 Jun 2026 17:23:30 +0800 +Subject: [PATCH] input: Fix overeager NUL deletion in SMALL mode + +NUL characters should not be removed from input lines that are +yet to be processed because they could become the input to the +next executed utility. + +Fix this by moving the NUL deletion into pgetc when history support +is off (IS_DEFINED_SMALL). + +Also fold __pgetc into pgetc since the only other caller of it +is preadbuffer and that logic can also be moved up. + +Finally add a missing signed char cast for the unget characters. + +Reported-by: Kerin Millar +Fixes: 44ae22beedf8 ("input: Disable lleft in SMALL mode") +Fixes: 2c92409145d0 ("input: Allow MB_LEN_MAX calls to pungetc") +Signed-off-by: Herbert Xu +--- + src/input.c | 66 ++++++++++++++++++++++++++++------------------------- + 1 file changed, 35 insertions(+), 31 deletions(-) + +diff --git a/src/input.c b/src/input.c +index 0fb2f18..e9b9d33 100644 +--- a/src/input.c ++++ b/src/input.c +@@ -217,39 +217,47 @@ static void freestrings(struct strpush *sp) + } + + +-static int __pgetc(void) ++/* ++ * Read a character from the script, returning PEOF on end of file. ++ * Nul characters in the input are silently discarded. ++ */ ++ ++int __attribute__((noinline)) pgetc(void) + { ++ struct strpush *sp = parsefile->spfree; + int c; + ++ if (unlikely(sp)) ++ freestrings(sp); ++ ++again: + if (parsefile->unget) { + long unget = -(long)(unsigned)parsefile->unget--; + +- return parsefile->nextc[unget]; ++ return (signed char)parsefile->nextc[unget]; + } + +- if (parsefile->nleft > 0) { ++nextc: ++ if (likely(parsefile->nleft > 0)) { + parsefile->nleft--; + c = (signed char)*parsefile->nextc++; ++ } else if (unlikely(parsefile->strpush)) { ++ popstring(); ++ /* The freestrings call must be delayed til the next ++ * pgetc call for PEOA to work properly. ++ */ ++ goto again; + } else + c = preadbuffer(); + +- return c; +-} +- +- +-/* +- * Read a character from the script, returning PEOF on end of file. +- * Nul characters in the input are silently discarded. +- */ +- +-int __attribute__((noinline)) pgetc(void) +-{ +- struct strpush *sp = parsefile->spfree; +- +- if (unlikely(sp)) +- freestrings(sp); ++ /* delete nul characters */ ++ if (IS_DEFINED_SMALL && unlikely(!c)) { ++ parsefile->nextc = memmove(parsefile->nextc - 1, ++ parsefile->nextc, parsefile->nleft); ++ goto nextc; ++ } + +- return __pgetc(); ++ return c; + } + + int pgetc_eoa(void) +@@ -374,10 +382,6 @@ static int preadbuffer(void) + int more; + char *q; + +- if (unlikely(parsefile->strpush)) { +- popstring(); +- return __pgetc(); +- } + if (parsefile->eof & 2) { + eof: + parsefile->eof = 3; +@@ -408,6 +412,12 @@ again: + } + } + ++ if (IS_DEFINED_SMALL) { ++ q += more; ++ more = 0; ++ goto done; ++ } ++ + /* delete nul characters */ + for (;;) { + int c; +@@ -422,9 +432,6 @@ again: + + q++; + +- if (IS_DEFINED_SMALL) +- goto check; +- + switch (c) { + case '\n': + goto done; +@@ -439,11 +446,8 @@ again: + } + + check: +- if (more <= 0) { +- if (!IS_DEFINED_SMALL) +- goto again; +- break; +- } ++ if (more <= 0) ++ goto again; + } + done: + input_set_lleft(parsefile, more); +-- +2.53.0 +