gbranden pushed a commit to branch master
in repository groff.

commit 2b86c9332c7599db2371d19a49b173593f19799d
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Feb 4 05:30:17 2026 -0600

    Stop using `${1+"$@"}` in shell scripts.
    
    ...to kludge around old broken shells.
    
    The (forthcoming) Autoconf 2.73 manual explains.
    
    ---snip---
    You may see usages like ‘${1+"$@"}’ in older shell scripts designed to
    work around a portability problem in ancient shells.  Unfortunately this
    runs afoul of bugs in more-recent shells, and nowadays it is better to
    use plain ‘"$@"’ instead.
    
    The portability problem with ancient shells was significant.  When there
    are no positional arguments ‘"$@"’ should be discarded, but the original
    Unix version 7 Bourne shell mistakenly treated it as equivalent to ‘""’
    instead, and many ancient shells followed its lead.
    
    For many years shell scripts worked around this portability problem by
    using ‘${1+"$@"}’ instead of ‘"$@"’, and you may see this usage in older
    scripts.  Unfortunately, ‘${1+"$@"}’ does not work with ‘ksh93’ M 93t+
    (2009) as shipped in AIX 7.2 (2015), as this shell drops a trailing
    empty argument:
    
      $ set a b c ""
      $ set ${1+"$@"}
      $ echo $#
      3
    
    Also, ‘${1+"$@"}’ does not work with Zsh 4.2.6 (2005) and earlier, as
    shipped in Mac OS X releases before 10.5, as this old Zsh incorrectly
    word splits the result:
    
      zsh $ emulate sh
      zsh $ for i in "$@"; do echo $i; done
      Hello World
      !
      zsh $ for i in ${1+"$@"}; do echo $i; done
      Hello
      World
      !
    ---end snip---
    
    In light of all this winning by elite shell developers, use plain,
    idiomatic `"$@"` instead, relying on downstream distributors to patch
    the handful of occurrences in groff should their deployments be boxed in
    by a buggy /bin/sh.
    
    * src/preproc/eqn/neqn.sh:
    * src/roff/nroff/nroff.sh:
    * test-groff.in: Do it.
---
 ChangeLog               | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/preproc/eqn/neqn.sh |  5 +----
 src/roff/nroff/nroff.sh |  9 ++-------
 test-groff.in           |  2 +-
 4 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 33536ce32..ca157d341 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2026-02-04  G. Branden Robinson <[email protected]>
+
+       Stop using `${1+"$@"}` to kludge around old broken shells.
+
+       The (forthcoming) Autoconf 2.73 manual explains.
+
+       ---snip---
+       You may see usages like ‘${1+"$@"}’ in older shell scripts
+       designed to work around a portability problem in ancient shells.
+       Unfortunately this runs afoul of bugs in more-recent shells, and
+       nowadays it is better to use plain ‘"$@"’ instead.
+
+       The portability problem with ancient shells was significant.
+       When there are no positional arguments ‘"$@"’ should be
+       discarded, but the original Unix version 7 Bourne shell
+       mistakenly treated it as equivalent to ‘""’ instead, and many
+       ancient shells followed its lead.
+
+       For many years shell scripts worked around this portability
+       problem by using ‘${1+"$@"}’ instead of ‘"$@"’, and you may see
+       this usage in older scripts.  Unfortunately, ‘${1+"$@"}’ does
+       not work with ‘ksh93’ M 93t+ (2009) as shipped in AIX 7.2
+       {2015}, as this shell drops a trailing empty argument:
+
+         $ set a b c ""
+         $ set ${1+"$@"}
+         $ echo $#
+         3
+
+       Also, ‘${1+"$@"}’ does not work with Zsh 4.2.6 (2005) and
+       earlier, as shipped in Mac OS X releases before 10.5, as this
+       old Zsh incorrectly word splits the result:
+
+         zsh $ emulate sh
+         zsh $ for i in "$@"; do echo $i; done
+         Hello World
+         !
+         zsh $ for i in ${1+"$@"}; do echo $i; done
+         Hello
+         World
+         !
+       ---end snip---
+
+       In light of all this winning by elite shell developers,
+       use plain, idiomatic `"$@"` instead, relying on downstream
+       distributors to patch the handful of occurrences in groff should
+       their deployments be boxed in by a buggy /bin/sh.
+
+       * src/preproc/eqn/neqn.sh:
+       * src/roff/nroff/nroff.sh:
+       * test-groff.in: Do it.
+
 2026-02-03  G. Branden Robinson <[email protected]>
 
        * m4/groff.m4 (GROFF_URW_FONTS_CHECK): Stop blanking
diff --git a/src/preproc/eqn/neqn.sh b/src/preproc/eqn/neqn.sh
index 0846a03f7..12864a6eb 100644
--- a/src/preproc/eqn/neqn.sh
+++ b/src/preproc/eqn/neqn.sh
@@ -56,10 +56,7 @@ EOF
   esac
 done
 
-# Note: The construction '${1+"@$"}' preserves the absence of arguments
-# in old shells; see "Shell Substitutions" in the GNU Autoconf manual.
-# We don't want 'neqn' to become 'neqn ... ""' if $# equals zero.
-exec @g@eqn -T ascii ${1+"$@"}
+exec @g@eqn -T ascii "$@"
 
 # Local Variables:
 # fill-column: 72
diff --git a/src/roff/nroff/nroff.sh b/src/roff/nroff/nroff.sh
index c465cb39e..05c293632 100644
--- a/src/roff/nroff/nroff.sh
+++ b/src/roff/nroff/nroff.sh
@@ -251,16 +251,11 @@ groff=${GROFF_TEST_GROFF-groff}
 #
 # If POSIX adopts Bash's ${var@Q} or an equivalent, this issue can be
 # revisited.
-#
-# Note 2: The construction '${1+"$@"}' preserves the absence of
-# arguments in old shells; see "Shell Substitutions" in the GNU Autoconf
-# manual.  We don't want 'nroff' to become 'groff ... ""' if $# equals
-# zero.
 if [ -n "$dry_run" ]
 then
-  echo PATH="$GROFF_RUNTIME$PATH" $groff $T $opts ${1+"$@"}
+  echo PATH="$GROFF_RUNTIME$PATH" $groff $T $opts "$@"
 else
-  PATH="$GROFF_RUNTIME$PATH" $groff $T $opts ${1+"$@"}
+  PATH="$GROFF_RUNTIME$PATH" $groff $T $opts "$@"
 fi
 
 # Local Variables:
diff --git a/test-groff.in b/test-groff.in
index aa5da5071..a65898a77 100644
--- a/test-groff.in
+++ b/test-groff.in
@@ -52,4 +52,4 @@ $SEP$builddir/contrib/sboxes\
 export GROFF_COMMAND_PREFIX
 export GROFF_BIN_PATH GROFF_FONT_PATH GROFF_TMAC_PATH
 
-exec $builddir/groff ${1+"$@"}
+exec $builddir/groff "$@"

_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to