PHP 7 SSH2.SFTP stat() bug work around - php-7

I have an app the uses an SFTP connection to download files. It was working correctly in PHP 5.6, not so much in PHP 7. The error I get is as follows:
PHP Warning: filesize(): stat failed for ssh2.sftp ...
My code is as follows:
public function retrieveFiles($downloadTargetFolder,$remoteFolder = '.') {
$fileCount = 0;
echo "\nSftpFetcher retrieveFiles\n";
$con = ssh2_connect($this->host,$this->port) or die("Couldn't connect\n");
if($this->pubKeyFile){
$isAuth = ssh2_auth_pubkey_file($con, $this->user, $this->pubKeyFile, $this->privKeyFile);
} else {
$isAuth = ssh2_auth_password($con, $this->user, $this->pass);
};
if ($isAuth) {
$sftp = ssh2_sftp($con);
$rd = "ssh2.sftp://{$sftp}{$remoteFolder}";
if (!$dir = opendir($rd)) {
echo "\nCould not open the remote directory\n";
} else {
$files = array();
while (false != ($file = readdir($dir))) {
if ($file == "." || $file == "..")
continue;
$files[] = $file;
}
if (is_array($files)) {
foreach ($files as $remoteFile) {
echo "\ncheck file: $remoteFile vs filter: " . $this->filter."\n";
if ($this->filter !== null && strpos($remoteFile,$this->filter) === false) {
continue;
}
echo "file matched\n";
$localFile = $downloadTargetFolder . DIRECTORY_SEPARATOR . basename($remoteFile);
//$result = ftp_get($con,$localFile,$remoteFile,FTP_BINARY);
$result = true;
// Remote stream
if (!$remoteStream = #fopen($rd."/".$remoteFile, 'r')) {
echo "Unable to open the remote file $remoteFolder/$remoteFile\n";
$return = false;
} else {
// Local stream
if (!$localStream = #fopen($localFile, 'w')) {
echo "Unable to open the local file $localFile\n";
$return = false;
} else {
// Write from our remote stream to our local stream
$read = 0;
$fileSize = filesize($rd."/".$remoteFile);
while ($read < $fileSize && ($buffer = fread($remoteStream, $fileSize - $read))) {
$read += strlen($buffer);
if (fwrite($localStream, $buffer) === FALSE) {
echo "Unable to write the local file $localFile\n";
$return = false;
break;
}
}
echo "File retrieved";
// Close
fclose($localStream);
fclose($remoteStream);
}
}
if ($result) {
$fileCount++;
}
}
}
ssh2_exec($con, 'exit');
unset($con);
}
} else {
echo "Error authenticating the user ".$this->user."\n";
}
return $fileCount;
}
}
After some research I found there was an issue with stat():
http://dougal.gunters.org/blog/2016/01/18/wordpress-php7-and-updates-via-php-ssh2/
https://bugs.php.net/bug.php?id=71376
My question
Is there a workaround to allow me to download via SFTP given my current code or is there another library someone can recommend to use instead?
My PHP version:
PHP 7.0.8-0ubuntu0.16.04.3 (cli) ( NTS )

Quoting PHP ssh2.sftp opendir/readdir fix,
Instead of using "ssh2.sftp://$sftp" as a stream path, convert $sftp to an integer like so: "ssh2.sftp://" . intval($sftp) . "/". Then it will work just fine.
The reason for the change is as follows:
PHP 5.6.28 (and apparently 7.0.13) introduced a security fix to URL parsing, that caused the string interpolation of the $sftp resource handle to no-longer be recognized as a valid URL. In turn, that causes opendir(), readdir(), etc. to fail when you use an $sftp resource in the path string, after an upgrade to one of those PHP versions.
As for other libraries... only other library I'm aware of is phpseclib, which has an emulator of sorts for libssh2:
https://github.com/phpseclib/libssh2-compatibility-layer
That "emulator" could certainly be improved upon tho. Like a composer.json file ought to be added, etc.

I had the same issue with php 8.0.
Try putting the filesize command before the fopens.

Related

what does mean for this error "Notice: Array to string conversion in line 96"

