Skip Menu |

This queue is for tickets about the File-Tail CPAN distribution.

Report information
The Basics
Id: 92248
Status: resolved
Priority: 0/
Queue: File-Tail

People
Owner: Nobody in particular
Requestors: james.johnson [...] equifax.com
Cc:
AdminCc:

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



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);
So I've just ran into exact same issue, and am wondering when will it be fixed? For myself, though, I've patched it the same but different way as the OP, the diff's attached. Didn't like the idea of modifying buffer because it possibly can cause additional bugs like some junk in the output.
Subject: my.diff
--- Tail.pm.orig 2015-04-21 14:13:12.028579518 +0300 +++ Tail.pm 2015-04-21 14:29:16.948533099 +0300 @@ -298,12 +298,15 @@ } else { my $crs=0; my $maxlen=sysseek($object->{handle},0,SEEK_END); + my $prev_len = undef; while ($crs<$object->{"tail"}+1) { my $avlen=length($object->{"buffer"})/($crs+1); $avlen=80 unless $avlen; my $calclen=$avlen*$object->{"tail"}; $calclen+=1024 if $calclen<=length($object->{"buffer"}); $calclen=$maxlen if $calclen>$maxlen; + $calclen+=1024 if defined $prev_len && ( $calclen == $prev_len ); + $prev_len=$calclen; $object->{curpos}=sysseek($object->{handle},-$calclen,SEEK_END); sysread($object->{handle},$object->{"buffer"}, $calclen);
Thanks for pointing out the problem, I decided to do the fix in a slightly different way.
Seems that the issue still persists. Also I'm not sure what this new code you've put in here is supposed to mean: Show quoted text
> $calclen=length($object->{tail})+1024 if $calclen<=length($object->{"tail"});
( https://metacpan.org/source/MGRABNAR/File-Tail-1.2/Tail.pm#L305 ) For what reason it measures length of the number of lines to be read?
I've tried to change that line to something like that: $calclen+=1024 if $calclen<=length($object->{"buffer"}); But it yielded me no luck because the values were these: $calclen = 269.35 * 100 = 26935 length($buffer): 26935 ( $calclen <=> length($buffer) ): 1 ( $calclen - length($buffer) ): 3.63797880709171e-12 But everything seems to became fine when I do this: $calclen+=1024 if int($calclen)<=length($object->{"buffer"});
You are right, of course.