diff options
-rw-r--r-- | ext/standard/tests/file/bug55124.phpt | 18 | ||||
-rw-r--r-- | main/streams/plain_wrapper.c | 21 |
2 files changed, 25 insertions, 14 deletions
diff --git a/ext/standard/tests/file/bug55124.phpt b/ext/standard/tests/file/bug55124.phpt new file mode 100644 index 0000000000..892d4508d8 --- /dev/null +++ b/ext/standard/tests/file/bug55124.phpt @@ -0,0 +1,18 @@ +--TEST--
+Bug #55124 (recursive mkdir fails with current (dot) directory in path)
+--FILE--
+<?php
+$old_dir_path = getcwd();
+chdir(__DIR__);
+mkdir('a/./b', 0755, true);
+if (is_dir('a/b')) {
+ rmdir('a/b');
+}
+if (is_dir('/a')) {
+ rmdir('a');
+}
+chdir($old_dir_path);
+echo "OK";
+?>
+--EXPECT--
+OK
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 041a0e34e2..8303adb5b1 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -1147,24 +1147,18 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mod ret = php_mkdir(dir, mode TSRMLS_CC); } else { /* we look for directory separator from the end of string, thus hopefuly reducing our work load */ - char *e, *buf; + char *e; struct stat sb; int dir_len = strlen(dir); int offset = 0; + char buf[MAXPATHLEN]; - buf = estrndup(dir, dir_len); - -#ifdef PHP_WIN32 - e = buf; - while (*e) { - if (*e == '/') { - *e = DEFAULT_SLASH; - } - e++; + if (!expand_filepath_with_mode(dir, buf, NULL, 0, CWD_EXPAND TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path"); + return 0; } -#else - e = buf + dir_len; -#endif + + e = buf + strlen(buf); if ((p = memchr(buf, DEFAULT_SLASH, dir_len))) { offset = p - buf + 1; @@ -1216,7 +1210,6 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mod } } } - efree(buf); } if (ret < 0) { /* Failure */ |