commit:     972eb63cbb3187528cd9d02f97696b3e7319eaed
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Tue Oct 14 09:15:34 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Oct 14 12:59:10 2025 +0000
URL:        
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=972eb63c

Don't let _update_columns() restore IFS as '' where previously unset

One of the methods by which the _update_columns() function is able to
determine the dimensions of the terminal is to execute the stty(1)
utility. Should it elect to do so, it backs up the value of the 'IFS'
variable to one named 'genfun_ifs' before setting 'IFS' appropriately.
Then, after stty(1) has been executed, the prior value of 'IFS' is
restored from 'genfun_ifs'. All of which is fundamentally incorrect.

$ unset -v IFS
$ echo "IFS=${IFS-unset}"
IFS=unset
$ f() { old_ifs=$IFS; IFS=$old_ifs; }; f
$ echo "IFS=${IFS-unset}"
IFS=

Note how, despite IFS having been unset, the function 'restores' it by
assigning the null string. But these two states are not equivalent. The
specification exacts the following two requirements.

"If the IFS variable is set and has an empty string as its value, no
field splitting shall occur."

"If the IFS variable is unset, then for the purposes of this section,
but without altering the value of the variable, its value shall be
considered to contain the three single-byte characters <space>, <tab>,
and <newline> from the portable character set, all of which are IFS
white-space characters."

Address this issue by jettisoning the 'genfun_ifs' variable and
declaring 'IFS' as a local variable instead.

Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 functions.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/functions.sh b/functions.sh
index 5b49ce8..ed049c1 100644
--- a/functions.sh
+++ b/functions.sh
@@ -868,6 +868,8 @@ _update_columns()
 
        _update_columns()
        {
+               local IFS
+
                # Two optimisations are applied. Firstly, the rate at which
                # updates can be performed is throttled to intervals of half a
                # second. Secondly, if running on bash then the COLUMNS variable
@@ -887,11 +889,9 @@ _update_columns()
                        set -- 0 "${COLUMNS}"
                else
                        # This use of stty(1) is portable as of POSIX-1.2024.
-                       genfun_ifs=${IFS}
                        IFS=' '
                        # shellcheck disable=2046
                        set -- $(stty size 2>/dev/null)
-                       IFS=${genfun_ifs}
                fi
                [ "$#" -eq 2 ] && is_int "$2" && [ "$2" -gt 0 ] && 
genfun_cols=$2
        }

Reply via email to