stream_backend_file seems to be broken in 24-fixes and head in the following
From: Dave Badia <dbadia@gmail.com>
ways:
1. When sending the FileTransfer command, it doesn't include all requied
parameters causing the backend to responsd with
"malformed_filetransfer_command"
change as opposed to a bug)
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 head
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)
---
mythtv/bindings/perl/MythTV.pm | 29 ++++++++++++++++++++++++++---
1 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/mythtv/bindings/perl/MythTV.pm b/mythtv/bindings/perl/MythTV.pm
index f1ae4fa..9406702 100644
a
|
b
|
package MythTV; |
23 | 23 | use DBI; |
24 | 24 | use HTTP::Request; |
25 | 25 | use LWP::UserAgent; |
| 26 | use Math::BigInt; |
26 | 27 | |
27 | 28 | # Load the UPNP libraries if we have them, but die nicely if we don't. |
28 | 29 | BEGIN { |
… |
… |
EOF |
592 | 593 | my $sock = $self->new_backend_socket($host, |
593 | 594 | $port, |
594 | 595 | join($MythTV::BACKEND_SEP, |
595 | | 'ANN FileTransfer '.hostname, |
596 | | $basename)); |
| 596 | 'ANN FileTransfer '.hostname. |
| 597 | ' 0 1 2000', $basename, '...')); |
597 | 598 | my @recs = split($MythTV::BACKEND_SEP_rx, |
598 | 599 | $sock->read_data()); |
599 | 600 | # Error? |
… |
… |
EOF |
612 | 613 | $csock->read_data(); |
613 | 614 | } |
614 | 615 | # Transfer the data. |
615 | | my $total = $recs[3]; |
| 616 | # File size is longlong but is sent as 2 signed ints |
| 617 | my $total = $self->decodeLongLong($recs[2], $recs[3]); |
616 | 618 | while ($sock && $total > 0) { |
617 | 619 | # Attempt to read in 2M chunks, or the remaining total, whichever is |
618 | 620 | # smaller. |
… |
… |
EOF |
649 | 651 | # Return |
650 | 652 | return 2; |
651 | 653 | } |
| 654 | # Analogous to decodeLongLong in decodeencode.cpp |
| 655 | sub decodeLongLong { |
| 656 | my $self = shift; |
| 657 | my $first = shift; |
| 658 | my $longlong = Math::BigInt->bzero(); |
| 659 | if($first) { # 1st unsigned int is most significant |
| 660 | my $maxInt = Math::BigInt->new('4294967296'); |
| 661 | my $shifted = $self->signedToUnsignedInt($first) * $maxInt; |
| 662 | $longlong += $shifted; |
| 663 | } |
| 664 | # add the 2nd unsigned int |
| 665 | $longlong += $self->signedToUnsignedInt(shift); |
| 666 | return $longlong; |
| 667 | } |
| 668 | |
| 669 | sub signedToUnsignedInt { |
| 670 | my $self = shift; |
| 671 | $b = pack( "l", shift); |
| 672 | my @array = unpack( "L", $b ); |
| 673 | return Math::BigInt->new(@array); |
| 674 | } |
652 | 675 | |
653 | 676 | # Check the MythProto version between the backend and this script |
654 | 677 | sub check_proto_version { |