]> granicus.if.org Git - php/commitdiff
fix Phar::mount() to also allow running externally with full phar:// path, add test
authorGreg Beaver <cellog@php.net>
Mon, 21 Apr 2008 18:21:54 +0000 (18:21 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 21 Apr 2008 18:21:54 +0000 (18:21 +0000)
ext/phar/phar_object.c
ext/phar/tests/phar_mount.phpt [new file with mode: 0644]

index fdfac0eb3c4735a42a70491ef87a9566f329e18d..4fd99e2345980a47f9196d4d3ae8279ef0e6afaa 100755 (executable)
@@ -486,8 +486,15 @@ PHP_METHOD(Phar, mount)
        fname = zend_get_executed_filename(TSRMLS_C);
        fname_len = strlen(fname);
 
-       if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
+       if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                efree(entry);
+               entry = NULL;
+               if (path_len > 7 && !memcmp(path, "phar://", 7)) {
+                       zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Can only mount internal paths within a phar archive, use a relative path instead of \"%s\"", path);
+                       efree(arch);
+                       return;
+               }
+carry_on2:
                if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s is not a phar archive, cannot mount", arch);
                        efree(arch);
@@ -495,14 +502,23 @@ PHP_METHOD(Phar, mount)
                }
 carry_on:
                if (SUCCESS != phar_mount_entry(*pphar, actual, actual_len, path, path_len TSRMLS_CC)) {
+                       if (path && path == entry) {
+                               efree(entry);
+                       }
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Mounting of %s to %s within phar %s failed", path, actual, arch);
                }
+               if (path && path == entry) {
+                       efree(entry);
+               }
                efree(arch);
                return;
        } else if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **)&pphar)) {
                goto carry_on;
+       } else if (SUCCESS == phar_split_fname(path, path_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
+               path = entry;
+               path_len = entry_len;
+               goto carry_on2;
        }
-       zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Phar::mount() can only be run from within a phar archive");
 }
 /* }}} */
 
diff --git a/ext/phar/tests/phar_mount.phpt b/ext/phar/tests/phar_mount.phpt
new file mode 100644 (file)
index 0000000..90386ff
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+Phar: Phar::mount
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/tempmanifest1.phar.php';
+$pname = 'phar://' . $fname;
+
+$a = new Phar($fname);
+$a['index.php'] = '<?php
+Phar::mount("testit", "' . addslashes(__FILE__) . '");
+try {
+Phar::mount("testit", "' . addslashes(__FILE__) . '");
+} catch (Exception $e) {
+echo $e->getMessage() . "\n";
+}
+try {
+Phar::mount("' . addslashes($pname) . '/testit1", "' . addslashes(__FILE__) . '");
+} catch (Exception $e) {
+echo $e->getMessage() . "\n";
+}
+?>';
+$a->setStub('<?php
+set_include_path("phar://" . __FILE__);
+include "index.php";
+__HALT_COMPILER();');
+Phar::mount($pname . '/testit1', __FILE__);
+include $fname;
+?>
+===DONE===
+--CLEAN--
+<?php
+@unlink(dirname(__FILE__) . '/tempmanifest1.phar.php');
+?>
+--EXPECTF--
+Mounting of testit to %sphar_mount.php within phar %stempmanifest1.phar.php failed
+Can only mount internal paths within a phar archive, use a relative path instead of "phar://%stempmanifest1.phar.php/testit1"
+===DONE===
\ No newline at end of file