]> granicus.if.org Git - php/commitdiff
check for invalid aliases, add tests for this and direct setting of stub/alias
authorGreg Beaver <cellog@php.net>
Mon, 24 Mar 2008 01:33:30 +0000 (01:33 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 24 Mar 2008 01:33:30 +0000 (01:33 +0000)
ext/phar/TODO
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/tests/invalid_alias.phpt [new file with mode: 0644]
ext/phar/tests/invalid_setstubalias.phpt [new file with mode: 0644]

index 92fdffef3a4172d449eea8442d885baf8c0a9b10..9f38b059c996c1cfb1f4ca647e13402d81fb100a 100644 (file)
@@ -67,7 +67,7 @@ Version 2.0.0
    access, or a string representing a file within the archive to access. If
    unknown, the callback should return the original request uri [Greg]
  * rework filename detection so that alias is always checked first
- * make aliases containing '/' or '\' invalid
+ X make aliases containing '/' or '\' invalid [Greg]
  X implement manual mounting of external phar archives to locations inside a
    phar path, $phar->mount('/path/to/external.phar', 'internal/path');
    this would traverse external.phar's manifest, and add each entry as a
index 369fab3d8754a17338d0d00a15c91f488a0bd1a7..384b5b2b0b472df37152f4ac676011de1a45f615 100755 (executable)
@@ -361,6 +361,16 @@ static inline void phar_unixify_path_separators(char *path, int path_len)
        }
 }
 #endif
+/**
+ * validate an alias, returns 1 for success, 0 for failure
+ */
+static inline int phar_validate_alias(const char *alias, int alias_len) /* {{{ */
+{
+       return !(memchr(alias, '/', alias_len) || memchr(alias, '\\', alias_len) || memchr(alias, ':', alias_len) ||
+               memchr(alias, ';', alias_len));
+}
+/* }}} */
+
 
 void phar_request_initialize(TSRMLS_D);
 
index 3c99e699b8f865c446f73a239088ac1f87595c52..a6ae41af4e7c6696fd6800cc93a798bb4fe91c1d 100755 (executable)
@@ -2177,13 +2177,13 @@ PHP_METHOD(Phar, setAlias)
        if (PHAR_G(readonly)) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
                        "Cannot write out phar archive, phar is read-only");
-               return;
+               RETURN_FALSE;
        }
 
        if (phar_obj->arc.archive->is_data) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
                        "A Phar alias cannot be set in a plain %s archive", phar_obj->arc.archive->is_tar ? "tar" : "zip");
-               return;
+               RETURN_FALSE;
        }
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &alias, &alias_len) == SUCCESS) {
@@ -2196,6 +2196,11 @@ PHP_METHOD(Phar, setAlias)
                        efree(error);
                        RETURN_FALSE;
                }
+               if (!phar_validate_alias(alias, alias_len)) {
+                       zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+                               "Invalid alias \"%s\" specified for phar \"%s\"", alias, phar_obj->arc.archive->fname);
+                       RETURN_FALSE;
+               }
                if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) {
                        zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
                        readd = 1;
@@ -2222,7 +2227,7 @@ PHP_METHOD(Phar, setAlias)
                                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), oldalias, oldalias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
                        }
                        efree(error);
-                       return;
+                       RETURN_FALSE;
                }
                zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
                if (oldalias) {
diff --git a/ext/phar/tests/invalid_alias.phpt b/ext/phar/tests/invalid_alias.phpt
new file mode 100644 (file)
index 0000000..dc0c71e
--- /dev/null
@@ -0,0 +1,45 @@
+--TEST--
+Phar: set alias with invalid alias containing / \ : or ;
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar';
+
+$p = new Phar($fname);
+try {
+       $p->setAlias('hi/');
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+try {
+       $p->setAlias('hi\\l');
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+
+try {
+       $p->setAlias('hil;');
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+
+try {
+       $p->setAlias(':hil');
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar');
+?>
+--EXPECTF--
+Invalid alias "hi/" specified for phar "%sinvalid_alias.phar"
+Invalid alias "hi\l" specified for phar "%sinvalid_alias.phar"
+Invalid alias "hil;" specified for phar "%sinvalid_alias.phar"
+Invalid alias ":hil" specified for phar "%sinvalid_alias.phar"
+===DONE===
\ No newline at end of file
diff --git a/ext/phar/tests/invalid_setstubalias.phpt b/ext/phar/tests/invalid_setstubalias.phpt
new file mode 100644 (file)
index 0000000..04cb779
--- /dev/null
@@ -0,0 +1,47 @@
+--TEST--
+Phar: invalid set alias or stub via array access
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar';
+$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip';
+
+$p = new Phar($fname);
+try {
+       $p['.phar/stub.php'] = 'hi';
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+try {
+       $p['.phar/alias.txt'] = 'hi';
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+$p = new Phar($fname2);
+try {
+       $p['.phar/stub.php'] = 'hi';
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+try {
+       $p['.phar/alias.txt'] = 'hi';
+} catch (Exception $e) {
+       echo $e->getMessage() . "\n";
+}
+
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.zip');
+?>
+--EXPECTF--
+Cannot set stub ".phar/stub.php" directly in phar "%sinvalid_setstubalias.phar.tar", use setStub
+Cannot set alias ".phar/alias.txt" directly in phar "%sinvalid_setstubalias.phar.tar", use setAlias
+Cannot set stub ".phar/stub.php" directly in phar "%sinvalid_setstubalias.phar.zip", use setStub
+Cannot set alias ".phar/alias.txt" directly in phar "%sinvalid_setstubalias.phar.zip", use setAlias
+===DONE===
\ No newline at end of file