diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index e0561c74..54d76a1b 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -1050,6 +1050,12 @@ class SFTP extends SSH2 { $files = $this->_list($dir, false); + // If we get an int back, then that is an "unexpected" status. + // We do not have a file list, so return false. + if (is_int($files)) { + return false; + } + if (!$recursive || $files === false) { return $files; } @@ -1085,6 +1091,13 @@ class SFTP extends SSH2 function rawlist($dir = '.', $recursive = false) { $files = $this->_list($dir, true); + + // If we get an int back, then that is an "unexpected" status. + // We do not have a file list, so return false. + if (is_int($files)) { + return false; + } + if (!$recursive || $files === false) { return $files; } @@ -1152,8 +1165,12 @@ class SFTP extends SSH2 break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - $this->_logError($response); - return false; + if (strlen($response) < 4) { + return false; + } + extract(unpack('Nstatus', $this->_string_shift($response, 4))); + $this->_logError($response, $status); + return $status; default: user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS'); return false; @@ -1222,7 +1239,7 @@ class SFTP extends SSH2 extract(unpack('Nstatus', $this->_string_shift($response, 4))); if ($status != NET_SFTP_STATUS_EOF) { $this->_logError($response, $status); - return false; + return $status; } break 2; default: @@ -1898,7 +1915,7 @@ class SFTP extends SSH2 $i = 0; $entries = $this->_list($path, true); - if ($entries === false) { + if ($entries === false || is_int($entries)) { return $this->_setstat($path, $attr, false); } @@ -2743,9 +2760,14 @@ class SFTP extends SSH2 $i = 0; $entries = $this->_list($path, true); - // normally $entries would have at least . and .. but it might not if the directories - // permissions didn't allow reading - if (empty($entries)) { + // The folder does not exist at all, so we cannot delete it. + if ($entries === NET_SFTP_STATUS_NO_SUCH_FILE) { + return false; + } + + // Normally $entries would have at least . and .. but it might not if the directories + // permissions didn't allow reading. If this happens then default to an empty list of files. + if ($entries === false || is_int($entries)) { $entries = array(); } diff --git a/tests/Functional/Net/SFTPUserStoryTest.php b/tests/Functional/Net/SFTPUserStoryTest.php index 17497f67..fc11e7b1 100644 --- a/tests/Functional/Net/SFTPUserStoryTest.php +++ b/tests/Functional/Net/SFTPUserStoryTest.php @@ -623,6 +623,12 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase 'Failed asserting that stat on a deleted directory returns false' ); + $this->assertFalse( + $sftp->delete(self::$scratchDir), + 'Failed asserting that non-existent directory could not ' . + 'be deleted using recursive delete().' + ); + return $sftp; }