Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFTP::nlist returns integer entries for files names consisting of digits only #1623

Closed
Mellthas opened this issue Feb 28, 2021 · 5 comments
Closed

Comments

@Mellthas
Copy link

If I run $sftp->nlist() in a directory with a file (or directory) named 20210228, I get the following result from var_dump:

array(3) {
  [0]=>
  string(1) "."
  [1]=>
  string(2) ".."
  [2]=>
  int(20210228)
}

Shouldn't the file names always be string? The integer entries will result in warnings if I try something like this:

foreach ($sftp->nlist() as $path) {
  var_dump($sftp->is_dir($path));
}
PHP Warning: Trying to access array offset on value of type int in [...]/phpseclib/Net/SFTP.php on line 731

phpseclib version 2.0.30
Tested on PHP 7.4.15 and 8.0.2

@Mellthas Mellthas changed the title SFTP::nlist returns integer entries for files names consisting of digits only SFTP::nlist returns integer entries for files names consisting of digits only Feb 28, 2021
@Mellthas
Copy link
Author

After a quick glance into the code, this might be related to the entries being stored as array keys in the _list() method, and the fact that integer-like keys are being converted to int keys automatically by PHP.

@terrafrost
Copy link
Member

Interesting. https://stackoverflow.com/a/35180513/569976 suggests that there is kinda a workaround for it but an imperfect one.

I suppose the parameter to is_dir could be explicitly cast to a string but I feel that that's somewhat imperfect, as well. It might be the best solution, however, for 1.0 / 2.0 / 3.0.

As for fixing this going forward... #1418 would do the trick. It wouldn't be an array - it'd be an object that looked like an array. But that's a BC breaking change that wouldn't be included in 1.0 / 2.0 / 3.0.

@Mellthas
Copy link
Author

Mellthas commented Mar 3, 2021

Are you concerned about changing the return value of nlist wrt. to types, because someone might rely on the current behavior (getting int for certain file names)? If not, changing

return $raw ? $contents : array_keys($contents);
to

return $raw ? $contents : array_map('strval', array_keys($contents));

might do the trick, as far as I can see; so casting the list to strings explicitly before returning. In the other case, the behavior is not surprising at least in the case that you are aware of PHP implicitly casting array keys to int, as an array is returned.

@terrafrost
Copy link
Member

Are you concerned about changing the return value of nlist wrt. to types, because someone might rely on the current behavior (getting int for certain file names)?

No. getting int for certain file names is undocumented behavior. What I'm saying is a BC break is the idea of returning an ArrayObject instance instead of an array. Like if you're passing the output of nlist() into a method that, through the use of type hinting, is expecting an array... that'd be the bigger BC break of concern.

Anyway, your proposed solution seems reasonable. I'll try to implement it in the next few days!

@terrafrost
Copy link
Member

The proposed code change is now live!:

a45ccba

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants