|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-07-20 03:53 UTC] anrdaemon at freemail dot ru
Description:
------------
When given a long string (> 260 characters), realpath() and SplFileInfo::getRealPath() both fail to convert path to something sensible and return empty result.
However, using dirname() to shorten the input string will result in the function working again.
Additionally, PHP reporting "invalid path", if you try to use extended access syntax ('\\?\<path>').
(Oh, and before you say something silly, the sting in example is an equivalent of a real path generated by Composer.)
Test script:
---------------
<?php
$fn = "{$_SERVER['TEMP']}/_test/documents/projects/myproject/vendor/name/library/classpath";
$fn1 = "$fn/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library/classpath";
mkdir($fn, 0777, true);
error_log(strlen($fn));
error_log(realpath($fn));
error_log(strlen($fn1));
error_log($fn1);
error_log(realpath($fn1));
error_log(strlen(dirname($fn1)));
error_log(dirname($fn1));
error_log(realpath(dirname($fn1)));
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 04:00:01 2025 UTC |
Didn't change. If not made worse. Refined script: <?php $fn = "{$_SERVER['TEMP']}/_test/documents/projects/myproject/vendor/name/library/classpath"; $fn1 = "$fn/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library/classpath"; mkdir($fn, 0777, true); error_log(sprintf("(%u)%s", strlen($fn), $fn)); error_log("=>" . realpath($fn)); error_log(sprintf("(%u)%s", strlen($fn1), $fn1)); error_log("=>" . realpath($fn1)); error_log(sprintf("(%u)%s", strlen(dirname($fn1)), dirname($fn1))); error_log("=>" . realpath(dirname($fn1))); PHP 5.6.23/64 (101)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath =>C:\Users\anrdaemon\AppData\Local\Temp\_test\documents\projects\myproject\vendor\name\library\classpath (266)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library/classpath => (256)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library =>C:\Users\anrdaemon\AppData\Local\Temp\_test\documents\projects\myproject\vendor\name\library PHP 7.0.8/64 (101)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath =>C:\Users\anrdaemon\AppData\Local\Temp\_test\documents\projects\myproject\vendor\name\library\classpath (266)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library/classpath => (256)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library =>C:\Users\anrdaemon\AppData\Local\Temp\_test\documents\projects\myproject\vendor\name\library PHP 7.1.0b1/64 (101)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath =>C:\Users\anrdaemon\AppData\Local\Temp\_test\documents\projects\myproject\vendor\name\library\classpath (266)C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library/classpath => (260)\\?\C:\Users\ANRDAE~1\AppData\Local\Temp/_test/documents/projects/myproject/vendor/name/library/classpath/../../../../../../../../_test/documents/projects/myproject/vendor/name/library/../../../../../../../_test/documents/projects/myproject/vendor/name/library =>The issue is FindFirstFileW(), which isn't as liberal with regard to the \\?\ prefix as without it. POC: #include <windows.h> int main() { HANDLE h; WIN32_FIND_DATA fd; h = FindFirstFileW(L"C:\\Windows", &fd); printf("%i\n", h != INVALID_HANDLE_VALUE); h = FindFirstFileW(L"C:/Windows", &fd); printf("%i\n", h != INVALID_HANDLE_VALUE); h = FindFirstFileW(L"\\\\?\\C:\\Windows", &fd); printf("%i\n", h != INVALID_HANDLE_VALUE); h = FindFirstFileW(L"\\\\?\\C:/Windows", &fd); printf("%i\n", h != INVALID_HANDLE_VALUE); return 0; } outputs: 1 1 1 0 Neither slashes (nor dots nor double-dots) are converted, as noted on MSDN in the section about "Maximum Path Length Limitation"[1]. It occurs to me that this conversion would have to be done by PHP in the first place. Anatol, what do you think? [1] <https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath>