This patch originated from the thread that begins here:

http://lists.infradead.org/pipermail/get_iplayer/2011-March/001078.html

While hacking on get_iplayer to download embedded media clips from a couple 
of other BBC web sites, I discovered a problem (explained in the commit 
message below) with the logic used to compute expiry dates for downloaded
programmes.  A few media clips had expiry dates too large for get_iplayer
to handle, so it would bomb.  This is an esoteric issue that will likely
never affect normal iPlayer programmes, which of course expire fairly 
quickly.  Still, I couldn't let a bug remain unfixed if I could help it.
I also hope to work in general support for downloading from embedded clip
URLs, and this patch would be necessary for that.

Updated get_iplayer script here:

https://github.com/dinkypumpkin/get_iplayer/raw/patched/get_iplayer

Commit history here:

https://github.com/dinkypumpkin/get_iplayer/commits/patched/

Patch follows -

get_iplayer uses timegm() to calculate expiry dates for
downloaded programmes.  In 32-bit versions of perl or any
perl < 5.10.1, timegm() croaks for any date greater than
2038-01-16 23:59:59.  The current approach of setting
year = 2038 for any dates in 2038 and after is insufficient
to ensure a safe 32-bit date.  This patch changes the code
to run timegm() within an eval block.  If timegm() croaks,
epoch date is set to arbitrary safe value (2038-01-01 00:00:00).
Redundant calls to to timegm() have also been removed.

The problem corrected by this patch is very much an edge case,
so far only observed when using a hacked get_iplayer to download
media clips embedded in other BBC web sites.  However, the logic
is still incorrect, so this patch has been created to fix it.
---
 get_iplayer |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/get_iplayer b/get_iplayer
index 81d6dea..3d68865 100755
--- a/get_iplayer
+++ b/get_iplayer
@@ -4839,15 +4839,15 @@ sub get_time_string {
        main::logger "DEBUG: $_ = $year, $mon, $mday, $hour, $min, $sec, 
$tzhour, $tzmin\n" if $opt->{debug};
        # Sanity check date data
        return '' if $year < 1970 || $mon < 1 || $mon > 12 || $mday < 1 || 
$mday > 31 || $hour < 0 || $hour > 24 || $min < 0 || $min > 59 || $sec < 0 || 
$sec > 59 || $tzhour < -13 || $tzhour > 13 || $tzmin < -59 || $tzmin > 59;
-       # Year cannot be > 2032 so limit accordingly :-/
-       $year = 2038 if $year > 2038;
        # Calculate the seconds difference between epoch_now and 
epoch_datestring and convert back into array_time
-       my $epoch = timegm($sec, $min, $hour, $mday, ($mon-1), ($year-1900), 
undef, undef, 0) - $tzhour*60*60 - $tzmin*60;
+       my $epoch = eval { timegm($sec, $min, $hour, $mday, ($mon-1), 
($year-1900), undef, undef, 0) - $tzhour*60*60 - $tzmin*60; };
+       # ensure safe 32-bit date if timegm croaks
+       if ( $@ ) { $epoch = timegm(0, 0, 0, 1, 0, 138, undef, undef, 0) - 
$tzhour*60*60 - $tzmin*60; };
        my $rtn;
        if ( $diff ) {
                # Return time ago
                if ( $epoch < $diff ) {
-                       my @time = gmtime( $diff - ( timegm($sec, $min, $hour, 
$mday, ($mon-1), ($year-1900), undef, undef, 0) - $tzhour*60*60 - $tzmin*60 ) );
+                       my @time = gmtime( $diff - $epoch );
                        # The time() func gives secs since 1970, gmtime is 
since 1900
                        my $years = $time[5] - 70;
                        $rtn = "$years years " if $years;
@@ -4855,7 +4855,7 @@ sub get_time_string {
                        return $rtn;
                # Return time to go
                } elsif ( $epoch > $diff ) {
-                       my @time = gmtime( ( timegm($sec, $min, $hour, $mday, 
($mon-1), ($year-1900), undef, undef, 0) - $tzhour*60*60 - $tzmin*60 ) - $diff 
);
+                       my @time = gmtime( $epoch - $diff );
                        my $years = $time[5] - 70;
                        $rtn = 'in ';
                        $rtn .= "$years years " if $years;
@@ -4868,7 +4868,7 @@ sub get_time_string {
        # Return time in epoch
        } else {
                # Calculate the seconds difference between epoch_now and 
epoch_datestring and convert back into array_time
-               return timegm($sec, $min, $hour, $mday, ($mon-1), ($year-1900), 
undef, undef, 0) - $tzhour*60*60 - $tzmin*60;
+               return $epoch;
        }
 }
 
-- 
1.7.4.3


_______________________________________________
get_iplayer mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/get_iplayer

Reply via email to