diff --git a/ext/standard/string.c b/ext/standard/string.c index 47b4f60f0fe..b47319be310 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1429,7 +1429,7 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen goto quit_loop; case 1: #if defined(PHP_WIN32) || defined(NETWARE) - if (*c == '/' || *c == '\\' || (*c == ':' && (c - s == 1))) { + if (*c == '/' || *c == '\\') { #else if (*c == '/') { #endif @@ -1437,6 +1437,19 @@ PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen state = 0; cend = c; } +#if defined(PHP_WIN32) || defined(NETWARE) + /* Catch relative paths in c:file.txt style. They're not to confuse + with the NTFS streams. This part ensures also, that no drive + letter traversing happens. */ + } else if ((*c == ':' && (c - comp == 1))) { + if (state == 0) { + comp = c; + state = 1; + } else { + cend = c; + state = 0; + } +#endif } else { if (state == 0) { comp = c; diff --git a/ext/standard/tests/file/basename_bug66395_variation2-win32.phpt b/ext/standard/tests/file/basename_bug66395_variation2-win32.phpt new file mode 100644 index 00000000000..05df79b02a0 --- /dev/null +++ b/ext/standard/tests/file/basename_bug66395_variation2-win32.phpt @@ -0,0 +1,36 @@ +--TEST-- +basename bug #66395 check drive traversing and NTFS streams +--SKIPIF-- + +--FILE-- + +==DONE== +--EXPECTF-- +y +y +notdriveletter:file.txt +hcd:c.txt +some.txt +f.txt +g.txt +g.txt +world:somestream +world:some.stream +world:some.stream:$DATA +world:my.stream:$DATA +world:c:$DATA +==DONE==