Hi all,

I have discovered a problem with Heirloom mailx, which I'm able to also
reproduce in s-nail (I understand mailx is no longer maintained).

The problem is that sending an email produces a "Date:" header that is
incorrect when the system is in the Europe/Dublin timezone (email
appears to have been sent 2 hours earlier).

Minimal code to reproduce the issue:

root@darkstar:~# rm -f ~/dead.letter && TZ=Europe/Dublin mailx -S
mta=no-thank-you root < /dev/null; cat ~/dead.letter
mailx: No message, no subject; hope that's ok
mailx: Cannot start no-thank-you: executable not found (adjust *mta*
variable) /root/dead.letter 6/111 mailx: ... message not sent
From root Fri Nov  5 15:44:19 2021
Date: Fri, 05 Nov 2021 15:44:19 +0200
To: root
User-Agent: mailx v14.9.22

Compare with this other timezone in the same island (which is actually
Europe/London):

root@darkstar:~# rm -f ~/dead.letter && TZ=Europe/Belfast mailx -S
mta=no-thank-you root < /dev/null; cat ~/dead.letter mailx: No message,
no subject; hope that's ok mailx: Cannot start no-thank-you: executable
not found (adjust *mta* variable) /root/dead.letter 6/111
mailx: ... message not sent
From root Fri Nov  5 15:44:28 2021
Date: Fri, 05 Nov 2021 15:44:28 +0000
To: root
User-Agent: mailx v14.9.22

The first one is wrong-- as someone who lives in Ireland, I can
testify!.

In both cases, the output of other programs is as expected (for
example: "date", "date --utc", "date --rfc-2822").

Looking at the source of s-nail, I tracked it all down to a
naive/incorrect handling of tm->tm_isdst in mkdate() in sendout.c (the
same logic appears in other places, for example see the comment in
src/mx/header.c that reads "/* TODO simply adding an hour for ISDST
is .. buuh */".)

After a lot of research (and I feel I've become an expert on the
subject by now!) this is what I've found:

In 2018, the tzdata maintainers (IANA) corrected a historical mistake
with the Europe/Dublin timezone. The mistake was rooted in a
misunderstanding of whether IST meant "Irish Summer Time" or "Irish
Standard Time".

The problem was discussed at great length
(http://mm.icann.org/pipermail/tz/2018-January/thread.html) and it was
concluded that IST really meant Irish *Standard* Time (in constrast
with, say, British *Summer* Time), and that this standard time is
defined as UTC+0100.

This corresponds to the article at
https://en.wikipedia.org/wiki/Time_in_the_Republic_of_Ireland and the
notes at https://en.wikipedia.org/wiki/Winter_time_(clock_lag); the
source archive of tzdata has a long section dedicated to this problem
and a large set of official references and links to
www.irishstatutebook.ie.

Once the question was settled, the only possible solution for keeping
the Irish local time in sync with the rest of the world (for example,
Belfast & London) was for IANA to _reverse_ the functioning of the DST
flag for Ireland. The result is that in the current IANA timezone
database (2021e), Europe/Dublin has DST applied in *winter*, with an
adjustment of -1h (that is, negative). 

Digging deeper, one uncovers that there are a few other countries that
have (or once had) the same time-switch mechanism as Ireland;
amongst others, https://github.com/MenoData/Time4J/issues/742 also
concedes that negative DST is a reality.

In s-nail, the logic that works out the UTC offset does the right
thing in my testcase (october 2021, Ireland = UTC+0100), but then upon
inspecting tm->tm_isdst it sees that DST is in effect (remember,
flag has been reversed, so DST in Ireland is on in winter time) it adds
one hour (it should subtract one, because the adjustment is negative).

That's why I get a +0200 instead of +0000 out of s-nail.

You may wonder why this problem hasn't been noticed by Irish people in
the past three years (hey, there's quite an IT industry over here!).

It turns out that the introduction of a negative DST adjustment caused
all sorts of bugs back in 2018; in the source distribution of IANA's
tzdata, one can spot this inside ./europe:

  # In January 2018 we discovered that the negative SAVE values in the
  # Eire rules cause problems with tests for ICU [...] and with tests
  # for OpenJDK [...]
  # To work around this problem, the build procedure can translate the
  # following data into two forms, one with negative SAVE values and the
  # other form with a traditional approximation for Irish timestamps
  # after 1971-10-31 02:00 UTC; although this approximation has tm_isdst
  # flags that are reversed, its UTC offsets are correct and this often
  # suffices.  This source file currently uses only nonnegative SAVE
  # values, but this is intended to change and downstream code should
  # not rely on it.

So, a temporary hack was put in place in order to allow distro
maintainers to retain the old broken convention of IST and support
buggy software, but it is clear that the current (and technically, and
politically, correct) implementation of a negative DST adjustment for
Ireland is there to stay.

As a matter of fact, the distro maintainer can choose to compile
tzdata to keep buggy software happy ("make DATAFORM=rearguard"),
which replicates the behaviour of tzdata prior to 2018. Many distros
seem to be doing that for one reason or another, while some have passed
the upstream change down to their users (probably, without knowing).

(also, remember that the IANA tz database is basically the only source
of tz data and is used globally by pretty much anybody who has a system
clock; I can see why embedded platforms may not be easy to patch to
support the negative DST adjustment).

This explains why I see this problem in Slackware, but not on, for
example, CentOS (and also why some tools work correctly, and some, like
s-nail in this case, does not).

I am in the process of evaluating different approaches to solve this
bug in a portable way (e.g. without relying on non-standard extensions
like tm->tm_gmtoff, strftime's "%z" or timelocal()/gmtime()).

I can, however, only test some portions of the patch (in particular, I
don't use IMAP).

I would like to know if a patch is welcome and whether there is
bandwidth to review it and eventually merge it in.

Thanks,
Andrea.

Reply via email to