this is the example of signup page. the error is"Notice: Array to string conversion in
C:\xampp\htdocs\sample\signup.php on line 96" what are the possible solutions.
here is the code........
<?php
$con = mysqli_connect('localhost','root') or die(mysqli_error());
mysqli_select_db($con,'kms') or die (mysqli_error());
if (isset($_POST['techno']) && isset($_FILES['profile_picture']))
{
$firstname = $_POST['firstname'];
$middlename = $_POST['middlename'];
$lastname = $_POST['lastname'];
$email = $_POST['email'];
$password = $_POST['password'];
$psw_repeat = $_POST['psw_repeat'];
$dob = $_POST['dob'];
$gender = $_POST['gender'];
$occupation = $_POST['occupation'];
$address = $_POST['address'];
$about = $_POST['about'];
$phonenumber = $_POST['phonenumber'];
$profile_picture = $_FILES['profile_picture'];
$q = "INSERT INTO user (firstname,middlename,lastname,email,password,dob,gender,occupation,address,about,phonenumber,profile_picture) values ('$firstname','$middlename','$lastname','$email','$password',$dob,'$gender','$occupation','$address','$about',$phonenumber,'$profile_picture')";
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["profile_picture"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["profile_picture"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "File is not an image.";
$uploadOk = 0;
}
}
// Check if file already exists
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
if ($_FILES["profile_picture"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["profile_picture"]["tmp_name"], $target_file)) {
echo "The file ". basename( $_FILES["profile_picture"]["name"]). " has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
if($psw_repeat != $password)
{
echo("Password does not match");
}
mysqli_query($con,$q) or die(mysqli_error($con));
mysqli_close($con);
}
?>
in line number 96...the code is for inserting data into database...
i have googled this error....ut there is no solution

timthumb not working after site migration

I just move my site from xfactorapp.com and any new uploaded picture has no thumbnail. Image is on server but thumbnail is not generated.
How can i change that code to make thumbnail visible from new server?
function href_t`imthumb($file, $set = null, $xf = true) {
if (!$set || !$xf) {
$timthumb = webpath_assets('/timthumb.php');
$href = $timthumb . '?src=' . $file;
if (xcount($set) > 0) {
foreach ($set as $k => $v) {
$href .= '&' . $k . '=' . $v;
}
}
return $href;
} else {
$param['w'] = 150;
$param['h'] = 150;
$param['zc'] = 0;
$param['q'] = 90;
if (DEV) {
$app = DEV_PREFIX . APP_VERSION;
} else {
$app = LIVE_PREFIX . APP_VERSION;
}
if (xcount($set) > 0) {
foreach ($set as $k => $v) {
$param[$k] = $v;
}
$file = '/' . $app . $file;
$protocol = 'http';
if (isSSL()) {
$protocol = 'https';
}
return $protocol . '://thumb.xfactorapp.com/tt/' . implode('/', $param) . $file;
}
}
}
wich give me:
<img class="img-responsive" alt="building" src="http://thumb.xfactorapp.com/tt/263/147/2/90/v3/uploads/_lifttec/cms/58529051881f8f0d87ab1401/5947fffeac28b_200-ATJ-Platforma-autoridicatoare-articulata.jpg">
i wish to change code to take thumbnail with parnam properties but from upload not from thumb.xfactorapp.com
Thanks
Just change $xf from true to false $xf = false.
If you changed server, May be GD Library is missing,So Install and Restart Apache then check your file permission.
// To install GD Library
sudo apt-get install php5.6-gd
// To Restart Apache2
sudo /etc/init.d/apache2 restart

PayPal PDT SSL connection hangs up on my addon domain

On my PayPal autoReturn page with a known-to-work PHP script to accommodate Payment Data Transfer, no matter what I do I keep getting this error message: "Warning: fgets(): SSL: Connection reset by peer...*(on the line where this is: '$line = fgets($fp, 1024);'* "
Before I ask my question, let me just say that I've tried everything suggested here and in any other forum or article that I've been advised to read, e.g. changing HTTP 1.0 to HTTP 1.1, using $res=stream_get_contents($fp, 1024) instead of the while loop with $line = fgets($fp, 1024), etc., etc. My problem persists.
Here's what I think might be the problem (and I'm hoping someone can tell me if I'm on the right track): My auto return page for PDT is on an add-on site and I'm thinking that PayPal hangs up when the shared SSL (for my primary domain on a shared server) isn't recognized. So I've asked my web host for SSL to be installed specifically for my add-on domain.
Could the add-on domain SSL thing be the reason for my warning message? Again, that message is: "Warning: fgets(): SSL: Connection reset by peer...*(on the line where this is: '$line = fgets($fp, 1024);'* "
Here's my code:
//look if the parameter 'tx' is set in the GET request and that it does not have a null or empty value
if(isset($_GET['tx']) && ($_GET['tx'])!=null && ($_GET['tx'])!= "") {
$tx = $_GET['tx'];
verifyWithPayPal($tx);
}
else {
exitCode();
}
function verifyWithPayPal($tx) {
$req = 'cmd=_notify-synch';
$tx_token = $tx;
$auth_token = "MY SANDBOX AUTH_TOKEN HERE";
$req .= "&tx=$tx_token&at=$auth_token";
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
// url for paypal sandbox
//$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
// url for payal
// $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
// If possible, securely post back to paypal using HTTPS
// Your PHP server will need to be SSL enabled.
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if (!$fp) {
exitCode();
} else {
fputs($fp, $header . $req);
// read the body data
$res = '';
$headerdone = false;
while (!feof($fp)) {
$line = fgets($fp, 1024);
// $res=stream_get_contents($fp, 1024);
if (strcmp($line, "\r\n") == 0) {
// read the header
$headerdone = true;
}
else if ($headerdone) {
// header has been read. now read the contents
$res .= $line;
}
}
// parse the data
$lines = explode("\n", $res);
$response = array();
if (strcmp ($lines[0], "SUCCESS") == 0) {
for ($i=1; $i<count($lines);$i++){
list($key,$val) = explode("=", $lines[$i]);
$response[urldecode($key)] = urldecode($val);
}
$itemName = $response["item_name"];
$amount = $response["payment_gross"];
$myEmail = $response["receiver_email"];
$userEmailPaypalId = $response["payer_email"];
$paymentStatus = $response["payment_status"];
$paypalTxId = $response["txn_id"];
$currency = $response["mc_currency"];
// check the payment_status is Completed
if($paymentStatus!="Completed") {
payment_complete();
emailer($userEmailPayPalID);
} else {
payment_incomplete($paymentStatus);
}
/*
// check that txn_id has not been previously processed
checkIfTransactionHasAlreadyBeenProcessed($paypalTxId);
// check that receiver_email is your Primary PayPal email
checkThatPaymentIsReceivedAtYourEmailAddress($myEmail);
// check that payment_amount/payment_currency are correct
checkPaymentAmountAndCurrency($amount, $currency);
// process the order
processOrder();
} else {
exitCode();
*/
}
}
fclose ($fp);
}
I notice you're connecting to www.sandbox.paypal.com. I believe you want to connect to api.sandbox.paypal.com.

Apache Cordova File API via Windows Phone

I have tried to use Apache Cordova File Plugin documentation
Here is my code. It just basically goes through all folders into file system.
function log(text) {
var element = document.createElement('div');
element.innerHTML = text;
document.getElementById("log").appendChild(element);
}
function onSuccess(fileSystem) {
function printEntries(entries) {
log("Enter printEntries function");
var i;
log("Number of entries" + entries.length);
for (i = 0; i < entries.length; i++) {
log("Interation number " + i);
if (entries[i].isFile) {
log(entries[i].name);
} else {
log("Moving into subdirectory name: " + entries[i].name);
entries[i].createReader().readEntries(printEntries, fail);
}
}
}
function fail(error) {
log("Failed to list directory contents: " + error.code);
}
// Get a directory reader
var directoryReader = fileSystem.root.createReader();
// Get a list of all the entries in the directory
directoryReader.readEntries(printEntries, fail);
}
// request the persistent file system
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, null);
When I deploy my application to the my Lumia I have only this directories:
/
-Shared
---Media
---ShellContent
---Transfers
-debugOutput.txt
-DeviceID.txt
It seams that I have no access to files, that stored on my phone (images, videos).
So, my question is: Is it possible to get files from phone file system and sd card?

header function is not working on online server

I have been having problem with header(); This script was generated by dreamweaver login. why will it work on some hosting company and do not work on the company i m hosting?
I have notice that header() do not work on my hosting company at all on all my pages. why do i have this problem?
if (PHP_VERSION >= 5.2) {
session_regenerate_id(true);
} else {
session_regenerate_id();
}
//declare two session variables and assign them
$_SESSION['MM_Username'] = $loginUsername;
$_SESSION['MM_UserGroup'] = $loginStrGroup;
if (isset($_SESSION['PrevUrl']) && false) {
$MM_redirectLoginSuccess = $_SESSION['PrevUrl'];
}
header("Location: " . $MM_redirectLoginSuccess ); }
else {
header("Location: ". $MM_redirectLoginFailed );
}
}
It looks like there is a problem with the brackets around the header() calls:
if (PHP_VERSION >= 5.2) {
session_regenerate_id(true);
} else {
session_regenerate_id();
}
//declare two session variables and assign them
$_SESSION['MM_Username'] = $loginUsername;
$_SESSION['MM_UserGroup'] = $loginStrGroup;
// changes made below <------
if (isset($_SESSION['PrevUrl']) && false) { <--- && false needs fixing
$MM_redirectLoginSuccess = $_SESSION['PrevUrl'];
header("Location: " . $MM_redirectLoginSuccess );
} else {
header("Location: " . $MM_redirectLoginFailed );
}
Edit - the && false in the if statement will also always fail, this needs to be resolved.
add that code below after <body>
ob_start();
add that code below before </body>
ob_end_flush();
and voola problem solved. ^_^