Skip Menu |

This queue is for tickets about the DateTime-Set CPAN distribution.

Report information
The Basics
Id: 47945
Status: resolved
Worked: 1 hour (60 min)
Priority: 0/
Queue: DateTime-Set

People
Owner: FGLOCK [...] cpan.org
Requestors: nils.grunwald [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.27
Fixed in: (no value)



Subject: segfault when using as_list on large enough sets
Hello, here is a test case for this bug, which causes a segfault: use DateTime::Set; use DateTime; my $span = DateTime::Span->from_datetimes( start => DateTime->new( year => 1971 ), end => DateTime->new( year => 2009 ) ); my $set = DateTime::Set->from_recurrence( recurrence => sub { return $_[ 0 ] if $_[ 0 ]->is_infinite; return $_[ 0 ]->truncate( to => 'day' )->add( days => 1 ); }, ); my @array = $set->as_list( span => $span ); I have tested it on two machines with the same result, with perl 5.8.8 and perl 5.10 under Linux. Memory comsumption is well under what is available. If starting date is 1980 or more, everything runs fine.
Subject: Re: [rt.cpan.org #47945] segfault when using as_list on large enough sets
Date: Sun, 19 Jul 2009 10:48:48 +0200
To: bug-DateTime-Set [...] rt.cpan.org
From: "Flavio S. Glock" <fglock [...] gmail.com>
The error happens after the day list is built. It may be a perl memory allocation bug. I tried this simple test: In DateTime::Set line 524: --- sub as_list { [...] print "done\n"; return @result; } --- $ perl -Ilib bug_recurrence.pl done Segmentation fault Flávio S. Glock 2009/7/16 http://www.openidfrance.fr/nils.grunwald via RT <bug-DateTime-Set@rt.cpan.org>: Show quoted text
> Thu Jul 16 12:06:06 2009: Request 47945 was acted upon. > Transaction: Ticket created by http://www.openidfrance.fr/nils.grunwald >       Queue: DateTime-Set >     Subject: segfault when using as_list on large enough sets >   Broken in: 0.27 >    Severity: Important >       Owner: Nobody >  Requestors: nils.grunwald@gmail.com >      Status: new >  Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=47945 > > > > Hello, > > here is a test case for this bug, which causes a segfault: > > use DateTime::Set; > use DateTime; > > my $span = DateTime::Span->from_datetimes( start => DateTime->new( year > => 1971 ), end => DateTime->new( year => 2009 ) ); > > my $set = DateTime::Set->from_recurrence( >    recurrence => sub { >        return $_[ 0 ] if $_[ 0 ]->is_infinite; >        return $_[ 0 ]->truncate( to => 'day' )->add( days => 1 ); >    }, > ); > > my @array = $set->as_list( span => $span ); > > > I have tested it on two machines with the same result, with perl 5.8.8 > and perl 5.10 under Linux. Memory comsumption is well under what is > available. If starting date is 1980 or more, everything runs fine. >
Subject: Re: [rt.cpan.org #47945] segfault when using as_list on large enough sets
Date: Sun, 19 Jul 2009 13:29:23 +0200
To: bug-DateTime-Set [...] rt.cpan.org
From: "Flavio S. Glock" <fglock [...] gmail.com>
This change seems to fix the segfault. It is now published to cpan as DateTime::Set 0.28. Flávio S. Glock --- lib/DateTime/Set.pm 2009-07-19 12:28:15.000000000 +0200 +++ ../perl-date-time/modules/DateTime-Set/trunk/lib/DateTime/Set.pm 2009-04-02 20:17:48.000000000 +0200 @@ -488,6 +488,7 @@ return $dt2; } + sub as_list { my $self = shift; return undef unless ref( $self->{set} ); @@ -510,22 +511,16 @@ $set->min->is_infinite; my @result; - my $next = $self->min; - if ( $span ) { - my $next1 = $span->min; - $next = $next1 if $next1 && $next1 > $next; - $next = $self->current( $next ); - } - my $last = $self->max; - if ( $span ) { - my $last1 = $span->max; - $last = $last1 if $last1 && $last1 < $last; - } - do { - push @result, $next if !$span || $span->contains($next); - $next = $self->next( $next ); - } - while $next && $next <= $last; + # we should extract _copies_ of the set elements, + # such that the user can't modify the set indirectly + + my $iter = $set->iterator; + while ( my $dt = $iter->next ) + { + push @result, $dt + if ref( $dt ); # we don't want to return INFINITY value + }; + return @result; }