Bug#566013: [swaks] sends mails from a weird timezone

Niko Tyni ntyni at debian.org
Wed Jan 27 20:23:47 UTC 2010


On Wed, Jan 27, 2010 at 10:24:08AM -0600, Gunnar Wolf wrote:
 
> In any case, the potentially offending code (that means, the code that
> generates the date string - For the full code, /usr/bin/swaks lines
> 1532-1552) is:
> 
> sub get_date_string {
>   (…)
>   my @l = localtime();
>   (…)
>   my @g = gmtime();
>   $o = (timelocal(@l) - timelocal(@g))/36;
>   (…)
> }

> --- /usr/share/perl/5.10.1/Time/Local.pm	2009-11-21 13:30:05.000000000 -0600
> +++ /tmp/Local.pm				2010-01-27 10:21:17.000000000 -0600
> @@ -177,7 +177,11 @@
>      my ( $s, $m, $h ) = localtime($loc_t);
>      $loc_t -= $dst_off if $s != $_[0] || $m != $_[1] || $h != $_[2];
>  
> -    return $loc_t;
> +    # Comparing two very-slightly-off readings of the clock yields a
> +    # difference of -0.027777 seconds. Timezones are integers, and
> +    # represent the number of seconds; round (don't truncate) the
> +    # result as values ending with '99' are not valid.
> +    return int($loc_t + 0.5); 
>  }

Sorry if I'm dense, but I don't see Time::Local doing anything wrong here.
It's not a case of 0.027777 seconds - both localtime and gmtime have a
resolution of 1 second (as long as Time::HiRes is out of the picture).

Rather, the buggy code in swaks ends up dividing a one second difference
between the localtime() and gmtime() invocations by 36, giving the
magic 0.027777.

The zone handling code in timelocal() already does the right thing: it's
calling localtime with an argument so it doesn't look at the current time.
So should swaks.

perl -e '$|=1;use Time::Local; $sys_tz=`date +%z`*1; $i=0; while (1) { $ref=localtime; @l=localtime($ref); @g=gmtime($ref); $o=(timelocal(@l) - timelocal(@g))/36; print "." unless $i++%1000; print $o if $o ne $sys_tz}'

Please reassign back if you agree.
-- 
Niko Tyni   ntyni at debian.org






More information about the Perl-maintainers mailing list