Bug fix for SFTP::get()

This commit is contained in:
Ivailo Hristov 2016-02-17 14:57:32 +02:00
parent 11a539bcbd
commit 83b8d0ec0a

View File

@ -2063,21 +2063,18 @@ class SFTP extends SSH2
$fclose_check = $local_file !== false && !is_resource($local_file); $fclose_check = $local_file !== false && !is_resource($local_file);
$start = $offset; $start = $offset;
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
$read = 0; $read = 0;
$error = false; $break_loop = false;
while (!$error) { while (!$break_loop) {
$request_id_offset = 5;// just like that, a random number $request_id_offset = 5;// just like that, a random number
$i = $request_id_offset; $i = $request_id_offset;
// this puts a constraint on 32 bit systems where files larger than 4GB will not be completely downloaded if length is not specified. while ($i < NET_SFTP_QUEUE_SIZE+$request_id_offset && ($length < 0 || $read < $length)) {
$limit = $length > 0 ? max($this->max_sftp_packet, $length) : PHP_INT_MAX;
while ($i < NET_SFTP_QUEUE_SIZE+$request_id_offset && $read < $limit) {
$subtemp = $start + $read; $subtemp = $start + $read;
$possible_packet_sizes = array($this->max_sftp_packet, $size);
if ($limit - $read > 0) { $possible_packet_sizes = array($this->max_sftp_packet);
$possible_packet_sizes[] = $limit - $read; if ($length > 0 && $length - $read > 0) {
$possible_packet_sizes[] = $length - $read;
} }
$packet_size = min($possible_packet_sizes); $packet_size = min($possible_packet_sizes);
@ -2096,38 +2093,37 @@ class SFTP extends SSH2
$i++; $i++;
} }
while ($i > $request_id_offset) { if ($i > $request_id_offset) {
$this->request_id = $i; while ($i > $request_id_offset) {
$response = $this->_get_sftp_packet(); $this->request_id = $i;
$this->request_id=1; $response = $this->_get_sftp_packet();
switch ($this->packet_type) { $i--;
case NET_SFTP_DATA: $this->request_id=1;
$temp = substr($response, 4); switch ($this->packet_type) {
$offset+= strlen($temp); case NET_SFTP_DATA:
if ($local_file === false) { $temp = substr($response, 4);
$content.= $temp; $offset+= strlen($temp);
} else { if ($local_file === false) {
fputs($fp, $temp); $content.= $temp;
} } else {
break; fputs($fp, $temp);
case NET_SFTP_STATUS: }
// could, in theory, return false if !strlen($content) but we'll hold off for the time being break;
$this->_logError($response); case NET_SFTP_STATUS:
// don't break out of the loop so we can read the remaining responses // could, in theory, return false if !strlen($content) but we'll hold off for the time being
$error = true; $this->_logError($response);
break; // don't break out of the loop so we can read the remaining responses
default: $break_loop = true;
if ($fclose_check) { break;
fclose($fp); default:
} if ($fclose_check) {
throw new \UnexpectedValueException('Expected SSH_FXP_DATA or SSH_FXP_STATUS'); fclose($fp);
}
throw new \UnexpectedValueException('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
}
} }
} else {
if ($length > 0 && $length <= $offset - $start) { $break_loop = true;
// don't break out of the loop so we can read the remaining responses
$error = true;
}
$i--;
} }
} }