commit:     92741aa01fcdc6535c3582a00a3cbe7c6a030e40
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Feb 10 04:30:54 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Feb 10 06:07:33 2023 +0000
URL:        
https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=92741aa0

Improve the means by which the number of terminal columns is detected

The existing routine is not well structured and is perhaps a little too
trusting of its inputs. Clean it up and check that the value of COLUMNS
and the second field obtained from stty(1) are actually integers. To
this end, an is_int() function has been added. This function may yet
prove to be useful elsewhere.

This also fixes an instance of SC2068 by using read to consume the
output of stty(1), rather than perform word splitting and/or pathname
expansion. It also fixes an instance of SC2059 (format string abuse).

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

 functions.sh | 43 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/functions.sh b/functions.sh
index 9775e2c..9ab8d0c 100644
--- a/functions.sh
+++ b/functions.sh
@@ -397,6 +397,26 @@ is_older_than()
        read -r line
 }
 
+#
+#   Determine whether the first operand is in the form of an integer. A leading
+#   <hypen-minus> shall be permitted. Thereafter, leading zeroes shall not be
+#   permitted because the string might later be considered to be octal in an
+#   arithmetic context, causing the shell to exit if the number be invalid.
+#
+is_int() {
+       set -- "${1#-}"
+       case $1 in
+               ''|*[!0123456789]*)
+                       false
+                       ;;
+               0)
+                       true
+                       ;;
+               *)
+                       test "$1" = "${1#0}"
+       esac
+}
+
 # This is the main script, please add all functions above this point!
 
 # Dont output to stdout?
@@ -432,12 +452,23 @@ for arg in "$@" ; do
        esac
 done
 
-# Setup COLS and ENDCOL so eend can line up the [ ok ]
-COLS="${COLUMNS:-0}"            # bash's internal COLUMNS variable
-[ "${COLS}" -eq 0 ] && \
-        COLS="$(set -- $(stty size 2>/dev/null) ; printf "$2\n")"
-[ -z "${COLS}" ] && COLS=80
-[ "${COLS}" -gt 0 ] || COLS=80 # width of [ ok ] == 7
+# Define COLS and ENDCOL so that eend can line up the [ ok ].
+if is_int "${COLUMNS}" && [ "${COLUMNS}" -gt 0 ]; then
+       # The value of COLUMNS was likely set by a shell such as bash. Trust it.
+       COLS=${COLUMNS}
+else
+       # Try to use stty(1) to determine the number of columns. The use of the
+       # size operand is not portable.
+       COLS=$(
+               stty size 2>/dev/null | {
+                       read -r h w _ && printf '%s\n' "$w"
+               }
+       )
+       if ! is_int "${COLS}" || [ "${COLS}" -le 0 ]; then
+               # Give up and assume 80 available columns.
+               COLS=80
+       fi
+fi
 
 if ! yesno "${RC_ENDCOL}"; then
        ENDCOL=''

Reply via email to