Skip Menu |

This queue is for tickets about the Mail-Bulkmail CPAN distribution.

Report information
The Basics
Id: 1932
Status: resolved
Priority: 0/
Queue: Mail-Bulkmail

People
Owner: Nobody in particular
Requestors: ddkilzer [...] kilzer.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: Broken timezone specification generated by Bulkmail.pm
The Tz() method in Mail::Bulkmail occasionally generates invalid timezone offsets (outside the range -1200 to +1200). This post to the freebsd-ports mailing list by David Wolfskill from Nov 28, 2001 details the issues (both URLs to go the same message): http://www.geocrawler.com/archives/3/167/2001/11/100/7193611/ http://www.geocrawler.com/mail/msg.php3?msg_id=7193611&list=167 The patch in the above mail message was attached to this bug report for reference purposes (in case the URLs above cease working before this bug gets fixed). Here is the contents of the original message itself: FROM: David Wolfskill DATE: 11/28/2001 21:42:54 SUBJECT: ports/32372: Broken timezone specification generated by Bulkmail.pm Show quoted text
>Number: 32372 >Category: ports >Synopsis: Broken timezone specification generated by Bulkmail.pm >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Nov 28 21:50:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: David Wolfskill >Release: FreeBSD 4.1.1-STABLE i386 >Organization:
Whistle Communications Show quoted text
>Environment:
Use the /usr/ports/mail/p5-Mail-Bulkmail (Mail::Bulkmail) port. Show quoted text
>Description:
The Bulkmail.pm module generates its own Date: header for the messages it sends. One of the fields in the Date: header is the time specification, which includes a "timezone" specification, which denotes the number of hours and minutes the time in question is offset from UTC (GMT), as well as the direction of that offset. The module has a function ("Tz", starting at line 703) to compute the above-mentioned offset. The function will, under some circumstances, produce and return values that are not within the range -1200 to +1200, and has the (slight!) possibility of returning a value that is otherwise incorrect. (This latter is highly improbable, but easily fixed.) The Tz() function works by using the "hours" and "minutes" part of the current time; in particular, it examines and uses the difference between the "localtime()" and the "gmtime()" results. There are some problems, though: * There is code to check to see if the magnitude of the difference exceeds 12 hours. However, in such a case, the result is adjusted by 12 hours, rather than the 24 hours that would be correct. (For example, sending a message at 1703 hrs. local time, from a time zone that is 8 hrs. west of GMT -- so that the time in question is 0103 hrs. UTC/GMT the following day -- would yield a difference of 16 hrs. Since this is >12, the code then subtracts that difference (16) from 12, yielding -4. Rather, the code should subtract 24 from the difference in the ">12" case, yielding -8 hrs., which is correct.) * Even though the "difference" is "corrected" (albeit incorrectly, per the above), there is a sprintf() call immediately afterward that clobbers the "correction" anyway, so the reported offset in the above example will be "1600", which is outside the range of -1200 to +1200. Note that the extent to which this result will be in error depends on the magnitude of the offset between local time and UTC/GMT, as well as the time of day of the experiment. * There is no provision to ensure that an offset that has a non-zero "minutes" component actually has the direction of the minutes component that agrees with the direction of the hours component. (For 0- or 30-minute offsets, this isn't likely to matter much.) * Finally, the exceedingly improbable error is caused by the use of two *different* calls to Perl's time() function (one for the localtime() call; the other for the gmtime() call). It is possible, though (very!) unlikely that the two calls will be made at times such that the results could be on either side of a minute (or even hour) boundary. The cure for this is to invoke time() but once, save the value, and use that for each of the localtime() and gmtime() calls. Show quoted text
>How-To-Repeat:
Well, here are the salient headers from an example such as the one described above: Received: from us.ibm.com (pau-amma.whistle.com [207.76.205.64]) by gatekeeper.whistle.com (8.11.1/8.11.1) with SMTP id fAS13NE20829 for <<EMAIL: PROTECTED>>; Tue, 27 Nov 2001 17:03:23 -0800 (PST) Message-Id: <<EMAIL: PROTECTED>> Date: Tue, 27 Nov 2001 17:03:23 +1600 Note the timezone specification in the Date: header vs. that in the Received: header. Had this been done between 0000 - 1559 hrs. PST (8 hrs. west of GMT), the error would not have been apparent. Show quoted text
>Fix:
Apply the following patch to Bulkmail.pm: --- Bulkmail.pm.orig Fri Sep 7 12:28:16 2001 +++ Bulkmail.pm Wed Nov 28 07:27:50 2001 @@ -704,16 +704,31 @@ my $self = shift or undef; - my ($min, $hour, $isdst) = (localtime(time))[1,2,-1]; - my ($gmin, $ghour, $gsdst) = (gmtime(time))[1,2, -1]; + my $now = time; + my ($min, $hour, $isdst) = (localtime($now))[1,2,-1]; + my ($gmin, $ghour, $gsdst) = (gmtime($now))[1,2, -1]; - my $diffhour = $hour - $ghour; - $diffhour = 12 - $diffhour if $diffhour > 12; - $diffhour = 12 + $diffhour if $diffhour < -12; + my $diffmin = ($hour - $ghour) * 60 + ($min - $gmin); + my $diffhour = int($diffmin / 60); + $diffmin -= $diffhour * 60; + if ($diffhour > 12) { + $diffhour -= 24; + if ($diffmin) { + $diffhour += 1; + $diffmin -= 60; + } + } elsif ($diffhour < -12) { + $diffhour += 24; + if ($diffmin) { + $diffhour -= 1; + $diffmin += 60; + } + } + $diffmin = abs($diffmin); - ($diffhour = sprintf("%03d", $hour - $ghour)) =~ s/^0/\+/; + ($diffhour = sprintf("%03d%02d", $diffhour, $diffmin)) =~ s/^0/\+/; - return $diffhour . sprintf("%02d", $min - $gmin); + return $diffhour; }; Show quoted text
>Release-Note: >Audit-Trail: >Unformatted:
To Unsubscribe: send mail to <EMAIL: PROTECTED> with "unsubscribe freebsd-ports" in the body of the message
--- Bulkmail.pm.orig Fri Sep 7 12:28:16 2001 +++ Bulkmail.pm Wed Nov 28 07:27:50 2001 @@ -704,16 +704,31 @@ my $self = shift or undef; - my ($min, $hour, $isdst) = (localtime(time))[1,2,-1]; - my ($gmin, $ghour, $gsdst) = (gmtime(time))[1,2, -1]; + my $now = time; + my ($min, $hour, $isdst) = (localtime($now))[1,2,-1]; + my ($gmin, $ghour, $gsdst) = (gmtime($now))[1,2, -1]; - my $diffhour = $hour - $ghour; - $diffhour = 12 - $diffhour if $diffhour > 12; - $diffhour = 12 + $diffhour if $diffhour < -12; + my $diffmin = ($hour - $ghour) * 60 + ($min - $gmin); + my $diffhour = int($diffmin / 60); + $diffmin -= $diffhour * 60; + if ($diffhour > 12) { + $diffhour -= 24; + if ($diffmin) { + $diffhour += 1; + $diffmin -= 60; + } + } elsif ($diffhour < -12) { + $diffhour += 24; + if ($diffmin) { + $diffhour -= 1; + $diffmin += 60; + } + } + $diffmin = abs($diffmin); - ($diffhour = sprintf("%03d", $hour - $ghour)) =~ s/^0/\+/; + ($diffhour = sprintf("%03d%02d", $diffhour, $diffmin)) =~ s/^0/\+/; - return $diffhour . sprintf("%02d", $min - $gmin); + return $diffhour; };
From: Jim
Sorry, just getting around to updating things on here now. This has (finally) been fixed as of v3.00. [guest - Thu Jan 9 12:58:13 2003]: Show quoted text
> The Tz() method in Mail::Bulkmail occasionally generates invalid > timezone offsets (outside the range -1200 to +1200). This post > to the freebsd-ports mailing list by David Wolfskill from Nov 28, > 2001 details the issues (both URLs to go the same message): > > http://www.geocrawler.com/archives/3/167/2001/11/100/7193611/ > http://www.geocrawler.com/mail/msg.php3?msg_id=7193611&list=167 > > The patch in the above mail message was attached to this bug > report for reference purposes (in case the URLs above cease > working before this bug gets fixed). Here is the contents of the > original message itself: > > > FROM: David Wolfskill > DATE: 11/28/2001 21:42:54 > SUBJECT: ports/32372: Broken timezone specification generated by > Bulkmail.pm >
> >Number: 32372 > >Category: ports > >Synopsis: Broken timezone specification generated by
> Bulkmail.pm
> >Confidential: no > >Severity: non-critical > >Priority: low > >Responsible: freebsd-ports > >State: open > >Quarter: > >Keywords: > >Date-Required: > >Class: sw-bug > >Submitter-Id: current-users > >Arrival-Date: Wed Nov 28 21:50:01 PST 2001 > >Closed-Date: > >Last-Modified: > >Originator: David Wolfskill > >Release: FreeBSD 4.1.1-STABLE i386 > >Organization:
> Whistle Communications
> >Environment:
> > Use the /usr/ports/mail/p5-Mail-Bulkmail (Mail::Bulkmail) port. >
> >Description:
> > The Bulkmail.pm module generates its own Date: header for the > messages it sends. One of the fields in the Date: header is the > time specification, which includes a "timezone" specification, > which denotes the number of hours and minutes the time in > question is offset from UTC (GMT), as well as the direction of > that offset. > > The module has a function ("Tz", starting at line 703) to > compute the above-mentioned offset. The function will, under > some circumstances, produce and return values that are not > within the range -1200 to +1200, and has the (slight!) > possibility of returning a value that is otherwise incorrect. > (This latter is highly improbable, but easily fixed.) > > The Tz() function works by using the "hours" and "minutes" part > of the current time; in particular, it examines and uses the > difference between the "localtime()" and the "gmtime()" results. > There are some problems, though: > > * There is code to check to see if the magnitude of the > difference exceeds 12 hours. However, in such a case, the > result is adjusted by 12 hours, rather than the 24 hours that > would be correct. (For example, sending a message at 1703 > hrs. local time, from a time zone that is 8 hrs. west of GMT > -- so that the time in question is 0103 hrs. UTC/GMT the > following day -- would yield a difference of 16 hrs. Since > this is >12, the code then subtracts that difference (16) from > 12, yielding -4. Rather, the code should subtract 24 from the > difference in the ">12" case, yielding -8 hrs., which is > correct.) > > * Even though the "difference" is "corrected" (albeit > incorrectly, per the above), there is a sprintf() call > immediately afterward that clobbers the "correction" anyway, > so the reported offset in the above example will be "1600", > which is outside the range of -1200 to +1200. Note that the > extent to which this result will be in error depends on the > magnitude of the offset between local time and UTC/GMT, as > well as the time of day of the experiment. > > * There is no provision to ensure that an offset that has a > non-zero "minutes" component actually has the direction of the > minutes component that agrees with the direction of the hours > component. (For 0- or 30-minute offsets, this isn't likely to > matter much.) > > * Finally, the exceedingly improbable error is caused by the use > of two *different* calls to Perl's time() function (one for > the localtime() call; the other for the gmtime() call). It is > possible, though (very!) unlikely that the two calls will be > made at times such that the results could be on either side of > a minute (or even hour) boundary. The cure for this is to > invoke time() but once, save the value, and use that for each > of the localtime() and gmtime() calls. >
> >How-To-Repeat:
> > Well, here are the salient headers from an example such as the > one described above: > > Received: from us.ibm.com (pau-amma.whistle.com [207.76.205.64]) > by gatekeeper.whistle.com (8.11.1/8.11.1) with SMTP id fAS13NE20829 > for <<EMAIL: PROTECTED>>; Tue, 27 Nov 2001 17:03:23 -0800 (PST) > Message-Id: <<EMAIL: PROTECTED>> > Date: Tue, 27 Nov 2001 17:03:23 +1600 > > Note the timezone specification in the Date: header vs. that in > the Received: header. Had this been done between 0000 - 1559 > hrs. PST (8 hrs. west of GMT), the error would not have been > apparent.
> >Fix:
> > Apply the following patch to Bulkmail.pm: > > --- Bulkmail.pm.orig Fri Sep 7 12:28:16 2001 > +++ Bulkmail.pm Wed Nov 28 07:27:50 2001 > @@ -704,16 +704,31 @@ > > my $self = shift or undef; > > - my ($min, $hour, $isdst) = (localtime(time))[1,2,-1]; > - my ($gmin, $ghour, $gsdst) = (gmtime(time))[1,2, -1]; > + my $now = time; > + my ($min, $hour, $isdst) = (localtime($now))[1,2,-1]; > + my ($gmin, $ghour, $gsdst) = (gmtime($now))[1,2, -1]; > > - my $diffhour = $hour - $ghour; > - $diffhour = 12 - $diffhour if $diffhour > 12; > - $diffhour = 12 + $diffhour if $diffhour < -12; > + my $diffmin = ($hour - $ghour) * 60 + ($min - $gmin); > + my $diffhour = int($diffmin / 60); > + $diffmin -= $diffhour * 60; > + if ($diffhour > 12) { > + $diffhour -= 24; > + if ($diffmin) { > + $diffhour += 1; > + $diffmin -= 60; > + } > + } elsif ($diffhour < -12) { > + $diffhour += 24; > + if ($diffmin) { > + $diffhour -= 1; > + $diffmin += 60; > + } > + } > + $diffmin = abs($diffmin); > > - ($diffhour = sprintf("%03d", $hour - $ghour)) =~ s/^0/\+/; > + ($diffhour = sprintf("%03d%02d", $diffhour, $diffmin)) =~ s/^0/\+/; > > - return $diffhour . sprintf("%02d", $min - $gmin); > + return $diffhour; > > };
> >Release-Note: > >Audit-Trail: > >Unformatted:
> > To Unsubscribe: send mail to <EMAIL: PROTECTED> > with "unsubscribe freebsd-ports" in the body of the message