Bug 60534
Summary: | perl sort function broken | ||
---|---|---|---|
Product: | [Retired] Red Hat Linux | Reporter: | Dax Kelson <dkelson> |
Component: | perl | Assignee: | Chip Turner <cturner> |
Status: | CLOSED RAWHIDE | QA Contact: | David Lawrence <dkl> |
Severity: | high | Docs Contact: | |
Priority: | medium | ||
Version: | 7.2 | ||
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | All | ||
OS: | Linux | ||
URL: | http://www.gurulabs.com/files/perl-testcase.txt | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2002-03-01 08:25:35 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
Dax Kelson
2002-03-01 07:57:33 UTC
I checked and it is broken on the perl shipped with RHL 7.1 too. You're seeing the result of a bugfix in perl 5.6.1. In earlier versions, the sort() function was not fully reentrant. This meant if your comparison function used sort, it could confuse perl, resulting in bad sorting, core dumps, or other various behavior. Unfortunately, Date::Manip's ParseDate ends up using sort for some kinds of input, thus triggering the bug you see. The two options are upgrade to Perl 5.6.1 (not yet available for Red Hat 7.2, though available in an unsupported version if you would like to test it) or to work around the problem. Below is a modified version of your script that works in 5.6.0 and 5.6.1. The key here is to do the ParseDate outside of your sorting function, thus avoiding the problem. The technique is called a Schwartzian Transform, and is a bit convoluted, but the idea is to basically pre-compute ParseDate for each element of the list to be sorted, then sort THAT list. #!/usr/bin/perl use Date::Manip; @list = ('dax-4th April 1975 14:10', 'kim-1st August 1975 22:20', 'bryan-8th January 1972 17:30', 'rick-28th May 1978 17:30', 'sarah-8th January 1972 12:30', 'heather-28th May 1978 17:30'); @sorted = map { $_->[0] } sort by_birthdate map { [ $_, ParseDate((split(/-/, $_, 2))[1]) ] } @list; print "Sorted:\n"; print "\t$_\n" foreach @sorted; sub by_birthdate { my($retval,$datea,$dateb,$str1,$str2,$flag); # this is the first hint of prob print "comparing $a->[0] WITH $b->[0]\n"; $flag=&Date_Cmp($a->[1],$b->[1]); if ($flag<0) { return(1); } elsif ($flag > 0) { return(-1); } else { return 0; } } |