[PATCH] Ensure safe 32-bit date if timegm() fails
dinkypumpkin
dinkypumpkin at gmail.com
Thu Apr 7 16:43:52 EDT 2011
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
More information about the get_iplayer
mailing list