[PROPOSED 1/3] Avoid expr in tzselect
* tzselect.ksh: Rewrite to not use the expr command. Various implementations have problems or dump core given unusual inputs, so to avoid these issues use awk or sh (which we need to use anyway) instead of using expr. --- tzselect.ksh | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/tzselect.ksh b/tzselect.ksh index 2073bccd..cc58db03 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -40,6 +40,9 @@ REPORT_BUGS_TO=tz@iana.org # The substr avoids problems when VALUE is of the form X=Y and would be # misinterpreted as an assignment. +# This script does not want path expansion. +set -f + # Specify default values for environment variables if they are unset. : ${AWK=awk} : ${TZDIR=`pwd`} @@ -113,7 +116,8 @@ then else doselect() { # Field width of the prompt numbers. - select_width=`expr $# : '.*'` + print_nargs_length="BEGIN {print length(\"$#\");}" + select_width=`$AWK "$print_nargs_length"` select_i= @@ -124,14 +128,14 @@ else select_i=0 for select_word do - select_i=`expr $select_i + 1` + select_i=`$AWK "BEGIN { print $select_i + 1 }"` printf >&2 "%${select_width}d) %s\\n" $select_i "$select_word" done;; *[!0-9]*) echo >&2 'Please enter a number in range.';; *) if test 1 -le $select_i && test $select_i -le $#; then - shift `expr $select_i - 1` + shift `$AWK "BEGIN { print $select_i - 1 }"` select_result=$1 break fi @@ -165,7 +169,7 @@ do esac done -shift `expr $OPTIND - 1` +shift `$AWK "BEGIN { print $OPTIND - 1 }"` case $# in 0) ;; *) say >&2 "$0: $1: unknown argument"; exit 1 @@ -439,7 +443,12 @@ while continent=$select_result case $continent in Americas) continent=America;; - *" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''` + *) + # Get the first word of $continent. Path expansion is disabled + # so this works even with "*", which should not happen. + IFS=" " + for continent in $continent ""; do break; done + IFS=$newline;; esac case $zonetabtype,$continent in zonenow,*) ;; @@ -746,15 +755,18 @@ while do TZdate=`LANG=C TZ="$TZ_for_date" date` UTdate=`LANG=C TZ=UTC0 date` - TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'` - UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'` - case $TZsec in - $UTsec) + if $AWK ' + function getsecs(d) { + return match(d, /.*:[0-5][0-9]/) ? substr(d, RLENGTH - 1, 2) : "" + } + BEGIN { exit getsecs(ARGV[1]) != getsecs(ARGV[2]) } + ' ="$TZdate" ="$UTdate" + then extra_info=" Selected time is now: $TZdate. Universal Time is now: $UTdate." break - esac + fi done -- 2.40.1
* tzselect.ksh: Rewrite to not use the sed command. It’s used only in one place, and awk can do it; this removes a dependency of tzselect on sed. --- tzselect.ksh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tzselect.ksh b/tzselect.ksh index cc58db03..8e66b30d 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -511,7 +511,7 @@ while "$output_distances_or_times" \ ="$coord" ="$TZ_COUNTRY_TABLE" ="$TZ_ZONE_TABLE" | sort -n | - sed "${location_limit}q" + $AWK "{print} NR == $location_limit { exit }" ` regions=` $AWK ' -- 2.40.1
* tzselect.ksh: Rewrite to not use the pwd command when developing, except on ancient shells where PWD does not work. This removes a dependency when developing on non-ancient platforms. --- tzselect.ksh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tzselect.ksh b/tzselect.ksh index 8e66b30d..c56bc822 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -45,7 +45,8 @@ set -f # Specify default values for environment variables if they are unset. : ${AWK=awk} -: ${TZDIR=`pwd`} +: ${PWD=`pwd`} +: ${TZDIR=$PWD} # Output one argument as-is to standard output, with trailing newline. # Safer than 'echo', which can mishandle '\' or leading '-'. -- 2.40.1
participants (1)
-
Paul Eggert