Skip to content

Commit

Permalink
Fix stream_backend_file in the perl bindings
Browse files Browse the repository at this point in the history
stream_backend_file seems to be broken in 24-fixes and master in the following
ways:
1. When sending the FileTransfer command, it doesn't include all required
parameters causing the backend to respond with "malformed_filetransfer_command"
2. The length of the file to be streamed is not parsed correctly when >
2147483647, which results in corrupt or zero length files being written to
disk

This patch fixes these issues.  Patch applies cleanly to 24-fixes and master

The file length fix was tested against files of lengths 2012338647
(regression), 2500703244 (requires conversion to unsigned to be interpreted
correctly), and 31219659384 (test longlong)

Fixes #9837

Signed-off-by: Gavin Hurlbut <ghurlbut@mythtv.org>
  • Loading branch information
dbadia authored and Beirdo committed Jun 27, 2011
1 parent c80795e commit e3953dc
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions mythtv/bindings/perl/MythTV.pm
Expand Up @@ -23,6 +23,7 @@ package MythTV;
use DBI;
use HTTP::Request;
use LWP::UserAgent;
use Math::BigInt;

# Load the UPNP libraries if we have them, but die nicely if we don't.
BEGIN {
Expand Down Expand Up @@ -592,8 +593,8 @@ EOF
my $sock = $self->new_backend_socket($host,
$port,
join($MythTV::BACKEND_SEP,
'ANN FileTransfer '.hostname,
$basename));
'ANN FileTransfer '.hostname.
' 0 1 2000', $basename, '...'));
my @recs = split($MythTV::BACKEND_SEP_rx,
$sock->read_data());
# Error?
Expand All @@ -612,7 +613,8 @@ EOF
$csock->read_data();
}
# Transfer the data.
my $total = $recs[3];
# File size is longlong but is sent as 2 signed ints
my $total = $self->decodeLongLong($recs[2], $recs[3]);
while ($sock && $total > 0) {
# Attempt to read in 2M chunks, or the remaining total, whichever is
# smaller.
Expand Down Expand Up @@ -649,6 +651,27 @@ EOF
# Return
return 2;
}
# Analogous to decodeLongLong in decodeencode.cpp
sub decodeLongLong {
my $self = shift;
my $first = shift;
my $longlong = Math::BigInt->bzero();
if($first) { # 1st unsigned int is most significant
my $maxInt = Math::BigInt->new('4294967296');
my $shifted = $self->signedToUnsignedInt($first) * $maxInt;
$longlong += $shifted;
}
# add the 2nd unsigned int
$longlong += $self->signedToUnsignedInt(shift);
return $longlong;
}

sub signedToUnsignedInt {
my $self = shift;
$b = pack( "l", shift);
my @array = unpack( "L", $b );
return Math::BigInt->new(@array);
}

# Check the MythProto version between the backend and this script
sub check_proto_version {
Expand Down

0 comments on commit e3953dc

Please sign in to comment.