[PATCH 1/5] tzselect.ksh: TZ validation bugs
This commit fixes the following POSIX TZ validation bugs in tzselect.ksh. Did not allow: TZ name quoting (<, >): TZ="<EST+5>5" Allowed: TZ name == Non-alpha characters: TZ="E!T5" Time > 24 hours Julian date == J0 Julian date > J365 Julian date > 365 Month date > M12.x.x Month date > Mx.5.x Month date > Mx.x.6 Month date < M1.x.x Month date < Mx.1.x Signed-off-by: J William Piggott <elseifthen@gmx.com> --- tzselect.ksh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tzselect.ksh b/tzselect.ksh index df5621f..10570b6 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -346,11 +346,14 @@ while 'that is 10 hours ahead (east) of UTC.' read TZ $AWK -v TZ="$TZ" 'BEGIN { - tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+" - time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?" + tzname = "(<[[:alnum:]+-]{3,}>|[[:alpha:]]{3,})" + time = "(2[0-4]|[0-1]?[0-9])" \ + "(:[0-5][0-9](:[0-5][0-9])?)?" offset = "[-+]?" time - date = "(J?[0-9]+|M[0-9]+\\.[0-9]+\\.[0-9]+)" - datetime = "," date "(/" time ")?" + mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]" + jdate = "((J[1-9]|[0-9]|J?[1-2]?[0-9][0-9])" \ + "|J?3[0-5][0-9]|J?36[0-5])" + datetime = ",(" mdate "|" jdate ")(/" time ")?" tzpattern = "^(:.*|" tzname offset "(" tzname \ "(" offset ")?(" datetime datetime ")?)?)$" if (TZ ~ tzpattern) exit 1
The regions list criteria was only based on country. This caused, for example, all of Australia to be listed under the regions for Antarctica > Australia. This commit requires both country and continent to match for a region selection. Signed-off-by: J William Piggott <elseifthen@gmx.com> --- tzselect.ksh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tzselect.ksh b/tzselect.ksh index 10570b6..e9cc4c7 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -440,6 +440,7 @@ while # Get list of names of time zone rule regions in the country. regions=`$AWK \ -v country="$country" \ + -v continent="$continent" \ -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ ' BEGIN { @@ -453,7 +454,7 @@ while } } /^#/ { next } - $1 ~ cc { print $4 } + $1 ~ cc && $3 ~ ("^" continent "/"){ print $4 } ' <"$TZ_ZONE_TABLE"`
Signed-off-by: J William Piggott <elseifthen@gmx.com> --- tzselect.ksh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tzselect.ksh b/tzselect.ksh index e9cc4c7..905953c 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -455,7 +455,7 @@ while } /^#/ { next } $1 ~ cc && $3 ~ ("^" continent "/"){ print $4 } - ' <"$TZ_ZONE_TABLE"` + ' <"$TZ_ZONE_TABLE" | sort` # If there's more than one region, ask the user which one.
Local time is now: $TZdate. Universal Time is now: $UTdate. The above is assuming that the System Clock is set properly and that the caller is finding a 'local' time zone. Local time is unknown, the displayed time should be labeled as using the selected time zone. The System Clock scale is unknown and should be labeled as Raw System Time showing a time zone of RAW. Signed-off-by: J William Piggott <elseifthen@gmx.com> --- tzselect.ksh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tzselect.ksh b/tzselect.ksh index 905953c..3e8d07b 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -507,14 +507,14 @@ while for i in 1 2 3 4 5 6 7 8 do TZdate=`LANG=C TZ="$TZ_for_date" date` - UTdate=`LANG=C TZ=UTC0 date` + UTdate=`LANG=C TZ=RAW0 date` TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'` UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'` case $TZsec in $UTsec) extra_info=" -Local time is now: $TZdate. -Universal Time is now: $UTdate." +Time with selected TZ: $TZdate. +Raw System Clock time: $UTdate." break esac done
The last message from tzselect states: "... use the tzselect command in shell scripts" To do so there needs to be a way to silence the dialog tail. This commit adds an -s option to facilitate that. Signed-off-by: J William Piggott <elseifthen@gmx.com> --- tzselect.ksh | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/tzselect.ksh b/tzselect.ksh index 3e8d07b..41a430f 100644 --- a/tzselect.ksh +++ b/tzselect.ksh @@ -50,11 +50,12 @@ say() { exit 1 } +script_mode=0 coord= location_limit=10 zonetabtype=zone1970 -usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT] +usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT] [-s] Select a time zone interactively. Options: @@ -70,7 +71,11 @@ Options: -n LIMIT Display at most LIMIT locations when -c is used (default $location_limit). - --version + -s + Silence the dialog, after the confirmation prompt is answered, to + facilitate calling tzselect from other applications. + + --version Output version information. --help @@ -146,13 +151,15 @@ else } fi -while getopts c:n:t:-: opt +while getopts sc:n:t:-: opt do case $opt$OPTARG in c*) coord=$OPTARG ;; n*) location_limit=$OPTARG ;; + s ) + script_mode=1 ;; t*) # Undocumented option, used for developer testing. zonetabtype=$OPTARG ;; -help) @@ -544,17 +551,19 @@ Raw System Clock time: $UTdate." do coord= done -case $SHELL in -*csh) file=.login line="setenv TZ '$TZ'";; -*) file=.profile line="TZ='$TZ'; export TZ" -esac +if test $script_mode -ne 1 ; then + case $SHELL in + *csh) file=.login line="setenv TZ '$TZ'";; + *) file=.profile line="TZ='$TZ'; export TZ" + esac -say >&2 " + say >&2 " You can make this change permanent for yourself by appending the line $line to the file '$file' in your home directory; then log out and log in again. Here is that TZ value again, this time on standard output so that you can use the $0 command in shell scripts:" +fi say "$TZ"
J William Piggott wrote:
To do so there needs to be a way to silence the dialog tail.
Sorry, I don't see why the dialog tail needs to be silenced. It's sent to stderr, just like all the other stderr messages (which also don't need to be silenced). A script that wants to capture the resulting zone should capture just stdout.
On 02/13/2016 02:16 AM, Paul Eggert wrote:
J William Piggott wrote:
To do so there needs to be a way to silence the dialog tail.
Sorry, I don't see why the dialog tail needs to be silenced. It's sent to stderr, just like all the other stderr messages (which also don't need to be silenced). A script that wants to capture the resulting zone should capture just stdout.
After the calling script receives the selected time zone, then it determines what to do with it and how to reply to the user. So the following tail dialog (after the confirmation) makes no sense: ______________________________ Is the above information OK? 1) Yes 2) No #? 1 You can make this change permanent for yourself by appending the line TZ='America/New_York'; export TZ to the file '.profile' in your home directory; then log out and log in again. Here is that TZ value again, this time on standard output so that you can use the /usr/bin/tzselect command in shell scripts: America/New_York ______________________________ It needs to end after the user confirms, and the calling script takes over from there. The tail dialog is distracting, confusing, and unnecessary.
J William Piggott wrote:
After the calling script receives the selected time zone, then it determines what to do with it and how to reply to the user. So the following tail dialog (after the confirmation) makes no sense:
______________________________
Is the above information OK? 1) Yes 2) No #? 1
You can make this change permanent for yourself by appending the line TZ='America/New_York'; export TZ to the file '.profile' in your home directory; then log out and log in again.
Here is that TZ value again, this time on standard output so that you can use the /usr/bin/tzselect command in shell scripts: America/New_York ______________________________
It needs to end after the user confirms, and the calling script takes over from there. The tail dialog is distracting, confusing, and unnecessary.
Sorry, I'm not following the chronology, as the calling script cannot possibly receive the selected time zone until after tzselect outputs the tail dialog. So if the calling script knows that the user has confirmed, it can filter out any further stderr output it doesn't want; and if it doesn't know, it shouldn't care. Perhaps you could give a runnable example of a calling script to illustrate the bug?
On 02/13/2016 01:19 PM, Paul Eggert wrote:
J William Piggott wrote:
After the calling script receives the selected time zone, then it determines what to do with it and how to reply to the user. So the following tail dialog (after the confirmation) makes no sense:
______________________________
Is the above information OK? 1) Yes 2) No #? 1
You can make this change permanent for yourself by appending the line TZ='America/New_York'; export TZ to the file '.profile' in your home directory; then log out and log in again.
Here is that TZ value again, this time on standard output so that you can use the /usr/bin/tzselect command in shell scripts: America/New_York ______________________________
It needs to end after the user confirms, and the calling script takes over from there. The tail dialog is distracting, confusing, and unnecessary.
Sorry, I'm not following the chronology, as the calling script cannot possibly receive the selected time zone until after tzselect outputs the tail dialog. So if the calling script knows that the user has confirmed, it can filter out any further stderr output it doesn't want; and if it doesn't know, it shouldn't care.
Perhaps you could give a runnable example of a calling script to illustrate the bug?
#!/bin/sh tzselect > /tmp/tz TIMEZONE=`cat /tmp/tz` # Do something here like # cp /usr/share/zoneinfo/$TIMEZONE /etc/localtime rm -f /tmp/tz echo "The System Time Zone is now set to $TIMEZONE"
Thanks for the scenario. How about the attached patch instead?
On 02/14/2016 12:14 AM, Paul Eggert wrote:
Thanks for the scenario. How about the attached patch instead?
It won't work, the output must be a terminal or the user would not be able to select a time zone ( I did test it to verify my opinion ). What do you not like about my solution? It is a simple change which has no impact on the default behavior.
Whoops, I spoke too soon. I forgot to modify my test script to use the patched tzselect. Your solution does work. So it looks good to me. On 02/14/2016 12:15 PM, J William Piggott wrote:
On 02/14/2016 12:14 AM, Paul Eggert wrote:
Thanks for the scenario. How about the attached patch instead?
It won't work, the output must be a terminal or the user would not be able to select a time zone ( I did test it to verify my opinion ).
What do you not like about my solution? It is a simple change which has no impact on the default behavior.
On Jan 20, 11:47am, elseifthen@gmx.com (J William Piggott) wrote: -- Subject: [tz] [PATCH 4/5] tzselect.ksh: time scales assumed | TZdate=`LANG=C TZ="$TZ_for_date" date` It would be good to stop using backquotes for command substitution at some point. We are requiring ksh for this script anyway... christos
Christos Zoulas wrote:
It would be good to stop using backquotes for command substitution at some point. We are requiring ksh for this script anyway...
The script does not require ksh; it tests dynamically for ksh extensions and uses them only if present. Also, the script uses backquotes for portability to Solaris /bin/sh. A comment in the script says: # For portability to Solaris 9 /bin/sh this script avoids some POSIX # features and common extensions, such as $(...) (which works sometimes # but not others), $((...)), and $10. The same problem occurs with Solaris 10 /bin/sh, which Oracle says they'll support until January 2021. Solaris 10 typically comes with other shells too, but we might as well continue to support /bin/sh if it's easy. I think Solaris finally switched to a POSIX-compatible /bin/sh in Solaris 11.
On Feb 12, 11:53pm, eggert@cs.ucla.edu (Paul Eggert) wrote: -- Subject: Re: [tz] [PATCH 4/5] tzselect.ksh: time scales assumed | Christos Zoulas wrote: | > It would be good to stop using backquotes for command substitution | > at some point. We are requiring ksh for this script anyway... | | The script does not require ksh; it tests dynamically for ksh extensions and | uses them only if present. Also, the script uses backquotes for portability to | Solaris /bin/sh. A comment in the script says: | | # For portability to Solaris 9 /bin/sh this script avoids some POSIX | # features and common extensions, such as $(...) (which works sometimes | # but not others), $((...)), and $10. | | The same problem occurs with Solaris 10 /bin/sh, which Oracle says they'll | support until January 2021. Solaris 10 typically comes with other shells too, | but we might as well continue to support /bin/sh if it's easy. | | I think Solaris finally switched to a POSIX-compatible /bin/sh in Solaris 11. -- End of excerpt from Paul Eggert
J William Piggott wrote:
Local time is unknown, the displayed time should be labeled as using the selected time zone.
The System Clock scale is unknown and should be labeled as Raw System Time showing a time zone of RAW.
The former makes sense, but the latter would be more confusing than helpful, as the tz system assumes that the system clock uses Universal Time and the benefit of reminding the user here that this is merely an assumption seems considerably smaller than the cost of the added confusion. I installed the attached patch to address the former issue.
J William Piggott wrote:
The regions list criteria was only based on country. This caused, for example, all of Australia to be listed under the regions for Antarctica > Australia.
Here, I think the current behavior is intended. The idea is that if one selects (say) the United States, it's common to want to select Hawaii next, even if one came to the United States selection via North America rather than via the Pacific. That is, the selection is not via a tree but is via a DAG, and the difference matters when a country crosses continental borders. The same comment applies to the later patches that assume this one.
participants (3)
-
christos@zoulas.com -
J William Piggott -
Paul Eggert