]> granicus.if.org Git - php/commitdiff
Fix #78641: addGlob can modify given remove_path value
authorChristoph M. Becker <cmbecker69@gmx.de>
Tue, 8 Oct 2019 07:25:56 +0000 (09:25 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Tue, 8 Oct 2019 07:45:05 +0000 (09:45 +0200)
`remove_path` points to the given string, so we must not modify it.
Instead we use a duplicate, if we need the modification.

We may want to switch to `zend_string`s in master.

NEWS
ext/zip/php_zip.c
ext/zip/tests/bug78641.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 62b6d7342f40be523cb9ea444493abdbee0e1139..4003ef78934f878647d165f8fc6276a8651f5f9c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,9 @@ PHP                                                                        NEWS
   . Fixed bug #76859 (stream_get_line skips data if used with data-generating 
     filter). (kkopachev)
 
+- Zip:
+  . Fixed bug #78641 (addGlob can modify given remove_path value). (cmb)
+
 26 Sep 2019, PHP 7.2.23
 
 - Core:
index 7f7880dd6c8949d6f1058bcc2be8e8c4189ebe87..6b29266d9b21185842deebc851d6b9e10acb05f9 100644 (file)
@@ -1667,7 +1667,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
        struct zip *intern;
        zval *self = getThis();
        char *path = ".";
-       char *remove_path = NULL;
+       char *remove_path = NULL, *save_remove_path;
        char *add_path = NULL;
        size_t  add_path_len, remove_path_len = 0, path_len = 1;
        zend_long remove_all_path = 0;
@@ -1703,10 +1703,11 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
                RETURN_FALSE;
        }
 
+       save_remove_path = remove_path;
        if (remove_path && remove_path_len > 1) {
                size_t real_len = strlen(remove_path);
                if ((real_len > 1) && ((remove_path[real_len - 1] == '/') || (remove_path[real_len - 1] == '\\'))) {
-                       remove_path[real_len - 1] = '\0';
+                       remove_path = estrndup(remove_path, real_len - 1);
                }
        }
 
@@ -1766,6 +1767,9 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
                        }
                }
        }
+       if (remove_path != save_remove_path) {
+               efree(remove_path);
+       }
 }
 /* }}} */
 
diff --git a/ext/zip/tests/bug78641.phpt b/ext/zip/tests/bug78641.phpt
new file mode 100644 (file)
index 0000000..3198c6c
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bug #78641 (addGlob can modify given remove_path value)
+--SKIPIF--
+<?php
+if (!extension_loaded('zip')) die('skip zip extension not available');
+?>
+--FILE--
+<?php
+define("TMPDIR", __DIR__ . "/");
+
+$file = TMPDIR . 'bug78641';
+touch($file);
+
+$zip = new ZipArchive();
+$zip->open(TMPDIR . "bug78641.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);
+var_dump(basename(TMPDIR));
+$zip->addGlob($file, 0, ["remove_path" => TMPDIR]);
+var_dump(basename(TMPDIR));
+$zip->close();
+?>
+--EXPECT--
+string(5) "tests"
+string(5) "tests"
+--CLEAN--
+<?php
+unlink(__DIR__ . '/bug78641');
+unlink(__DIR__ . '/bug78641.zip');
+?>