summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/tests/file/bug55124.phpt18
-rw-r--r--main/streams/plain_wrapper.c21
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 */