]> granicus.if.org Git - php/commitdiff
Fix bug #77680: Correctly implement recursive mkdir on FTP stream
authorVlad Temian <vladtemian@gmail.com>
Tue, 19 Mar 2019 16:36:45 +0000 (18:36 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 25 Mar 2019 16:43:46 +0000 (17:43 +0100)
If the root directory was missing, an extra CWD without arguments was
made. Also, the MKD contained an empty string.

Now the CWD will use / and MKDs will be issued starting from the root
directory.

NEWS
ext/ftp/tests/server.inc
ext/standard/ftp_fopen_wrapper.c
ext/standard/tests/streams/bug77680.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 8165400d84dcb9286e871a5b439a3e3ca93f2615..52edd493e77905c2263c0f9d872e73e944f19560 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,7 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2019, PHP 7.2.18
 
-- interbase:
+- Interbase:
   . Fixed bug #72175 (Impossibility of creating multiple connections to
     Interbase with php 7.x). (Nikita)
 
@@ -12,6 +12,10 @@ PHP                                                                        NEWS
 - Reflection:
   . Fixed bug #77772 (ReflectionClass::getMethods(null) doesn't work). (Nikita)
 
+- Standard:
+  . Fixed bug #77680 (recursive mkdir on ftp stream wrapper is incorrect).
+    (Vlad Temian)
+
 04 Apr 2019, PHP 7.2.17
 
 - Core:
index 67531de995a1dc5d43462304275599a521931dd4..6e360c67e5a1cbb9a6c940c17232c0a5d00c188d 100644 (file)
@@ -289,8 +289,13 @@ if ($pid) {
             }
 
                }elseif (preg_match("~^CWD ([A-Za-z./]+)\r\n$~", $buf, $m)) {
-                       change_dir($m[1]);
-                       fputs($s, "250 CWD command successful.\r\n");
+                       if (isset($bug77680)) {
+                               fputs($s, "550 Directory change to $m[1] failed: file does not exist\r\n");
+                               var_dump($buf);
+                       } else {
+                               change_dir($m[1]);
+                               fputs($s, "250 CWD command successful.\r\n");
+                       }
 
                } elseif (preg_match("~^NLST(?: ([A-Za-z./]+))?\r\n$~", $buf, $m)) {
 
@@ -332,6 +337,9 @@ if ($pid) {
                        if (isset($bug7216)) {
                                fputs($s, "257 OK.\r\n");
                        } else {
+                               if (isset($bug77680)) {
+                                       var_dump($buf);
+                               }
                                fputs($s, "257 \"/path/to/ftproot$cwd$m[1]\" created.\r\n");
                        }
 
index 37b754a119f27677b967e023776938e8f2a25ce7..e23ffee17002ae909e5e01a0d6a01668c93d6bab 100644 (file)
@@ -1070,41 +1070,40 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in
 
         /* find a top level directory we need to create */
         while ((p = strrchr(buf, '/'))) {
-            *p = '\0';
-                       php_stream_printf(stream, "CWD %s\r\n", buf);
+                       *p = '\0';
+                       php_stream_printf(stream, "CWD %s\r\n", strlen(buf) ? buf : "/");
                        result = GET_FTP_RESULT(stream);
                        if (result >= 200 && result <= 299) {
                                *p = '/';
                                break;
                        }
-        }
-        if (p == buf) {
-                       php_stream_printf(stream, "MKD %s\r\n", resource->path);
-                       result = GET_FTP_RESULT(stream);
-        } else {
-                       php_stream_printf(stream, "MKD %s\r\n", buf);
-                       result = GET_FTP_RESULT(stream);
-                       if (result >= 200 && result <= 299) {
-                               if (!p) {
-                                       p = buf;
-                               }
-                               /* create any needed directories if the creation of the 1st directory worked */
-                               while (++p != e) {
-                                       if (*p == '\0' && *(p + 1) != '\0') {
-                                               *p = '/';
-                                               php_stream_printf(stream, "MKD %s\r\n", buf);
-                                               result = GET_FTP_RESULT(stream);
-                                               if (result < 200 || result > 299) {
-                                                       if (options & REPORT_ERRORS) {
-                                                               php_error_docref(NULL, E_WARNING, "%s", tmp_line);
-                                                       }
-                                                       break;
+               }
+
+               php_stream_printf(stream, "MKD %s\r\n", strlen(buf) ? buf : "/");
+               result = GET_FTP_RESULT(stream);
+
+               if (result >= 200 && result <= 299) {
+                       if (!p) {
+                               p = buf;
+                       }
+                       /* create any needed directories if the creation of the 1st directory worked */
+                       while (p != e) {
+                               if (*p == '\0' && *(p + 1) != '\0') {
+                                       *p = '/';
+                                       php_stream_printf(stream, "MKD %s\r\n", buf);
+                                       result = GET_FTP_RESULT(stream);
+                                       if (result < 200 || result > 299) {
+                                               if (options & REPORT_ERRORS) {
+                                                       php_error_docref(NULL, E_WARNING, "%s", tmp_line);
                                                }
+                                               break;
                                        }
                                }
+                               ++p;
                        }
                }
-        efree(buf);
+
+               efree(buf);
     }
 
        php_url_free(resource);
diff --git a/ext/standard/tests/streams/bug77680.phpt b/ext/standard/tests/streams/bug77680.phpt
new file mode 100644 (file)
index 0000000..8537bd4
--- /dev/null
@@ -0,0 +1,36 @@
+--TEST--
+Recursive mkdir() on ftp should create missing directories.
+--SKIPIF--
+<?php
+if (array_search('ftp',stream_get_wrappers()) === FALSE) die("skip ftp wrapper not available.");
+if (!function_exists('pcntl_fork')) die("skip pcntl_fork() not available.");
+?>
+--FILE--
+<?php
+$bug77680=1;
+
+require __DIR__ . "/../../../ftp/tests/server.inc";
+
+$path = "ftp://localhost:" . $port."/one/two/three/";
+mkdir($path, 0755, true);
+
+?>
+==DONE==
+--EXPECTF--
+string(20) "CWD /one/two/three
+"
+string(14) "CWD /one/two
+"
+string(10) "CWD /one
+"
+string(7) "CWD /
+"
+string(7) "MKD /
+"
+string(10) "MKD /one
+"
+string(14) "MKD /one/two
+"
+string(20) "MKD /one/two/three
+"
+==DONE==