Subject: | Bug in File::Tail->position(), patch included. |
Date: | Sat, 18 Jan 2014 03:45:19 +0000 |
To: | "'bug-File-Tail [...] rt.cpan.org'" <bug-File-Tail [...] rt.cpan.org> |
From: | James Johnson <james.johnson [...] equifax.com> |
After using File::Tail for a couple of years, I ran into an edge case this week. My value for the 'tail' constructor parameter and my particular input file's format (an inconsistent combination of very long and relatively short lines) caused the while() loop in the position() method to go into an infinite loop.
My first fix was to force $avlen to an integer value but I suspect that would also fail under the right circumstances. The patch below detects when the file position has not changed and adds $avlen padding to the input buffer. This forces $avlen to increase in the next iteration which, in turn, forces $curpos closer to the beginning of the file.
Show quoted text
> rpm -q perl-File-Tail
perl-File-Tail-0.99.3-1.22.x86_64
Show quoted text>
> perl -v
This is perl, v5.10.0 built for x86_64-linux-thread-multi
Copyright 1987-2007, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Show quoted text>
> uname -a
Linux jamestest 3.0.93-0.5-default #1 SMP Tue Aug 27 08:17:02 UTC 2013 (925d406) x86_64 x86_64 x86_64 GNU/Linux
Show quoted text>
> cat /etc/SuSE-release
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 2
Show quoted text>
Patch:
*** Tail.pm.orig 2014-01-18 03:29:25.048024000 +0000
--- Tail.pm 2014-01-18 03:30:50.665179000 +0000
***************
*** 296,301 ****
--- 296,302 ----
} else {
my $crs=0;
my $maxlen=sysseek($object->{handle},0,SEEK_END);
+ my $last_curpos = -1;
while ($crs<$object->{"tail"}+1) {
my $avlen=length($object->{"buffer"})/($crs+1);
$avlen=80 unless $avlen;
***************
*** 307,312 ****
--- 308,314 ----
$calclen);
$object->{curpos}=sysseek($object->{handle},0,SEEK_CUR);
$crs=$object->{"buffer"}=~tr/\n//;
+ $object->{"buffer"} = $object->{"buffer"} . ' 'x$avlen if( $object->{"curpos"} >= $last_curpos );
last if ($calclen>=$maxlen);
}
$object->{curpos}=sysseek($object->{handle},0,SEEK_CUR);